Skip to content

Commit 28b4d24

Browse files
committed
fix: handle Universal Link and interstitial deep links in app URL listener
- Add handleUniversalLinkDeepLink for fliq.linkforty.com/s URLs (cold + warm start) - Handle fliq:// scheme URLs with encrypted params from interstitial page - Fix ITSAppUsesNonExemptEncryption to false (encryption is exempt)
1 parent dc11ab1 commit 28b4d24

3 files changed

Lines changed: 42 additions & 3 deletions

File tree

app.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"applinks:fliq.linkforty.com"
2121
],
2222
"infoPlist": {
23-
"ITSAppUsesNonExemptEncryption": true
23+
"ITSAppUsesNonExemptEncryption": false
2424
},
2525
"privacyManifests": {
2626
"NSPrivacyAccessedAPITypes": [

app/_layout.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { Pressable, Text } from 'react-native';
1111
import { GestureHandlerRootView } from 'react-native-gesture-handler';
1212
import * as Linking from 'expo-linking';
1313
import { initializeSDK, onDeepLink, onDeferredDeepLink, trackEvent } from '@/lib/sdk';
14-
import { handleSDKDeepLink, handleSchemeDeepLink } from '@/lib/deep-link-router';
14+
import { handleSDKDeepLink, handleSchemeDeepLink, handleUniversalLinkDeepLink } from '@/lib/deep-link-router';
1515
import { isOnboardingComplete } from '@/lib/settings';
1616
import { fetchPushMessage } from '@/lib/push';
1717
import { saveMessage } from '@/lib/storage';
@@ -132,13 +132,18 @@ export default function RootLayout() {
132132
const subscription = Linking.addEventListener('url', ({ url }) => {
133133
if (url.startsWith('fliq://open')) {
134134
handleSchemeDeepLink(url);
135+
} else if (url.includes('fliq.linkforty.com/s') || (url.startsWith('fliq://') && url.includes('e='))) {
136+
// Universal Links (fliq.linkforty.com) and interstitial scheme URLs (fliq://?e=...&n=...#key)
137+
handleUniversalLinkDeepLink(url);
135138
}
136139
});
137140

138-
// Check if app was cold-launched via fliq:// scheme
141+
// Check if app was cold-launched via deep link
139142
Linking.getInitialURL().then((initialUrl) => {
140143
if (initialUrl?.startsWith('fliq://open')) {
141144
handleSchemeDeepLink(initialUrl);
145+
} else if (initialUrl?.includes('fliq.linkforty.com/s') || (initialUrl?.startsWith('fliq://') && initialUrl?.includes('e='))) {
146+
handleUniversalLinkDeepLink(initialUrl);
142147
}
143148
});
144149

lib/deep-link-router.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { router } from 'expo-router';
22
import { saveMessage } from './storage';
33
import { trackEvent } from './sdk';
44
import { getSettings } from './settings';
5+
import { parseDeepLink } from './deeplink';
56
import { decrypt, isEncryptedPayload, extractKeyFromFragment } from './crypto';
67
import type { Message } from './types';
78
import type { DeepLinkData } from '@linkforty/mobile-sdk-expo';
@@ -163,6 +164,39 @@ export async function handleSchemeDeepLink(url: string): Promise<void> {
163164
}
164165
}
165166

167+
/**
168+
* Handle a Universal Link deep link (https://fliq.linkforty.com/s?...).
169+
* Parses the encrypted or legacy URL, decrypts the message, saves it,
170+
* and navigates to the reveal screen. Works for both cold and warm starts.
171+
*/
172+
export async function handleUniversalLinkDeepLink(url: string): Promise<void> {
173+
try {
174+
const payload = parseDeepLink(url);
175+
if (!payload) return;
176+
177+
const id = Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
178+
const msg: Message = {
179+
id,
180+
content: payload.content,
181+
revealStyle: payload.revealStyle,
182+
senderName: payload.senderName,
183+
createdAt: new Date().toISOString(),
184+
isRead: false,
185+
direction: 'received',
186+
};
187+
188+
await saveMessage(msg);
189+
trackEvent('message_received', {
190+
revealStyle: msg.revealStyle,
191+
source: 'universal_link',
192+
});
193+
194+
navigateToReveal(id);
195+
} catch {
196+
// Silently fail — user will see inbox
197+
}
198+
}
199+
166200
function navigateToReveal(id: string): void {
167201
try {
168202
router.replace(`/reveal/${id}`);

0 commit comments

Comments
 (0)