@smarthivelabs-devs/auth-expo 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -182,9 +182,39 @@ if (result.requiresVerification) {
182
182
 
183
183
  ---
184
184
 
185
- ## OAuth Redirect Sign-in (Browser)
185
+ ## Social OAuth Sign-in (Google, Apple, GitHub, etc.)
186
186
 
187
- The original flow is completely unchanged. Use it for social login or when you want the hosted login page.
187
+ Each social provider uses **your project's own credentials** — the consent screen shows your app name. Configure credentials in your SmartHive dashboard under **Project OAuth Providers**, then call:
188
+
189
+ ```tsx
190
+ import { useAuth } from "@smarthivelabs-devs/auth-expo";
191
+ import { Button } from "react-native";
192
+
193
+ export default function LoginScreen() {
194
+ const { signIn } = useAuth();
195
+
196
+ return (
197
+ <>
198
+ <Button title="Continue with Google" onPress={() => signIn.social("google")} />
199
+ <Button title="Continue with Apple" onPress={() => signIn.social("apple")} />
200
+ <Button title="Continue with GitHub" onPress={() => signIn.social("github")} />
201
+ </>
202
+ );
203
+ }
204
+ ```
205
+
206
+ `signIn.social()` calls `Linking.openURL()` to open the provider's consent screen in the system browser. When the user approves, the provider redirects back to your app's `redirectUri` deep link with `?access_token=...&refresh_token=...`. The `SmartHiveProvider` deep link listener picks this up automatically and saves the session — no extra setup needed.
207
+
208
+ **Supported providers:**
209
+ `google` · `apple` · `github` · `facebook` · `twitter` · `linkedin` · `microsoft` · `discord` · `spotify` · `twitch` · `reddit` · `gitlab` · `slack` · `notion` · `zoom` · `figma`
210
+
211
+ > **Deep link required** — make sure `redirectUri` is set to your app scheme (e.g. `myapp://auth/callback`) and your scheme is registered in `app.json`. See the Deep Link Setup section below.
212
+
213
+ ---
214
+
215
+ ## OAuth Redirect Sign-in (SmartHive hosted page)
216
+
217
+ The original PKCE flow — redirects to the SmartHive hosted login page and back. Use it for SSO or when you want the hosted login UI.
188
218
 
189
219
  ```tsx
190
220
  import { useAuth } from "@smarthivelabs-devs/auth-expo";
@@ -250,14 +280,19 @@ const {
250
280
  session, // AuthSession | null
251
281
  isLoaded, // true once initial SecureStore read is done
252
282
  isSignedIn, // boolean
253
- login, // OAuth redirect sign-in
283
+ login, // OAuth redirect sign-in (PKCE, SmartHive hosted page)
254
284
  logout, // sign out
255
- signIn, // headless sign-in methods
285
+ signIn, // headless + social sign-in methods
256
286
  signUp, // headless sign-up methods
257
287
  refreshSession, // force a token refresh
258
288
  authFetch, // authenticated fetch wrapper
259
289
  getAuthorizationHeader, // () => Promise<{ authorization: string }>
260
290
  } = useAuth();
291
+
292
+ // Social sign-in is under signIn.social:
293
+ await signIn.social("google");
294
+ await signIn.social("apple");
295
+ await signIn.social("github");
261
296
  ```
262
297
 
263
298
  ### `useSession()`
@@ -490,6 +525,82 @@ await client.login();
490
525
 
491
526
  ---
492
527
 
528
+ ## Social Auth Proxy (White-label Domain)
529
+
530
+ By default, when a user taps "Sign in with Google", the iOS system prompt shows:
531
+
532
+ > *"YourApp wants to use **authcore.smarthivelabs.dev** to sign in"*
533
+
534
+ And the Google consent screen shows:
535
+
536
+ > *"to continue to **smarthivelabs.dev**"*
537
+
538
+ To show **your own domain** on both prompts, add two thin proxy routes to your backend and set `socialProxyUrl` in the provider config. SmartHive Auth does all the OAuth work — your domain just acts as the visible entry point.
539
+
540
+ ### Step 1 — Add proxy routes to your backend
541
+
542
+ ```ts
543
+ // src/routes/socialProxyRoutes.ts
544
+ import express from "express";
545
+ const router = express.Router();
546
+
547
+ const SMARTHIVE_BASE = process.env.SMARTHIVE_AUTH_BASE_URL!; // https://authcore.smarthivelabs.dev
548
+ const SMARTHIVE_ENV = process.env.SMARTHIVE_AUTH_ENVIRONMENT!; // prod
549
+ const SMARTHIVE_PID = process.env.SMARTHIVE_PROJECT_ID!;
550
+ const APP_BASE_URL = process.env.APP_BASE_URL!; // https://api.yourapp.com
551
+
552
+ // Initiation — app calls this, proxy forwards to SmartHive
553
+ router.get("/:provider", async (req, res) => {
554
+ const target = new URL(`${SMARTHIVE_BASE}/${SMARTHIVE_ENV}/api/auth/social/${req.params.provider}`);
555
+ target.searchParams.set("project_id", SMARTHIVE_PID);
556
+ if (req.query.redirect_uri) target.searchParams.set("redirect_uri", req.query.redirect_uri as string);
557
+ target.searchParams.set("proxy_callback", `${APP_BASE_URL}/api/auth/social/${req.params.provider}/callback`);
558
+ res.redirect(target.toString());
559
+ });
560
+
561
+ // Callback — Google/Apple calls this, proxy forwards to SmartHive
562
+ router.get("/:provider/callback", async (req, res) => {
563
+ const target = new URL(`${SMARTHIVE_BASE}/${SMARTHIVE_ENV}/api/auth/social/${req.params.provider}/callback`);
564
+ for (const [k, v] of Object.entries(req.query)) target.searchParams.set(k, v as string);
565
+ res.redirect(target.toString());
566
+ });
567
+
568
+ app.use("/api/auth/social", router);
569
+ ```
570
+
571
+ Required env vars on your backend:
572
+ ```env
573
+ SMARTHIVE_AUTH_BASE_URL=https://authcore.smarthivelabs.dev
574
+ SMARTHIVE_AUTH_ENVIRONMENT=prod
575
+ APP_BASE_URL=https://api.yourapp.com
576
+ ```
577
+
578
+ ### Step 2 — Register your callback URL with each provider
579
+
580
+ In your Google Cloud Console (or Apple/GitHub/etc. developer console), register:
581
+ ```
582
+ https://api.yourapp.com/api/auth/social/google/callback
583
+ ```
584
+ instead of the SmartHive URL. Replace `google` with each provider you support.
585
+
586
+ ### Step 3 — Set `socialProxyUrl` in your app
587
+
588
+ ```tsx
589
+ <SmartHiveProvider
590
+ publishableKey="pk_prod_..."
591
+ projectId="your-project-id"
592
+ baseUrl="https://authcore.smarthivelabs.dev"
593
+ redirectUri="myapp://auth/callback"
594
+ socialProxyUrl="https://api.yourapp.com" // ← add this
595
+ >
596
+ <App />
597
+ </SmartHiveProvider>
598
+ ```
599
+
600
+ That's it. `signIn.social("google")` now opens `api.yourapp.com/api/auth/social/google`, iOS shows your domain, and Google shows "to continue to **yourapp.com**".
601
+
602
+ ---
603
+
493
604
  ## Related Packages
494
605
 
495
606
  | Package | Use case |
package/dist/index.d.ts CHANGED
@@ -1,9 +1,16 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { SmartHiveAuthConfig, SmartHiveAuthClient, AuthSession, HeadlessSignInResult, HeadlessSignUpResult } from '@smarthivelabs-devs/auth-sdk';
2
+ import { SmartHiveAuthConfig, SmartHiveAuthClient, AuthSession, HeadlessSignInResult, SocialProvider, HeadlessSignUpResult } from '@smarthivelabs-devs/auth-sdk';
3
3
 
4
4
  interface SmartHiveExpoConfig extends Omit<SmartHiveAuthConfig, "storage"> {
5
5
  /** Deep link redirect URI, e.g. "myapp://auth/callback" */
6
6
  redirectUri: string;
7
+ /**
8
+ * URL of your own backend's social auth proxy (e.g. "https://api.myapp.com").
9
+ * When set, social OAuth routes through your domain — Google/Apple consent screens
10
+ * show your domain instead of SmartHive's. Your backend must implement
11
+ * GET /api/auth/social/:provider and GET /api/auth/social/:provider/callback.
12
+ */
13
+ socialProxyUrl?: string;
7
14
  }
8
15
  /**
9
16
  * Build a deep link redirect URI from your Expo app scheme.
@@ -61,6 +68,10 @@ interface AuthContextValue {
61
68
  callbackURL?: string;
62
69
  }): Promise<void>;
63
70
  };
71
+ /** Initiate a social OAuth flow — opens an in-app browser sheet (expo-web-browser). Auto-closes on redirect and updates session state. */
72
+ social(provider: SocialProvider, options?: {
73
+ redirectUri?: string;
74
+ }): Promise<void>;
64
75
  };
