diff --git a/example/backend/server.js b/example/backend/server.js
index 2a10971..80d888f 100644
--- a/example/backend/server.js
+++ b/example/backend/server.js
@@ -153,6 +153,37 @@ app.post('/api/challenge-token', async (req, res) => {
}
});
+app.post('/api/launch-url', async (req, res) => {
+ try {
+ const { userId } = req.body;
+
+ if (!userId) {
+ return res.status(400).json({ error: 'userId is required' });
+ }
+
+ console.log(` Tracking 'launch' for user: ${userId}`);
+
+ const trackResponse = await authsignal.track({
+ userId,
+ action: 'launch',
+ });
+
+ console.log(` State: ${trackResponse.state}, URL: ${trackResponse.url}`);
+
+ res.json({
+ url: trackResponse.url,
+ token: trackResponse.token,
+ state: trackResponse.state,
+ });
+ } catch (error) {
+ console.error(' Error:', error.message);
+ res.status(500).json({
+ error: 'Failed to get launch URL',
+ details: error.message,
+ });
+ }
+});
+
app.post('/api/validate', async (req, res) => {
try {
const { token } = req.body;
diff --git a/example/package-lock.json b/example/package-lock.json
index ca5f1f5..585731e 100644
--- a/example/package-lock.json
+++ b/example/package-lock.json
@@ -30,7 +30,7 @@
}
},
"..": {
- "version": "2.4.0",
+ "version": "2.6.1",
"license": "MIT",
"devDependencies": {
"@authsignal/browser": "^1.13.1",
diff --git a/example/src/screens/HomeScreen.tsx b/example/src/screens/HomeScreen.tsx
index 292a511..e521a1b 100644
--- a/example/src/screens/HomeScreen.tsx
+++ b/example/src/screens/HomeScreen.tsx
@@ -77,6 +77,58 @@ export function HomeScreen() {
}
};
+ // --- Launch Methods ---
+
+ const launchPopup = async () => {
+ const authsignal = authsignalRef.current;
+ if (!authsignal) return;
+
+ try {
+ addOutput('Getting launch URL from backend...');
+ const response = await BackendService.getLaunchUrl(userId);
+
+ if (!response?.url) {
+ addOutput('Failed to get launch URL');
+ return;
+ }
+
+ addOutput(`Launch URL received (state: ${response.state})`);
+ addOutput('Opening in popup mode...');
+
+ const token = await authsignal.launch(response.url);
+
+ if (token) {
+ addOutput(`Popup completed! Token: ${token.substring(0, 20)}...`);
+ } else {
+ addOutput('Popup closed without completing.');
+ }
+ } catch (e) {
+ addOutput(`Error: ${e}`);
+ }
+ };
+
+ const launchRedirect = async () => {
+ const authsignal = authsignalRef.current;
+ if (!authsignal) return;
+
+ try {
+ addOutput('Getting launch URL from backend...');
+ const response = await BackendService.getLaunchUrl(userId);
+
+ if (!response?.url) {
+ addOutput('Failed to get launch URL');
+ return;
+ }
+
+ addOutput(`Launch URL received (state: ${response.state})`);
+ addOutput('Redirecting...');
+
+ await authsignal.launch(response.url, { mode: 'redirect' });
+ } catch (e) {
+ addOutput(`Error: ${e}`);
+ }
+ };
+
// --- Passkey Methods ---
const registerPasskey = async () => {
@@ -550,6 +602,23 @@ export function HomeScreen() {
onInitialize={initializeSDK}
/>
+ {/* Launch */}
+
+
+
+
+
{/* Passkeys */}
{
+ try {
+ const response = await fetch(`${this.baseUrl}/api/launch-url`, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ userId }),
+ });
+
+ if (response.ok) {
+ return await response.json();
+ }
+ console.log(`Failed to get launch URL: ${response.status}`);
+ return null;
+ } catch (e) {
+ console.log(`Backend connection error: ${e}`);
+ return null;
+ }
+ }
+
async checkHealth(): Promise {
try {
const controller = new AbortController();
diff --git a/package-lock.json b/package-lock.json
index dfc30f4..e81530e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "react-native-authsignal",
- "version": "2.4.0",
+ "version": "2.6.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "react-native-authsignal",
- "version": "2.4.0",
+ "version": "2.6.0",
"license": "MIT",
"devDependencies": {
"@authsignal/browser": "^1.13.1",
@@ -24,7 +24,7 @@
"typescript": "^4.5.2"
},
"peerDependencies": {
- "@authsignal/browser": ">=0.5.0",
+ "@authsignal/browser": ">=1.0.0",
"react": "*",
"react-native": "*"
},
diff --git a/package.json b/package.json
index 1c7e8c8..45d7f3e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "react-native-authsignal",
- "version": "2.6.0",
+ "version": "2.6.1",
"description": "The official Authsignal React Native library.",
"main": "lib/commonjs/index",
"module": "lib/module/index",
diff --git a/src/index.tsx b/src/index.tsx
index c21ef22..61ca245 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -71,10 +71,7 @@ export class Authsignal {
await AuthsignalModule.setToken(token);
}
- async launch(
- url: string,
- _options?: LaunchOptions
- ): Promise {
+ async launch(url: string, _options?: LaunchOptions): Promise {
return await launch(url);
}
}
diff --git a/src/index.web.tsx b/src/index.web.tsx
index 13e21f1..5387e60 100644
--- a/src/index.web.tsx
+++ b/src/index.web.tsx
@@ -64,10 +64,7 @@ export class Authsignal {
client.setToken(token);
}
- async launch(
- url: string,
- options?: LaunchOptions
- ): Promise {
+ async launch(url: string, options?: LaunchOptions): Promise {
return await launch(url, options);
}
}
@@ -76,8 +73,6 @@ export function launch(
url: string,
options?: LaunchOptions
): Promise {
- const mode = options?.mode ?? 'popup';
-
if (_lastClient) {
const client = getOrCreateWebClient({
tenantID: _lastClient.tenantID,
@@ -85,7 +80,12 @@ export function launch(
enableLogging: _lastClient.enableLogging,
});
- return client.launch(url, { mode }).then((result) => {
+ if (options?.mode === 'redirect') {
+ client.launch(url, { mode: 'redirect' });
+ return Promise.resolve(null);
+ }
+
+ return client.launch(url, { mode: 'popup' }).then((result) => {
return result?.token ?? null;
});
}
diff --git a/src/types.ts b/src/types.ts
index 11f707f..86533da 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -131,10 +131,8 @@ export interface DeletePinInput {
username: string;
}
-export type LaunchMode = 'popup' | 'redirect';
-
export interface LaunchOptions {
- mode?: LaunchMode;
+ mode?: 'popup' | 'redirect';
}
export enum KeychainAccess {