diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6c61232..93921ee 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,17 +20,17 @@ jobs: uses: softprops/action-gh-release@v1 with: body: | - **New Nostros Release [${{ github.ref_name }}]** + **New Nostros Release [${{ github.ref_name }}]** + + **Download** - **What's Changed** + https://github.com/KoalaSat/nostros/releases/download/${{ github.ref_name }}/nostros-${{ github.ref_name }}-universal.apk **Changelog** https://github.com/KoalaSat/nostros/releases/${{ github.ref_name }} - **Download** - - https://github.com/KoalaSat/nostros/releases/download/${{ github.ref_name }}/nostros-${{ github.ref_name }}-universal.apk + **What's Changed** # Upload APK artifact asset - name: 'Download universal APK Artifact' uses: actions/download-artifact@v3 diff --git a/android/app/src/main/java/com/nostros/classes/Websocket.java b/android/app/src/main/java/com/nostros/classes/Websocket.java index 8e176a1..73a3c72 100644 --- a/android/app/src/main/java/com/nostros/classes/Websocket.java +++ b/android/app/src/main/java/com/nostros/classes/Websocket.java @@ -82,7 +82,11 @@ public class Websocket { Log.d("Websocket", "RECEIVE URL:" + url + " __DUP__ " + message); } } else if (messageType.equals("OK")) { + Log.d("Websocket", "RECEIVE OK:" + url + message); reactNativeConfirmation(jsonArray.get(1).toString()); + } else if (messageType.equals("AUTH")) { + Log.d("Websocket", "RECEIVE AUTH:" + url + message); + reactNativeAuth(jsonArray.get(1).toString()); } } @Override @@ -126,4 +130,14 @@ public class Websocket { .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emit("WebsocketNotification", payload); } + + public void reactNativeAuth(String challenge) { + Log.d("Websocket", "reactNativeNotification"); + WritableMap payload = Arguments.createMap(); + payload.putString("challenge", challenge); + payload.putString("url", url); + context + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit("WebsocketAuth", payload); + } } diff --git a/frontend/Components/TextContent/index.tsx b/frontend/Components/TextContent/index.tsx index a0feeb5..c61cf60 100644 --- a/frontend/Components/TextContent/index.tsx +++ b/frontend/Components/TextContent/index.tsx @@ -105,11 +105,10 @@ export const TextContent: React.FC = ({ matchingString, matches, ) => { - const mentionIndex: number = parseInt(matches[1]) - - if (userNames[mentionIndex]) { + if (userNames[matchingString]) { return `@${userNames[matchingString]}` } else if (event) { + const mentionIndex: number = parseInt(matches[1]) const tag = event.tags[mentionIndex] if (tag) { @@ -122,7 +121,7 @@ export const TextContent: React.FC = ({ getUser(pubKey, database).then((user) => { setLoadedUsers(getUnixTime(new Date())) setUserNames((prev) => { - if (user?.name) prev[mentionIndex] = user.name + if (user?.name) prev[matchingString] = user.name return prev }) }) diff --git a/frontend/Contexts/RelayPoolContext.tsx b/frontend/Contexts/RelayPoolContext.tsx index b7fd9ab..4f10236 100644 --- a/frontend/Contexts/RelayPoolContext.tsx +++ b/frontend/Contexts/RelayPoolContext.tsx @@ -35,8 +35,10 @@ export interface RelayPoolContextProps { } export interface WebsocketEvent { - eventId: string + eventId?: string kind?: string + url?: string + challenge?: string } export interface RelayPoolContextProviderProps { @@ -79,6 +81,7 @@ export const RelayPoolContextProvider = ({ const [newNotifications, setNewNotifications] = useState(0) const [newDirectMessages, setNewDirectMessages] = useState(0) const [newGroupMessages, setNewGroupMessages] = useState(0) + const [chalenges, setChallenges] = useState([]) const sendEvent: (event: Event, relayUrl?: string) => Promise = async ( event, @@ -107,6 +110,27 @@ export const RelayPoolContextProvider = ({ return await relayPool?.sendEvent(event, relayUrl) } + const sendAuth: (challenge: string, url: string) => Promise = async ( + challenge, + url, + ) => { + if (publicKey && privateKey) { + let nostrEvent: Event = { + content: '', + created_at: getUnixTime(new Date()), + kind: 22242, + pubkey: publicKey, + tags: [ + ["relay", url], + ["challenge", challenge] + ], + } + nostrEvent = await signEvent(nostrEvent, privateKey) + + await relayPool?.sendAuth(nostrEvent, url) + } + } + const sendRelays: (url?: string) => Promise = async (url) => { if (publicKey && database) { getActiveRelays(database).then((results) => { @@ -125,11 +149,22 @@ export const RelayPoolContextProvider = ({ } const changeEventIdHandler: (event: WebsocketEvent) => void = (event) => { - setLastEventId(event.eventId) + if (event.eventId) setLastEventId(event.eventId) } + const changeConfirmationIdHandler: (event: WebsocketEvent) => void = (event) => { - setLastConfirmationId(event.eventId) + if (event.eventId) setLastConfirmationId(event.eventId) } + + const authHandler: (event: WebsocketEvent) => Promise = async (event) => { + if (event.url && event.challenge) { + setChallenges((prev) => { + prev.push(event) + return prev + }) + } + } + const changeNotificationHandler: (event: WebsocketEvent) => void = (event) => { if (event.kind === '4') { setNewDirectMessages((prev) => prev + 1) @@ -140,6 +175,10 @@ export const RelayPoolContextProvider = ({ } } + const debouncedAuthdHandler = useMemo( + () => debounce(authHandler, 250), + [relayPool], + ) const debouncedEventIdHandler = useMemo( () => debounce(changeEventIdHandler, 250), [setLastEventId], @@ -238,6 +277,7 @@ export const RelayPoolContextProvider = ({ if (publicKey && publicKey !== '') { DeviceEventEmitter.addListener('WebsocketEvent', debouncedEventIdHandler) DeviceEventEmitter.addListener('WebsocketConfirmation', debouncedConfirmationHandler) + DeviceEventEmitter.addListener('WebsocketAuth', debouncedAuthdHandler) DeviceEventEmitter.addListener('WebsocketNotification', changeNotificationHandler) loadRelayPool() } @@ -249,6 +289,18 @@ export const RelayPoolContextProvider = ({ } }, [relayPool]) + useEffect(() => { + if (relayPoolReady) { + setChallenges((prev) => { + prev.forEach((event) => { + if (event.challenge && event.url) sendAuth(event.challenge, event.url) + }) + + return [] + }) + } + }, [relayPoolReady, chalenges.length]) + return ( Promise = async ( + event, + relayUrl, + ) => { + if (validateEvent(event)) { + this.sendRelay(['AUTH', event], relayUrl) + return event + } else { + console.log('Not valid event', event) + return null + } + } + public readonly subscribe: (subId: string, filters?: RelayFilters[]) => void = async ( subId, filters,