65
76
  signUp: {
66
77
  email(params: {
package/dist/index.js CHANGED
@@ -10,9 +10,11 @@ import {
10
10
  } from "react";
11
11
  import { Linking } from "react-native";
12
12
  import { AuthRequest } from "expo-auth-session";
13
+ import * as WebBrowser from "expo-web-browser";
13
14
  import * as SecureStore from "expo-secure-store";
14
15
  import {
15
- initAuth
16
+ initAuth,
17
+ envFromPublishableKey
16
18
  } from "@smarthivelabs-devs/auth-sdk";
17
19
  import { Fragment, jsx } from "react/jsx-runtime";
18
20
  var secureStorage = {
@@ -60,6 +62,24 @@ function initExpoAuth(config) {
60
62
  }
61
63
  await secureStorage.setItem(storageKeys.pkceState, request.state);
62
64
  await Linking.openURL(url);
65
+ },
66
+ async loginSocial(provider, options) {
67
+ const redirectUri = options?.redirectUri ?? config.redirectUri;
68
+ let socialUrl;
69
+ if (config.socialProxyUrl) {
70
+ socialUrl = new URL(`${normalizeBaseUrl(config.socialProxyUrl)}/api/auth/social/${provider}`);
71
+ socialUrl.searchParams.set("redirect_uri", redirectUri);
72
+ } else {
73
+ const authBase = normalizeBaseUrl(config.authDomain ?? config.baseUrl);
74
+ const env = envFromPublishableKey(config.publishableKey);
75
+ socialUrl = new URL(`${authBase}/${env}/api/auth/social/${provider}`);
76
+ socialUrl.searchParams.set("project_id", config.projectId);
77
+ socialUrl.searchParams.set("redirect_uri", redirectUri);
78
+ }
79
+ const result = await WebBrowser.openAuthSessionAsync(socialUrl.toString(), redirectUri);
80
+ if (result.type === "success") {
81
+ await base.handleSocialCallback({ url: result.url });
82
+ }
63
83
  }
64
84
  };
65
85
  }
@@ -83,8 +103,17 @@ function SmartHiveProvider({ children, ...config }) {
83
103
  }, [client]);
84
104
  useEffect(() => {
85
105
  function handleUrl({ url }) {
86
- client.handleCallback({ url }).then((s) => setSession(s)).catch(() => {
87
- });
106
+ try {
107
+ const parsed = new URL(url);
108
+ if (parsed.searchParams.has("access_token") || parsed.searchParams.has("error")) {
109
+ client.handleSocialCallback({ url }).then((s) => setSession(s)).catch(() => {
110
+ });
111
+ } else {
112
+ client.handleCallback({ url }).then((s) => setSession(s)).catch(() => {
113
+ });
114
+ }
115
+ } catch {
116
+ }
88
117
  }
89
118
  const sub = Linking.addEventListener("url", handleUrl);
90
119
  Linking.getInitialURL().then((url) => {
@@ -137,6 +166,11 @@ function SmartHiveProvider({ children, ...config }) {
137
166
  },
138
167
  magicLink: {
139
168
  send: (p) => h.signIn.magicLink.send(p)
169
+ },
170
+ social: async (provider, options) => {
171
+ await client.loginSocial(provider, options);
172
+ const s = await client.getSession();
173
+ if (s) setSession(s);
140
174
  }
141
175
  };
142
176
  }, [client]);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/provider.tsx"],"sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { Linking } from \"react-native\";\nimport { AuthRequest } from \"expo-auth-session\";\nimport * as SecureStore from \"expo-secure-store\";\nimport {\n initAuth,\n type AuthSession,\n type AuthStorage,\n type HeadlessClient,\n type HeadlessSignInResult,\n type HeadlessSignUpResult,\n type SmartHiveAuthClient,\n type SmartHiveAuthConfig,\n} from \"@smarthivelabs-devs/auth-sdk\";\n\n// ── Secure storage adapter ────────────────────────────────────────────────────\n\nconst secureStorage: AuthStorage = {\n getItem: (key) => SecureStore.getItemAsync(key),\n setItem: (key, value) => SecureStore.setItemAsync(key, value),\n removeItem: (key) => SecureStore.deleteItemAsync(key),\n};\n\nconst storageKeys = {\n pkceVerifier: \"smarthive.auth.pkce_verifier\",\n pkceState: \"smarthive.auth.pkce_state\"\n} as const;\n\n// ── Config ────────────────────────────────────────────────────────────────────\n\nexport interface SmartHiveExpoConfig extends Omit<SmartHiveAuthConfig, \"storage\"> {\n /** Deep link redirect URI, e.g. \"myapp://auth/callback\" */\n redirectUri: string;\n}\n\n/**\n * Build a deep link redirect URI from your Expo app scheme.\n * @example buildRedirectUri(\"myapp\") → \"myapp://auth/callback\"\n */\nexport function buildRedirectUri(scheme: string, path = \"auth/callback\"): string {\n return `${scheme}://${path}`;\n}\n\nfunction normalizeBaseUrl(baseUrl: string) {\n return baseUrl.replace(/\\/$/, \"\");\n}\n\n// ── Auth client (Expo flavour) ─────────────────────────────────────────────────\n\n/**\n * Creates an auth client that uses SecureStore for token storage and\n * Linking.openURL for the OAuth redirect (instead of location.assign).\n */\nexport function initExpoAuth(config: SmartHiveExpoConfig): SmartHiveAuthClient {\n const base = initAuth({\n ...config,\n storage: secureStorage,\n temporaryStorage: secureStorage\n } as SmartHiveAuthConfig);\n\n return {\n ...base,\n async login(options) {\n const redirectUri = options?.redirectUri ?? config.redirectUri;\n const authBase = normalizeBaseUrl(config.authDomain ?? config.baseUrl);\n const request = new AuthRequest({\n clientId: config.publishableKey,\n redirectUri,\n responseType: \"code\",\n usePKCE: true,\n state: options?.state,\n extraParams: {\n project_id: config.projectId,\n publishable_key: config.publishableKey\n }\n });\n const url = await request.makeAuthUrlAsync({\n authorizationEndpoint: `${authBase}/api/auth/oauth2/authorize`\n });\n\n if (request.codeVerifier) {\n await secureStorage.setItem(storageKeys.pkceVerifier, request.codeVerifier);\n }\n await secureStorage.setItem(storageKeys.pkceState, request.state);\n await Linking.openURL(url);\n },\n };\n}\n\n// ── Context ────────────────────────────────────────────────────────────────────\n\ninterface AuthContextValue {\n client: SmartHiveAuthClient;\n session: AuthSession | null;\n isLoaded: boolean;\n isSignedIn: boolean;\n /** OAuth 2.0 + PKCE browser redirect sign-in (unchanged). */\n login(options?: { redirectUri?: string }): Promise<void>;\n logout(): Promise<void>;\n refreshSession(): Promise<void>;\n getAuthorizationHeader(): Promise<Record<string, string>>;\n authFetch(input: string | URL | Request, init?: RequestInit): Promise<Response>;\n /**\n * Headless (no browser) sign-in methods for custom login screens.\n * Tokens are stored in SecureStore automatically on success.\n */\n signIn: {\n email(params: { email: string; password: string }): Promise<HeadlessSignInResult>;\n phone: {\n sendOtp(params: { phoneNumber: string }): Promise<void>;\n verify(params: { phoneNumber: string; code: string }): Promise<HeadlessSignInResult>;\n };\n emailOtp: {\n send(params: { email: string }): Promise<void>;\n verify(params: { email: string; code: string }): Promise<HeadlessSignInResult>;\n };\n magicLink: {\n send(params: { email: string; callbackURL?: string }): Promise<void>;\n };\n };\n signUp: {\n email(params: { email: string; password: string; name?: string }): Promise<HeadlessSignUpResult>;\n };\n}\n\nconst AuthContext = createContext<AuthContextValue | null>(null);\n\n// ── Provider ───────────────────────────────────────────────────────────────────\n\nexport interface SmartHiveProviderProps extends SmartHiveExpoConfig {\n children: React.ReactNode;\n}\n\n/**\n * Wraps your Expo app and provides auth state to all child components.\n * Tokens are stored in SecureStore. Supports both:\n * - OAuth 2.0 + PKCE browser redirect via `login()`\n * - Headless direct sign-in via `signIn.*` (no browser, custom login screens)\n */\nexport function SmartHiveProvider({ children, ...config }: SmartHiveProviderProps) {\n const configRef = useRef(config);\n const client = useMemo(() => initExpoAuth(configRef.current), []);\n\n const [session, setSession] = useState<AuthSession | null>(null);\n const [isLoaded, setIsLoaded] = useState(false);\n\n // Initial session load from SecureStore\n useEffect(() => {\n let cancelled = false;\n client\n .initialize()\n .then(() => client.getSession())\n .then((s) => { if (!cancelled) setSession(s); })\n .catch(() => {})\n .finally(() => { if (!cancelled) setIsLoaded(true); });\n return () => { cancelled = true; };\n }, [client]);\n\n // Deep link listener — catches the OAuth callback redirect back into the app\n useEffect(() => {\n function handleUrl({ url }: { url: string }) {\n client\n .handleCallback({ url })\n .then((s) => setSession(s))\n .catch(() => {});\n }\n\n const sub = Linking.addEventListener(\"url\", handleUrl);\n\n // Handle cold-start: app opened directly from the OAuth redirect URL\n Linking.getInitialURL().then((url) => {\n if (url) handleUrl({ url });\n });\n\n return () => sub.remove();\n }, [client]);\n\n const login = useCallback(\n (options?: { redirectUri?: string }) => client.login(options),\n [client]\n );\n\n const logout = useCallback(async () => {\n await client.logout();\n setSession(null);\n }, [client]);\n\n const refreshSession = useCallback(async () => {\n setSession(await client.refreshSession());\n }, [client]);\n\n const getAuthorizationHeader = useCallback(\n () => client.getAuthorizationHeader(),\n [client]\n );\n\n const authFetch = useCallback(\n (input: string | URL | Request, init?: RequestInit) => client.fetch(input, init),\n [client]\n );\n\n // ── Headless sign-in wrappers — save session + update state ──────────────────\n\n function wrapHeadlessSignIn(\n fn: (p: never) => Promise<HeadlessSignInResult>\n ) {\n return async (params: never) => {\n const result = await fn(params);\n setSession({\n accessToken: result.accessToken,\n refreshToken: result.refreshToken,\n expiresAt: result.expiresAt,\n user: result.user,\n });\n return result;\n };\n }\n\n const signIn = useMemo<AuthContextValue[\"signIn\"]>(() => {\n const h: HeadlessClient = client.headless;\n return {\n email: wrapHeadlessSignIn(h.signIn.email.bind(h.signIn) as never),\n phone: {\n sendOtp: (p) => h.signIn.phone.sendOtp(p),\n verify: wrapHeadlessSignIn(h.signIn.phone.verify.bind(h.signIn.phone) as never),\n },\n emailOtp: {\n send: (p) => h.signIn.emailOtp.send(p),\n verify: wrapHeadlessSignIn(h.signIn.emailOtp.verify.bind(h.signIn.emailOtp) as never),\n },\n magicLink: {\n send: (p) => h.signIn.magicLink.send(p),\n },\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [client]);\n\n const signUp = useMemo<AuthContextValue[\"signUp\"]>(() => {\n const h: HeadlessClient = client.headless;\n return {\n email: async (params) => {\n const result = await h.signUp.email(params);\n if (!result.requiresVerification) {\n setSession({\n accessToken: result.accessToken,\n refreshToken: result.refreshToken,\n expiresAt: result.expiresAt,\n user: result.user,\n });\n }\n return result;\n },\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [client]);\n\n const value = useMemo<AuthContextValue>(\n () => ({\n client,\n session,\n isLoaded,\n isSignedIn: !!session,\n login,\n logout,\n refreshSession,\n getAuthorizationHeader,\n authFetch,\n signIn,\n signUp,\n }),\n [client, session, isLoaded, login, logout, refreshSession, getAuthorizationHeader, authFetch, signIn, signUp]\n );\n\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\n}\n\n// ── Hooks ──────────────────────────────────────────────────────────────────────\n\nfunction useAuthContext(): AuthContextValue {\n const ctx = useContext(AuthContext);\n if (!ctx) throw new Error(\"useAuth must be used inside <SmartHiveProvider>.\");\n return ctx;\n}\n\nexport function useAuth() { return useAuthContext(); }\nexport function useSession() { return useAuthContext().session; }\nexport function useUser() { return useAuthContext().session?.user ?? null; }\nexport function useIsLoaded() { return useAuthContext().isLoaded; }\n\nexport function useIsSignedIn() {\n const { isLoaded, isSignedIn } = useAuthContext();\n return isLoaded ? isSignedIn : null;\n}\n\nexport function useAuthFetch() {\n return useAuthContext().authFetch;\n}\n\nexport function useAuthorizationHeader() {\n return useAuthContext().getAuthorizationHeader;\n}\n\n// ── Render helpers ─────────────────────────────────────────────────────────────\n\nexport function SignedIn({ children }: { children: React.ReactNode }) {\n const { isLoaded, isSignedIn } = useAuthContext();\n if (!isLoaded || !isSignedIn) return null;\n return <>{children}</>;\n}\n\nexport function SignedOut({ children }: { children: React.ReactNode }) {\n const { isLoaded, isSignedIn } = useAuthContext();\n if (!isLoaded || isSignedIn) return null;\n return <>{children}</>;\n}\n\nexport function AuthLoading({ children }: { children: React.ReactNode }) {\n const { isLoaded } = useAuthContext();\n return isLoaded ? null : <>{children}</>;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/provider.tsx"],"sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { Linking } from \"react-native\";\nimport { AuthRequest } from \"expo-auth-session\";\nimport * as WebBrowser from \"expo-web-browser\";\nimport * as SecureStore from \"expo-secure-store\";\nimport {\n initAuth,\n envFromPublishableKey,\n type AuthSession,\n type AuthStorage,\n type HeadlessClient,\n type HeadlessSignInResult,\n type HeadlessSignUpResult,\n type SmartHiveAuthClient,\n type SmartHiveAuthConfig,\n type SocialProvider,\n} from \"@smarthivelabs-devs/auth-sdk\";\n\n// ── Secure storage adapter ────────────────────────────────────────────────────\n\nconst secureStorage: AuthStorage = {\n getItem: (key) => SecureStore.getItemAsync(key),\n setItem: (key, value) => SecureStore.setItemAsync(key, value),\n removeItem: (key) => SecureStore.deleteItemAsync(key),\n};\n\nconst storageKeys = {\n pkceVerifier: \"smarthive.auth.pkce_verifier\",\n pkceState: \"smarthive.auth.pkce_state\"\n} as const;\n\n// ── Config ────────────────────────────────────────────────────────────────────\n\nexport interface SmartHiveExpoConfig extends Omit<SmartHiveAuthConfig, \"storage\"> {\n /** Deep link redirect URI, e.g. \"myapp://auth/callback\" */\n redirectUri: string;\n /**\n * URL of your own backend's social auth proxy (e.g. \"https://api.myapp.com\").\n * When set, social OAuth routes through your domain — Google/Apple consent screens\n * show your domain instead of SmartHive's. Your backend must implement\n * GET /api/auth/social/:provider and GET /api/auth/social/:provider/callback.\n */\n socialProxyUrl?: string;\n}\n\n/**\n * Build a deep link redirect URI from your Expo app scheme.\n * @example buildRedirectUri(\"myapp\") → \"myapp://auth/callback\"\n */\nexport function buildRedirectUri(scheme: string, path = \"auth/callback\"): string {\n return `${scheme}://${path}`;\n}\n\nfunction normalizeBaseUrl(baseUrl: string) {\n return baseUrl.replace(/\\/$/, \"\");\n}\n\n// ── Auth client (Expo flavour) ─────────────────────────────────────────────────\n\n/**\n * Creates an auth client that uses SecureStore for token storage and\n * Linking.openURL for the OAuth redirect (instead of location.assign).\n */\nexport function initExpoAuth(config: SmartHiveExpoConfig): SmartHiveAuthClient {\n const base = initAuth({\n ...config,\n storage: secureStorage,\n temporaryStorage: secureStorage\n } as SmartHiveAuthConfig);\n\n return {\n ...base,\n async login(options) {\n const redirectUri = options?.redirectUri ?? config.redirectUri;\n const authBase = normalizeBaseUrl(config.authDomain ?? config.baseUrl);\n const request = new AuthRequest({\n clientId: config.publishableKey,\n redirectUri,\n responseType: \"code\",\n usePKCE: true,\n state: options?.state,\n extraParams: {\n project_id: config.projectId,\n publishable_key: config.publishableKey\n }\n });\n const url = await request.makeAuthUrlAsync({\n authorizationEndpoint: `${authBase}/api/auth/oauth2/authorize`\n });\n\n if (request.codeVerifier) {\n await secureStorage.setItem(storageKeys.pkceVerifier, request.codeVerifier);\n }\n await secureStorage.setItem(storageKeys.pkceState, request.state);\n await Linking.openURL(url);\n },\n\n async loginSocial(provider, options) {\n const redirectUri = options?.redirectUri ?? config.redirectUri;\n let socialUrl: URL;\n\n if (config.socialProxyUrl) {\n // Route through the app's own backend — Google/Apple show the app's domain\n socialUrl = new URL(`${normalizeBaseUrl(config.socialProxyUrl)}/api/auth/social/${provider}`);\n socialUrl.searchParams.set(\"redirect_uri\", redirectUri);\n // project_id is injected server-side by the backend proxy\n } else {\n // Direct SmartHive route\n const authBase = normalizeBaseUrl(config.authDomain ?? config.baseUrl);\n const env = envFromPublishableKey(config.publishableKey);\n socialUrl = new URL(`${authBase}/${env}/api/auth/social/${provider}`);\n socialUrl.searchParams.set(\"project_id\", config.projectId);\n socialUrl.searchParams.set(\"redirect_uri\", redirectUri);\n }\n\n // In-app browser sheet — auto-closes when redirectUri fires\n const result = await WebBrowser.openAuthSessionAsync(socialUrl.toString(), redirectUri);\n if (result.type === \"success\") {\n await base.handleSocialCallback({ url: result.url });\n }\n },\n };\n}\n\n// ── Context ────────────────────────────────────────────────────────────────────\n\ninterface AuthContextValue {\n client: SmartHiveAuthClient;\n session: AuthSession | null;\n isLoaded: boolean;\n isSignedIn: boolean;\n /** OAuth 2.0 + PKCE browser redirect sign-in (unchanged). */\n login(options?: { redirectUri?: string }): Promise<void>;\n logout(): Promise<void>;\n refreshSession(): Promise<void>;\n getAuthorizationHeader(): Promise<Record<string, string>>;\n authFetch(input: string | URL | Request, init?: RequestInit): Promise<Response>;\n /**\n * Headless (no browser) sign-in methods for custom login screens.\n * Tokens are stored in SecureStore automatically on success.\n */\n signIn: {\n email(params: { email: string; password: string }): Promise<HeadlessSignInResult>;\n phone: {\n sendOtp(params: { phoneNumber: string }): Promise<void>;\n verify(params: { phoneNumber: string; code: string }): Promise<HeadlessSignInResult>;\n };\n emailOtp: {\n send(params: { email: string }): Promise<void>;\n verify(params: { email: string; code: string }): Promise<HeadlessSignInResult>;\n };\n magicLink: {\n send(params: { email: string; callbackURL?: string }): Promise<void>;\n };\n /** Initiate a social OAuth flow — opens an in-app browser sheet (expo-web-browser). Auto-closes on redirect and updates session state. */\n social(provider: SocialProvider, options?: { redirectUri?: string }): Promise<void>;\n };\n signUp: {\n email(params: { email: string; password: string; name?: string }): Promise<HeadlessSignUpResult>;\n };\n}\n\nconst AuthContext = createContext<AuthContextValue | null>(null);\n\n// ── Provider ───────────────────────────────────────────────────────────────────\n\nexport interface SmartHiveProviderProps extends SmartHiveExpoConfig {\n children: React.ReactNode;\n}\n\n/**\n * Wraps your Expo app and provides auth state to all child components.\n * Tokens are stored in SecureStore. Supports both:\n * - OAuth 2.0 + PKCE browser redirect via `login()`\n * - Headless direct sign-in via `signIn.*` (no browser, custom login screens)\n */\nexport function SmartHiveProvider({ children, ...config }: SmartHiveProviderProps) {\n const configRef = useRef(config);\n const client = useMemo(() => initExpoAuth(configRef.current), []);\n\n const [session, setSession] = useState<AuthSession | null>(null);\n const [isLoaded, setIsLoaded] = useState(false);\n\n // Initial session load from SecureStore\n useEffect(() => {\n let cancelled = false;\n client\n .initialize()\n .then(() => client.getSession())\n .then((s) => { if (!cancelled) setSession(s); })\n .catch(() => {})\n .finally(() => { if (!cancelled) setIsLoaded(true); });\n return () => { cancelled = true; };\n }, [client]);\n\n // Deep link listener — catches both PKCE and social OAuth callbacks\n useEffect(() => {\n function handleUrl({ url }: { url: string }) {\n try {\n const parsed = new URL(url);\n if (parsed.searchParams.has(\"access_token\") || parsed.searchParams.has(\"error\")) {\n // Social auth callback — tokens already in URL params\n client\n .handleSocialCallback({ url })\n .then((s) => setSession(s))\n .catch(() => {});\n } else {\n // PKCE OAuth callback — exchange code for tokens\n client\n .handleCallback({ url })\n .then((s) => setSession(s))\n .catch(() => {});\n }\n } catch {\n // Unparseable URL — ignore\n }\n }\n\n const sub = Linking.addEventListener(\"url\", handleUrl);\n\n // Handle cold-start: app opened directly from the OAuth redirect URL\n Linking.getInitialURL().then((url) => {\n if (url) handleUrl({ url });\n });\n\n return () => sub.remove();\n }, [client]);\n\n const login = useCallback(\n (options?: { redirectUri?: string }) => client.login(options),\n [client]\n );\n\n const logout = useCallback(async () => {\n await client.logout();\n setSession(null);\n }, [client]);\n\n const refreshSession = useCallback(async () => {\n setSession(await client.refreshSession());\n }, [client]);\n\n const getAuthorizationHeader = useCallback(\n () => client.getAuthorizationHeader(),\n [client]\n );\n\n const authFetch = useCallback(\n (input: string | URL | Request, init?: RequestInit) => client.fetch(input, init),\n [client]\n );\n\n // ── Headless sign-in wrappers — save session + update state ──────────────────\n\n function wrapHeadlessSignIn(\n fn: (p: never) => Promise<HeadlessSignInResult>\n ) {\n return async (params: never) => {\n const result = await fn(params);\n setSession({\n accessToken: result.accessToken,\n refreshToken: result.refreshToken,\n expiresAt: result.expiresAt,\n user: result.user,\n });\n return result;\n };\n }\n\n const signIn = useMemo<AuthContextValue[\"signIn\"]>(() => {\n const h: HeadlessClient = client.headless;\n return {\n email: wrapHeadlessSignIn(h.signIn.email.bind(h.signIn) as never),\n phone: {\n sendOtp: (p) => h.signIn.phone.sendOtp(p),\n verify: wrapHeadlessSignIn(h.signIn.phone.verify.bind(h.signIn.phone) as never),\n },\n emailOtp: {\n send: (p) => h.signIn.emailOtp.send(p),\n verify: wrapHeadlessSignIn(h.signIn.emailOtp.verify.bind(h.signIn.emailOtp) as never),\n },\n magicLink: {\n send: (p) => h.signIn.magicLink.send(p),\n },\n social: async (provider, options) => {\n await client.loginSocial(provider, options);\n // loginSocial used openAuthSessionAsync + handleSocialCallback — session is now in SecureStore\n const s = await client.getSession();\n if (s) setSession(s);\n },\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [client]);\n\n const signUp = useMemo<AuthContextValue[\"signUp\"]>(() => {\n const h: HeadlessClient = client.headless;\n return {\n email: async (params) => {\n const result = await h.signUp.email(params);\n if (!result.requiresVerification) {\n setSession({\n accessToken: result.accessToken,\n refreshToken: result.refreshToken,\n expiresAt: result.expiresAt,\n user: result.user,\n });\n }\n return result;\n },\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [client]);\n\n const value = useMemo<AuthContextValue>(\n () => ({\n client,\n session,\n isLoaded,\n isSignedIn: !!session,\n login,\n logout,\n refreshSession,\n getAuthorizationHeader,\n authFetch,\n signIn,\n signUp,\n }),\n [client, session, isLoaded, login, logout, refreshSession, getAuthorizationHeader, authFetch, signIn, signUp]\n );\n\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\n}\n\n// ── Hooks ──────────────────────────────────────────────────────────────────────\n\nfunction useAuthContext(): AuthContextValue {\n const ctx = useContext(AuthContext);\n if (!ctx) throw new Error(\"useAuth must be used inside <SmartHiveProvider>.\");\n return ctx;\n}\n\nexport function useAuth() { return useAuthContext(); }\nexport function useSession() { return useAuthContext().session; }\nexport function useUser() { return useAuthContext().session?.user ?? null; }\nexport function useIsLoaded() { return useAuthContext().isLoaded; }\n\nexport function useIsSignedIn() {\n const { isLoaded, isSignedIn } = useAuthContext();\n return isLoaded ? isSignedIn : null;\n}\n\nexport function useAuthFetch() {\n return useAuthContext().authFetch;\n}\n\nexport function useAuthorizationHeader() {\n return useAuthContext().getAuthorizationHeader;\n}\n\n// ── Render helpers ─────────────────────────────────────────────────────────────\n\nexport function SignedIn({ children }: { children: React.ReactNode }) {\n const { isLoaded, isSignedIn } = useAuthContext();\n if (!isLoaded || !isSignedIn) return null;\n return <>{children}</>;\n}\n\nexport function SignedOut({ children }: { children: React.ReactNode }) {\n const { isLoaded, isSignedIn } = useAuthContext();\n if (!isLoaded || isSignedIn) return null;\n return <>{children}</>;\n}\n\nexport function AuthLoading({ children }: { children: React.ReactNode }) {\n const { isLoaded } = useAuthContext();\n return isLoaded ? null : <>{children}</>;\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smarthivelabs-devs/auth-expo",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "SmartHive Auth provider, hooks, and SecureStore integration for React Native / Expo",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -25,18 +25,20 @@
25
25
  "LICENSE"
26
26
  ],
27
27
  "peerDependencies": {
28
- "@smarthivelabs-devs/auth-sdk": "^1.1.0",
28
+ "@smarthivelabs-devs/auth-sdk": "^1.3.0",
29
29
  "expo-auth-session": ">=5",
30
30
  "expo-secure-store": ">=12",
31
+ "expo-web-browser": ">=12",
31
32
  "react": ">=18",
32
33
  "react-native": ">=0.73"
33
34
  },
34
35
  "devDependencies": {
35
36
  "@types/react": "^18.3.18",
36
37
  "@types/react-native": "^0.73.0",
38
+ "expo-web-browser": "^55.0.15",
37
39
  "tsup": "^8.3.0",
38
40
  "typescript": "^5.7.3",
39
- "@smarthivelabs-devs/auth-sdk": "^1.1.0"
41
+ "@smarthivelabs-devs/auth-sdk": "^1.3.0"
40
42
  },
41
43
  "scripts": {
42
44
  "build": "tsup",