@authon/react-native 0.1.19 → 0.1.20
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/dist/index.cjs +17 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -17
- package/dist/index.d.ts +11 -17
- package/dist/index.js +17 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -63,21 +63,21 @@ var AuthonMobileClient = class {
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
async signIn(params) {
|
|
66
|
-
const res = await this.request("POST", "/v1/auth/
|
|
67
|
-
this.tokens = res;
|
|
66
|
+
const res = await this.request("POST", "/v1/auth/signin", params);
|
|
67
|
+
this.tokens = this.toTokenPair(res);
|
|
68
68
|
await this.persistTokens();
|
|
69
69
|
return this.tokens;
|
|
70
70
|
}
|
|
71
71
|
async signUp(params) {
|
|
72
|
-
const res = await this.request("POST", "/v1/auth/
|
|
73
|
-
this.tokens = res;
|
|
72
|
+
const res = await this.request("POST", "/v1/auth/signup", params);
|
|
73
|
+
this.tokens = this.toTokenPair(res);
|
|
74
74
|
await this.persistTokens();
|
|
75
75
|
return this.tokens;
|
|
76
76
|
}
|
|
77
77
|
async signOut() {
|
|
78
78
|
if (this.tokens) {
|
|
79
79
|
try {
|
|
80
|
-
await this.request("POST", "/v1/auth/
|
|
80
|
+
await this.request("POST", "/v1/auth/signout", void 0);
|
|
81
81
|
} catch {
|
|
82
82
|
}
|
|
83
83
|
}
|
|
@@ -98,11 +98,11 @@ var AuthonMobileClient = class {
|
|
|
98
98
|
const token = refreshToken || this.tokens?.refreshToken;
|
|
99
99
|
if (!token) return null;
|
|
100
100
|
try {
|
|
101
|
-
const res = await fetch(`${this.apiUrl}/v1/auth/refresh`, {
|
|
101
|
+
const res = await fetch(`${this.apiUrl}/v1/auth/token/refresh`, {
|
|
102
102
|
method: "POST",
|
|
103
103
|
headers: {
|
|
104
104
|
"Content-Type": "application/json",
|
|
105
|
-
"
|
|
105
|
+
"x-api-key": this.publishableKey
|
|
106
106
|
},
|
|
107
107
|
body: JSON.stringify({ refreshToken: token })
|
|
108
108
|
});
|
|
@@ -111,7 +111,8 @@ var AuthonMobileClient = class {
|
|
|
111
111
|
if (this.storage) await this.storage.removeItem(STORAGE_KEY);
|
|
112
112
|
return null;
|
|
113
113
|
}
|
|
114
|
-
|
|
114
|
+
const data = await res.json();
|
|
115
|
+
this.tokens = this.toTokenPair(data);
|
|
115
116
|
await this.persistTokens();
|
|
116
117
|
return this.tokens;
|
|
117
118
|
} catch {
|
|
@@ -129,10 +130,17 @@ var AuthonMobileClient = class {
|
|
|
129
130
|
await this.storage.setItem(STORAGE_KEY, JSON.stringify(this.tokens));
|
|
130
131
|
}
|
|
131
132
|
}
|
|
133
|
+
toTokenPair(res) {
|
|
134
|
+
return {
|
|
135
|
+
accessToken: res.accessToken,
|
|
136
|
+
refreshToken: res.refreshToken,
|
|
137
|
+
expiresAt: Date.now() + res.expiresIn * 1e3
|
|
138
|
+
};
|
|
139
|
+
}
|
|
132
140
|
async request(method, path, body) {
|
|
133
141
|
const headers = {
|
|
134
142
|
"Content-Type": "application/json",
|
|
135
|
-
"
|
|
143
|
+
"x-api-key": this.publishableKey
|
|
136
144
|
};
|
|
137
145
|
if (this.tokens?.accessToken) {
|
|
138
146
|
headers["Authorization"] = `Bearer ${this.tokens.accessToken}`;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/AuthonProvider.tsx","../src/client.ts","../src/useAuthon.ts","../src/useUser.ts"],"sourcesContent":["export { AuthonProvider, AuthonContext } from './AuthonProvider';\nexport type { AuthonContextValue } from './AuthonProvider';\nexport { useAuthon } from './useAuthon';\nexport { useUser } from './useUser';\nexport { AuthonMobileClient } from './client';\nexport type {\n AuthonReactNativeConfig,\n AuthState,\n AuthonUser,\n SignInParams,\n SignUpParams,\n} from './types';\n","import React, { createContext, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { AuthonMobileClient } from './client';\nimport type { AuthState, AuthonReactNativeConfig, AuthonUser, SignInParams, SignUpParams } from './types';\n\nexport interface AuthonContextValue extends AuthState {\n user: AuthonUser | null;\n signIn: (params: SignInParams) => Promise<void>;\n signUp: (params: SignUpParams) => Promise<void>;\n signOut: () => Promise<void>;\n getToken: () => string | null;\n}\n\nexport const AuthonContext = createContext<AuthonContextValue | null>(null);\n\ninterface AuthonProviderProps extends AuthonReactNativeConfig {\n children: React.ReactNode;\n storage?: {\n getItem(key: string): Promise<string | null>;\n setItem(key: string, value: string): Promise<void>;\n removeItem(key: string): Promise<void>;\n };\n}\n\nexport function AuthonProvider({ children, storage, ...config }: AuthonProviderProps) {\n const clientRef = useRef<AuthonMobileClient | null>(null);\n const [authState, setAuthState] = useState<AuthState>({\n isLoaded: false,\n isSignedIn: false,\n userId: null,\n sessionId: null,\n accessToken: null,\n });\n const [user, setUser] = useState<AuthonUser | null>(null);\n\n if (!clientRef.current) {\n clientRef.current = new AuthonMobileClient(config);\n }\n\n const client = clientRef.current;\n\n useEffect(() => {\n if (storage) {\n client.setStorage(storage);\n }\n\n client.initialize().then(async (tokens) => {\n if (tokens) {\n const u = await client.getUser();\n setUser(u);\n setAuthState({\n isLoaded: true,\n isSignedIn: true,\n userId: u?.id || null,\n sessionId: null,\n accessToken: tokens.accessToken,\n });\n } else {\n setAuthState((prev) => ({ ...prev, isLoaded: true }));\n }\n });\n }, []);\n\n const signIn = useCallback(async (params: SignInParams) => {\n const tokens = await client.signIn(params);\n const u = await client.getUser();\n setUser(u);\n setAuthState({\n isLoaded: true,\n isSignedIn: true,\n userId: u?.id || null,\n sessionId: null,\n accessToken: tokens.accessToken,\n });\n }, [client]);\n\n const signUp = useCallback(async (params: SignUpParams) => {\n const tokens = await client.signUp(params);\n const u = await client.getUser();\n setUser(u);\n setAuthState({\n isLoaded: true,\n isSignedIn: true,\n userId: u?.id || null,\n sessionId: null,\n accessToken: tokens.accessToken,\n });\n }, [client]);\n\n const signOut = useCallback(async () => {\n await client.signOut();\n setUser(null);\n setAuthState({\n isLoaded: true,\n isSignedIn: false,\n userId: null,\n sessionId: null,\n accessToken: null,\n });\n }, [client]);\n\n const getToken = useCallback(() => {\n return client.getAccessToken();\n }, [client]);\n\n const value = useMemo<AuthonContextValue>(\n () => ({\n ...authState,\n user,\n signIn,\n signUp,\n signOut,\n getToken,\n }),\n [authState, user, signIn, signUp, signOut, getToken],\n );\n\n return <AuthonContext.Provider value={value}>{children}</AuthonContext.Provider>;\n}\n","import type { AuthonReactNativeConfig, AuthonUser, SignInParams, SignUpParams } from './types';\n\nconst DEFAULT_API_URL = 'https://api.authon.dev';\n\ninterface TokenPair {\n accessToken: string;\n refreshToken: string;\n expiresAt: number;\n}\n\ntype TokenStorage = {\n getItem(key: string): Promise<string | null>;\n setItem(key: string, value: string): Promise<void>;\n removeItem(key: string): Promise<void>;\n};\n\nconst STORAGE_KEY = '@authon/tokens';\n\nexport class AuthonMobileClient {\n private apiUrl: string;\n private publishableKey: string;\n private tokens: TokenPair | null = null;\n private storage: TokenStorage | null = null;\n\n constructor(config: AuthonReactNativeConfig) {\n this.publishableKey = config.publishableKey;\n this.apiUrl = (config.apiUrl || DEFAULT_API_URL).replace(/\\/$/, '');\n }\n\n setStorage(storage: TokenStorage) {\n this.storage = storage;\n }\n\n async initialize(): Promise<TokenPair | null> {\n if (!this.storage) return null;\n\n const stored = await this.storage.getItem(STORAGE_KEY);\n if (!stored) return null;\n\n try {\n const tokens: TokenPair = JSON.parse(stored);\n if (tokens.expiresAt > Date.now()) {\n this.tokens = tokens;\n return tokens;\n }\n // Try refreshing\n return await this.refreshToken(tokens.refreshToken);\n } catch {\n await this.storage.removeItem(STORAGE_KEY);\n return null;\n }\n }\n\n async signIn(params: SignInParams): Promise<TokenPair> {\n const res = await this.request('POST', '/v1/auth/sign-in', params);\n this.tokens = res as TokenPair;\n await this.persistTokens();\n return this.tokens;\n }\n\n async signUp(params: SignUpParams): Promise<TokenPair> {\n const res = await this.request('POST', '/v1/auth/sign-up', params);\n this.tokens = res as TokenPair;\n await this.persistTokens();\n return this.tokens;\n }\n\n async signOut(): Promise<void> {\n if (this.tokens) {\n try {\n await this.request('POST', '/v1/auth/sign-out', undefined);\n } catch {\n // Ignore sign-out errors\n }\n }\n this.tokens = null;\n if (this.storage) {\n await this.storage.removeItem(STORAGE_KEY);\n }\n }\n\n async getUser(): Promise<AuthonUser | null> {\n if (!this.tokens) return null;\n try {\n return (await this.request('GET', '/v1/auth/me')) as AuthonUser;\n } catch {\n return null;\n }\n }\n\n async refreshToken(refreshToken?: string): Promise<TokenPair | null> {\n const token = refreshToken || this.tokens?.refreshToken;\n if (!token) return null;\n\n try {\n const res = await fetch(`${this.apiUrl}/v1/auth/refresh`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Publishable-Key': this.publishableKey,\n },\n body: JSON.stringify({ refreshToken: token }),\n });\n\n if (!res.ok) {\n this.tokens = null;\n if (this.storage) await this.storage.removeItem(STORAGE_KEY);\n return null;\n }\n\n this.tokens = (await res.json()) as TokenPair;\n await this.persistTokens();\n return this.tokens;\n } catch {\n return null;\n }\n }\n\n getAccessToken(): string | null {\n return this.tokens?.accessToken || null;\n }\n\n isAuthenticated(): boolean {\n return this.tokens !== null && this.tokens.expiresAt > Date.now();\n }\n\n private async persistTokens(): Promise<void> {\n if (this.storage && this.tokens) {\n await this.storage.setItem(STORAGE_KEY, JSON.stringify(this.tokens));\n }\n }\n\n private async request(method: string, path: string, body?: unknown): Promise<unknown> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-Publishable-Key': this.publishableKey,\n };\n\n if (this.tokens?.accessToken) {\n headers['Authorization'] = `Bearer ${this.tokens.accessToken}`;\n }\n\n const res = await fetch(`${this.apiUrl}${path}`, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!res.ok) {\n const error = await res.json().catch(() => ({ message: res.statusText }));\n throw new Error(error.message || `Request failed with status ${res.status}`);\n }\n\n const text = await res.text();\n return text ? JSON.parse(text) : undefined;\n }\n}\n","import { useContext } from 'react';\nimport { AuthonContext, type AuthonContextValue } from './AuthonProvider';\n\nexport function useAuthon(): AuthonContextValue {\n const context = useContext(AuthonContext);\n if (!context) {\n throw new Error('useAuthon must be used within an <AuthonProvider>');\n }\n return context;\n}\n","import { useAuthon } from './useAuthon';\nimport type { AuthonUser } from './types';\n\nexport function useUser(): {\n isLoaded: boolean;\n isSignedIn: boolean;\n user: AuthonUser | null;\n} {\n const { isLoaded, isSignedIn, user } = useAuthon();\n return { isLoaded, isSignedIn, user };\n}\n"],"mappings":"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","names":["import_react"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/AuthonProvider.tsx","../src/client.ts","../src/useAuthon.ts","../src/useUser.ts"],"sourcesContent":["export { AuthonProvider, AuthonContext } from './AuthonProvider';\nexport type { AuthonContextValue } from './AuthonProvider';\nexport { useAuthon } from './useAuthon';\nexport { useUser } from './useUser';\nexport { AuthonMobileClient } from './client';\nexport type {\n AuthonReactNativeConfig,\n AuthState,\n AuthonUser,\n SignInParams,\n SignUpParams,\n} from './types';\n","import React, { createContext, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { AuthonMobileClient } from './client';\nimport type { AuthState, AuthonReactNativeConfig, AuthonUser, SignInParams, SignUpParams } from './types';\n\nexport interface AuthonContextValue extends AuthState {\n user: AuthonUser | null;\n signIn: (params: SignInParams) => Promise<void>;\n signUp: (params: SignUpParams) => Promise<void>;\n signOut: () => Promise<void>;\n getToken: () => string | null;\n}\n\nexport const AuthonContext = createContext<AuthonContextValue | null>(null);\n\ninterface AuthonProviderProps extends AuthonReactNativeConfig {\n children: React.ReactNode;\n storage?: {\n getItem(key: string): Promise<string | null>;\n setItem(key: string, value: string): Promise<void>;\n removeItem(key: string): Promise<void>;\n };\n}\n\nexport function AuthonProvider({ children, storage, ...config }: AuthonProviderProps) {\n const clientRef = useRef<AuthonMobileClient | null>(null);\n const [authState, setAuthState] = useState<AuthState>({\n isLoaded: false,\n isSignedIn: false,\n userId: null,\n sessionId: null,\n accessToken: null,\n });\n const [user, setUser] = useState<AuthonUser | null>(null);\n\n if (!clientRef.current) {\n clientRef.current = new AuthonMobileClient(config);\n }\n\n const client = clientRef.current;\n\n useEffect(() => {\n if (storage) {\n client.setStorage(storage);\n }\n\n client.initialize().then(async (tokens) => {\n if (tokens) {\n const u = await client.getUser();\n setUser(u);\n setAuthState({\n isLoaded: true,\n isSignedIn: true,\n userId: u?.id || null,\n sessionId: null,\n accessToken: tokens.accessToken,\n });\n } else {\n setAuthState((prev) => ({ ...prev, isLoaded: true }));\n }\n });\n }, []);\n\n const signIn = useCallback(async (params: SignInParams) => {\n const tokens = await client.signIn(params);\n const u = await client.getUser();\n setUser(u);\n setAuthState({\n isLoaded: true,\n isSignedIn: true,\n userId: u?.id || null,\n sessionId: null,\n accessToken: tokens.accessToken,\n });\n }, [client]);\n\n const signUp = useCallback(async (params: SignUpParams) => {\n const tokens = await client.signUp(params);\n const u = await client.getUser();\n setUser(u);\n setAuthState({\n isLoaded: true,\n isSignedIn: true,\n userId: u?.id || null,\n sessionId: null,\n accessToken: tokens.accessToken,\n });\n }, [client]);\n\n const signOut = useCallback(async () => {\n await client.signOut();\n setUser(null);\n setAuthState({\n isLoaded: true,\n isSignedIn: false,\n userId: null,\n sessionId: null,\n accessToken: null,\n });\n }, [client]);\n\n const getToken = useCallback(() => {\n return client.getAccessToken();\n }, [client]);\n\n const value = useMemo<AuthonContextValue>(\n () => ({\n ...authState,\n user,\n signIn,\n signUp,\n signOut,\n getToken,\n }),\n [authState, user, signIn, signUp, signOut, getToken],\n );\n\n return <AuthonContext.Provider value={value}>{children}</AuthonContext.Provider>;\n}\n","import type { AuthonReactNativeConfig, AuthonUser, SignInParams, SignUpParams } from './types';\n\nconst DEFAULT_API_URL = 'https://api.authon.dev';\n\ninterface TokenPair {\n accessToken: string;\n refreshToken: string;\n expiresAt: number;\n}\n\ninterface ApiAuthResponse {\n accessToken: string;\n refreshToken: string;\n expiresIn: number;\n user: AuthonUser;\n}\n\ntype TokenStorage = {\n getItem(key: string): Promise<string | null>;\n setItem(key: string, value: string): Promise<void>;\n removeItem(key: string): Promise<void>;\n};\n\nconst STORAGE_KEY = '@authon/tokens';\n\nexport class AuthonMobileClient {\n private apiUrl: string;\n private publishableKey: string;\n private tokens: TokenPair | null = null;\n private storage: TokenStorage | null = null;\n\n constructor(config: AuthonReactNativeConfig) {\n this.publishableKey = config.publishableKey;\n this.apiUrl = (config.apiUrl || DEFAULT_API_URL).replace(/\\/$/, '');\n }\n\n setStorage(storage: TokenStorage) {\n this.storage = storage;\n }\n\n async initialize(): Promise<TokenPair | null> {\n if (!this.storage) return null;\n\n const stored = await this.storage.getItem(STORAGE_KEY);\n if (!stored) return null;\n\n try {\n const tokens: TokenPair = JSON.parse(stored);\n if (tokens.expiresAt > Date.now()) {\n this.tokens = tokens;\n return tokens;\n }\n // Try refreshing\n return await this.refreshToken(tokens.refreshToken);\n } catch {\n await this.storage.removeItem(STORAGE_KEY);\n return null;\n }\n }\n\n async signIn(params: SignInParams): Promise<TokenPair> {\n const res = (await this.request('POST', '/v1/auth/signin', params)) as ApiAuthResponse;\n this.tokens = this.toTokenPair(res);\n await this.persistTokens();\n return this.tokens;\n }\n\n async signUp(params: SignUpParams): Promise<TokenPair> {\n const res = (await this.request('POST', '/v1/auth/signup', params)) as ApiAuthResponse;\n this.tokens = this.toTokenPair(res);\n await this.persistTokens();\n return this.tokens;\n }\n\n async signOut(): Promise<void> {\n if (this.tokens) {\n try {\n await this.request('POST', '/v1/auth/signout', undefined);\n } catch {\n // Ignore sign-out errors\n }\n }\n this.tokens = null;\n if (this.storage) {\n await this.storage.removeItem(STORAGE_KEY);\n }\n }\n\n async getUser(): Promise<AuthonUser | null> {\n if (!this.tokens) return null;\n try {\n return (await this.request('GET', '/v1/auth/me')) as AuthonUser;\n } catch {\n return null;\n }\n }\n\n async refreshToken(refreshToken?: string): Promise<TokenPair | null> {\n const token = refreshToken || this.tokens?.refreshToken;\n if (!token) return null;\n\n try {\n const res = await fetch(`${this.apiUrl}/v1/auth/token/refresh`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.publishableKey,\n },\n body: JSON.stringify({ refreshToken: token }),\n });\n\n if (!res.ok) {\n this.tokens = null;\n if (this.storage) await this.storage.removeItem(STORAGE_KEY);\n return null;\n }\n\n const data = (await res.json()) as ApiAuthResponse;\n this.tokens = this.toTokenPair(data);\n await this.persistTokens();\n return this.tokens;\n } catch {\n return null;\n }\n }\n\n getAccessToken(): string | null {\n return this.tokens?.accessToken || null;\n }\n\n isAuthenticated(): boolean {\n return this.tokens !== null && this.tokens.expiresAt > Date.now();\n }\n\n private async persistTokens(): Promise<void> {\n if (this.storage && this.tokens) {\n await this.storage.setItem(STORAGE_KEY, JSON.stringify(this.tokens));\n }\n }\n\n private toTokenPair(res: ApiAuthResponse): TokenPair {\n return {\n accessToken: res.accessToken,\n refreshToken: res.refreshToken,\n expiresAt: Date.now() + res.expiresIn * 1000,\n };\n }\n\n private async request(method: string, path: string, body?: unknown): Promise<unknown> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-api-key': this.publishableKey,\n };\n\n if (this.tokens?.accessToken) {\n headers['Authorization'] = `Bearer ${this.tokens.accessToken}`;\n }\n\n const res = await fetch(`${this.apiUrl}${path}`, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!res.ok) {\n const error = await res.json().catch(() => ({ message: res.statusText }));\n throw new Error(error.message || `Request failed with status ${res.status}`);\n }\n\n const text = await res.text();\n return text ? JSON.parse(text) : undefined;\n }\n}\n","import { useContext } from 'react';\nimport { AuthonContext, type AuthonContextValue } from './AuthonProvider';\n\nexport function useAuthon(): AuthonContextValue {\n const context = useContext(AuthonContext);\n if (!context) {\n throw new Error('useAuthon must be used within an <AuthonProvider>');\n }\n return context;\n}\n","import { useAuthon } from './useAuthon';\nimport type { AuthonUser } from './types';\n\nexport function useUser(): {\n isLoaded: boolean;\n isSignedIn: boolean;\n user: AuthonUser | null;\n} {\n const { isLoaded, isSignedIn, user } = useAuthon();\n return { isLoaded, isSignedIn, user };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,mBAAwF;;;ACExF,IAAM,kBAAkB;AAqBxB,IAAM,cAAc;AAEb,IAAM,qBAAN,MAAyB;AAAA,EACtB;AAAA,EACA;AAAA,EACA,SAA2B;AAAA,EAC3B,UAA+B;AAAA,EAEvC,YAAY,QAAiC;AAC3C,SAAK,iBAAiB,OAAO;AAC7B,SAAK,UAAU,OAAO,UAAU,iBAAiB,QAAQ,OAAO,EAAE;AAAA,EACpE;AAAA,EAEA,WAAW,SAAuB;AAChC,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,MAAM,aAAwC;AAC5C,QAAI,CAAC,KAAK,QAAS,QAAO;AAE1B,UAAM,SAAS,MAAM,KAAK,QAAQ,QAAQ,WAAW;AACrD,QAAI,CAAC,OAAQ,QAAO;AAEpB,QAAI;AACF,YAAM,SAAoB,KAAK,MAAM,MAAM;AAC3C,UAAI,OAAO,YAAY,KAAK,IAAI,GAAG;AACjC,aAAK,SAAS;AACd,eAAO;AAAA,MACT;AAEA,aAAO,MAAM,KAAK,aAAa,OAAO,YAAY;AAAA,IACpD,QAAQ;AACN,YAAM,KAAK,QAAQ,WAAW,WAAW;AACzC,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,QAA0C;AACrD,UAAM,MAAO,MAAM,KAAK,QAAQ,QAAQ,mBAAmB,MAAM;AACjE,SAAK,SAAS,KAAK,YAAY,GAAG;AAClC,UAAM,KAAK,cAAc;AACzB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,OAAO,QAA0C;AACrD,UAAM,MAAO,MAAM,KAAK,QAAQ,QAAQ,mBAAmB,MAAM;AACjE,SAAK,SAAS,KAAK,YAAY,GAAG;AAClC,UAAM,KAAK,cAAc;AACzB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,UAAyB;AAC7B,QAAI,KAAK,QAAQ;AACf,UAAI;AACF,cAAM,KAAK,QAAQ,QAAQ,oBAAoB,MAAS;AAAA,MAC1D,QAAQ;AAAA,MAER;AAAA,IACF;AACA,SAAK,SAAS;AACd,QAAI,KAAK,SAAS;AAChB,YAAM,KAAK,QAAQ,WAAW,WAAW;AAAA,IAC3C;AAAA,EACF;AAAA,EAEA,MAAM,UAAsC;AAC1C,QAAI,CAAC,KAAK,OAAQ,QAAO;AACzB,QAAI;AACF,aAAQ,MAAM,KAAK,QAAQ,OAAO,aAAa;AAAA,IACjD,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,cAAkD;AACnE,UAAM,QAAQ,gBAAgB,KAAK,QAAQ;AAC3C,QAAI,CAAC,MAAO,QAAO;AAEnB,QAAI;AACF,YAAM,MAAM,MAAM,MAAM,GAAG,KAAK,MAAM,0BAA0B;AAAA,QAC9D,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,aAAa,KAAK;AAAA,QACpB;AAAA,QACA,MAAM,KAAK,UAAU,EAAE,cAAc,MAAM,CAAC;AAAA,MAC9C,CAAC;AAED,UAAI,CAAC,IAAI,IAAI;AACX,aAAK,SAAS;AACd,YAAI,KAAK,QAAS,OAAM,KAAK,QAAQ,WAAW,WAAW;AAC3D,eAAO;AAAA,MACT;AAEA,YAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,WAAK,SAAS,KAAK,YAAY,IAAI;AACnC,YAAM,KAAK,cAAc;AACzB,aAAO,KAAK;AAAA,IACd,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,iBAAgC;AAC9B,WAAO,KAAK,QAAQ,eAAe;AAAA,EACrC;AAAA,EAEA,kBAA2B;AACzB,WAAO,KAAK,WAAW,QAAQ,KAAK,OAAO,YAAY,KAAK,IAAI;AAAA,EAClE;AAAA,EAEA,MAAc,gBAA+B;AAC3C,QAAI,KAAK,WAAW,KAAK,QAAQ;AAC/B,YAAM,KAAK,QAAQ,QAAQ,aAAa,KAAK,UAAU,KAAK,MAAM,CAAC;AAAA,IACrE;AAAA,EACF;AAAA,EAEQ,YAAY,KAAiC;AACnD,WAAO;AAAA,MACL,aAAa,IAAI;AAAA,MACjB,cAAc,IAAI;AAAA,MAClB,WAAW,KAAK,IAAI,IAAI,IAAI,YAAY;AAAA,IAC1C;AAAA,EACF;AAAA,EAEA,MAAc,QAAQ,QAAgB,MAAc,MAAkC;AACpF,UAAM,UAAkC;AAAA,MACtC,gBAAgB;AAAA,MAChB,aAAa,KAAK;AAAA,IACpB;AAEA,QAAI,KAAK,QAAQ,aAAa;AAC5B,cAAQ,eAAe,IAAI,UAAU,KAAK,OAAO,WAAW;AAAA,IAC9D;AAEA,UAAM,MAAM,MAAM,MAAM,GAAG,KAAK,MAAM,GAAG,IAAI,IAAI;AAAA,MAC/C;AAAA,MACA;AAAA,MACA,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,IACtC,CAAC;AAED,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,QAAQ,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,EAAE,SAAS,IAAI,WAAW,EAAE;AACxE,YAAM,IAAI,MAAM,MAAM,WAAW,8BAA8B,IAAI,MAAM,EAAE;AAAA,IAC7E;AAEA,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,WAAO,OAAO,KAAK,MAAM,IAAI,IAAI;AAAA,EACnC;AACF;;;ADxDS;AAxGF,IAAM,oBAAgB,4BAAyC,IAAI;AAWnE,SAAS,eAAe,EAAE,UAAU,SAAS,GAAG,OAAO,GAAwB;AACpF,QAAM,gBAAY,qBAAkC,IAAI;AACxD,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAoB;AAAA,IACpD,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,aAAa;AAAA,EACf,CAAC;AACD,QAAM,CAAC,MAAM,OAAO,QAAI,uBAA4B,IAAI;AAExD,MAAI,CAAC,UAAU,SAAS;AACtB,cAAU,UAAU,IAAI,mBAAmB,MAAM;AAAA,EACnD;AAEA,QAAM,SAAS,UAAU;AAEzB,8BAAU,MAAM;AACd,QAAI,SAAS;AACX,aAAO,WAAW,OAAO;AAAA,IAC3B;AAEA,WAAO,WAAW,EAAE,KAAK,OAAO,WAAW;AACzC,UAAI,QAAQ;AACV,cAAM,IAAI,MAAM,OAAO,QAAQ;AAC/B,gBAAQ,CAAC;AACT,qBAAa;AAAA,UACX,UAAU;AAAA,UACV,YAAY;AAAA,UACZ,QAAQ,GAAG,MAAM;AAAA,UACjB,WAAW;AAAA,UACX,aAAa,OAAO;AAAA,QACtB,CAAC;AAAA,MACH,OAAO;AACL,qBAAa,CAAC,UAAU,EAAE,GAAG,MAAM,UAAU,KAAK,EAAE;AAAA,MACtD;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,QAAM,aAAS,0BAAY,OAAO,WAAyB;AACzD,UAAM,SAAS,MAAM,OAAO,OAAO,MAAM;AACzC,UAAM,IAAI,MAAM,OAAO,QAAQ;AAC/B,YAAQ,CAAC;AACT,iBAAa;AAAA,MACX,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,QAAQ,GAAG,MAAM;AAAA,MACjB,WAAW;AAAA,MACX,aAAa,OAAO;AAAA,IACtB,CAAC;AAAA,EACH,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,aAAS,0BAAY,OAAO,WAAyB;AACzD,UAAM,SAAS,MAAM,OAAO,OAAO,MAAM;AACzC,UAAM,IAAI,MAAM,OAAO,QAAQ;AAC/B,YAAQ,CAAC;AACT,iBAAa;AAAA,MACX,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,QAAQ,GAAG,MAAM;AAAA,MACjB,WAAW;AAAA,MACX,aAAa,OAAO;AAAA,IACtB,CAAC;AAAA,EACH,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,cAAU,0BAAY,YAAY;AACtC,UAAM,OAAO,QAAQ;AACrB,YAAQ,IAAI;AACZ,iBAAa;AAAA,MACX,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,aAAa;AAAA,IACf,CAAC;AAAA,EACH,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,eAAW,0BAAY,MAAM;AACjC,WAAO,OAAO,eAAe;AAAA,EAC/B,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,YAAQ;AAAA,IACZ,OAAO;AAAA,MACL,GAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,WAAW,MAAM,QAAQ,QAAQ,SAAS,QAAQ;AAAA,EACrD;AAEA,SAAO,4CAAC,cAAc,UAAd,EAAuB,OAAe,UAAS;AACzD;;;AErHA,IAAAA,gBAA2B;AAGpB,SAAS,YAAgC;AAC9C,QAAM,cAAU,0BAAW,aAAa;AACxC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,mDAAmD;AAAA,EACrE;AACA,SAAO;AACT;;;ACNO,SAAS,UAId;AACA,QAAM,EAAE,UAAU,YAAY,KAAK,IAAI,UAAU;AACjD,SAAO,EAAE,UAAU,YAAY,KAAK;AACtC;","names":["import_react"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -14,22 +14,17 @@ interface AuthState {
|
|
|
14
14
|
}
|
|
15
15
|
interface AuthonUser {
|
|
16
16
|
id: string;
|
|
17
|
-
|
|
17
|
+
projectId: string;
|
|
18
|
+
email: string | null;
|
|
19
|
+
displayName: string | null;
|
|
20
|
+
avatarUrl: string | null;
|
|
21
|
+
phone: string | null;
|
|
18
22
|
emailVerified: boolean;
|
|
19
|
-
phone?: string;
|
|
20
23
|
phoneVerified: boolean;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
avatarUrl?: string;
|
|
26
|
-
banned: boolean;
|
|
27
|
-
metadata?: Record<string, unknown>;
|
|
28
|
-
externalAccounts?: Array<{
|
|
29
|
-
provider: string;
|
|
30
|
-
providerId: string;
|
|
31
|
-
email?: string;
|
|
32
|
-
}>;
|
|
24
|
+
isBanned: boolean;
|
|
25
|
+
publicMetadata: Record<string, unknown> | null;
|
|
26
|
+
lastSignInAt: string | null;
|
|
27
|
+
signInCount: number;
|
|
33
28
|
createdAt: string;
|
|
34
29
|
updatedAt: string;
|
|
35
30
|
}
|
|
@@ -42,9 +37,7 @@ interface SignInParams {
|
|
|
42
37
|
interface SignUpParams {
|
|
43
38
|
email: string;
|
|
44
39
|
password: string;
|
|
45
|
-
|
|
46
|
-
lastName?: string;
|
|
47
|
-
username?: string;
|
|
40
|
+
displayName?: string;
|
|
48
41
|
}
|
|
49
42
|
|
|
50
43
|
interface AuthonContextValue extends AuthState {
|
|
@@ -99,6 +92,7 @@ declare class AuthonMobileClient {
|
|
|
99
92
|
getAccessToken(): string | null;
|
|
100
93
|
isAuthenticated(): boolean;
|
|
101
94
|
private persistTokens;
|
|
95
|
+
private toTokenPair;
|
|
102
96
|
private request;
|
|
103
97
|
}
|
|
104
98
|
|
package/dist/index.d.ts
CHANGED
|
@@ -14,22 +14,17 @@ interface AuthState {
|
|
|
14
14
|
}
|
|
15
15
|
interface AuthonUser {
|
|
16
16
|
id: string;
|
|
17
|
-
|
|
17
|
+
projectId: string;
|
|
18
|
+
email: string | null;
|
|
19
|
+
displayName: string | null;
|
|
20
|
+
avatarUrl: string | null;
|
|
21
|
+
phone: string | null;
|
|
18
22
|
emailVerified: boolean;
|
|
19
|
-
phone?: string;
|
|
20
23
|
phoneVerified: boolean;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
avatarUrl?: string;
|
|
26
|
-
banned: boolean;
|
|
27
|
-
metadata?: Record<string, unknown>;
|
|
28
|
-
externalAccounts?: Array<{
|
|
29
|
-
provider: string;
|
|
30
|
-
providerId: string;
|
|
31
|
-
email?: string;
|
|
32
|
-
}>;
|
|
24
|
+
isBanned: boolean;
|
|
25
|
+
publicMetadata: Record<string, unknown> | null;
|
|
26
|
+
lastSignInAt: string | null;
|
|
27
|
+
signInCount: number;
|
|
33
28
|
createdAt: string;
|
|
34
29
|
updatedAt: string;
|
|
35
30
|
}
|
|
@@ -42,9 +37,7 @@ interface SignInParams {
|
|
|
42
37
|
interface SignUpParams {
|
|
43
38
|
email: string;
|
|
44
39
|
password: string;
|
|
45
|
-
|
|
46
|
-
lastName?: string;
|
|
47
|
-
username?: string;
|
|
40
|
+
displayName?: string;
|
|
48
41
|
}
|
|
49
42
|
|
|
50
43
|
interface AuthonContextValue extends AuthState {
|
|
@@ -99,6 +92,7 @@ declare class AuthonMobileClient {
|
|
|
99
92
|
getAccessToken(): string | null;
|
|
100
93
|
isAuthenticated(): boolean;
|
|
101
94
|
private persistTokens;
|
|
95
|
+
private toTokenPair;
|
|
102
96
|
private request;
|
|
103
97
|
}
|
|
104
98
|
|
package/dist/index.js
CHANGED
|
@@ -33,21 +33,21 @@ var AuthonMobileClient = class {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
async signIn(params) {
|
|
36
|
-
const res = await this.request("POST", "/v1/auth/
|
|
37
|
-
this.tokens = res;
|
|
36
|
+
const res = await this.request("POST", "/v1/auth/signin", params);
|
|
37
|
+
this.tokens = this.toTokenPair(res);
|
|
38
38
|
await this.persistTokens();
|
|
39
39
|
return this.tokens;
|
|
40
40
|
}
|
|
41
41
|
async signUp(params) {
|
|
42
|
-
const res = await this.request("POST", "/v1/auth/
|
|
43
|
-
this.tokens = res;
|
|
42
|
+
const res = await this.request("POST", "/v1/auth/signup", params);
|
|
43
|
+
this.tokens = this.toTokenPair(res);
|
|
44
44
|
await this.persistTokens();
|
|
45
45
|
return this.tokens;
|
|
46
46
|
}
|
|
47
47
|
async signOut() {
|
|
48
48
|
if (this.tokens) {
|
|
49
49
|
try {
|
|
50
|
-
await this.request("POST", "/v1/auth/
|
|
50
|
+
await this.request("POST", "/v1/auth/signout", void 0);
|
|
51
51
|
} catch {
|
|
52
52
|
}
|
|
53
53
|
}
|
|
@@ -68,11 +68,11 @@ var AuthonMobileClient = class {
|
|
|
68
68
|
const token = refreshToken || this.tokens?.refreshToken;
|
|
69
69
|
if (!token) return null;
|
|
70
70
|
try {
|
|
71
|
-
const res = await fetch(`${this.apiUrl}/v1/auth/refresh`, {
|
|
71
|
+
const res = await fetch(`${this.apiUrl}/v1/auth/token/refresh`, {
|
|
72
72
|
method: "POST",
|
|
73
73
|
headers: {
|
|
74
74
|
"Content-Type": "application/json",
|
|
75
|
-
"
|
|
75
|
+
"x-api-key": this.publishableKey
|
|
76
76
|
},
|
|
77
77
|
body: JSON.stringify({ refreshToken: token })
|
|
78
78
|
});
|
|
@@ -81,7 +81,8 @@ var AuthonMobileClient = class {
|
|
|
81
81
|
if (this.storage) await this.storage.removeItem(STORAGE_KEY);
|
|
82
82
|
return null;
|
|
83
83
|
}
|
|
84
|
-
|
|
84
|
+
const data = await res.json();
|
|
85
|
+
this.tokens = this.toTokenPair(data);
|
|
85
86
|
await this.persistTokens();
|
|
86
87
|
return this.tokens;
|
|
87
88
|
} catch {
|
|
@@ -99,10 +100,17 @@ var AuthonMobileClient = class {
|
|
|
99
100
|
await this.storage.setItem(STORAGE_KEY, JSON.stringify(this.tokens));
|
|
100
101
|
}
|
|
101
102
|
}
|
|
103
|
+
toTokenPair(res) {
|
|
104
|
+
return {
|
|
105
|
+
accessToken: res.accessToken,
|
|
106
|
+
refreshToken: res.refreshToken,
|
|
107
|
+
expiresAt: Date.now() + res.expiresIn * 1e3
|
|
108
|
+
};
|
|
109
|
+
}
|
|
102
110
|
async request(method, path, body) {
|
|
103
111
|
const headers = {
|
|
104
112
|
"Content-Type": "application/json",
|
|
105
|
-
"
|
|
113
|
+
"x-api-key": this.publishableKey
|
|
106
114
|
};
|
|
107
115
|
if (this.tokens?.accessToken) {
|
|
108
116
|
headers["Authorization"] = `Bearer ${this.tokens.accessToken}`;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/AuthonProvider.tsx","../src/client.ts","../src/useAuthon.ts","../src/useUser.ts"],"sourcesContent":["import React, { createContext, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { AuthonMobileClient } from './client';\nimport type { AuthState, AuthonReactNativeConfig, AuthonUser, SignInParams, SignUpParams } from './types';\n\nexport interface AuthonContextValue extends AuthState {\n user: AuthonUser | null;\n signIn: (params: SignInParams) => Promise<void>;\n signUp: (params: SignUpParams) => Promise<void>;\n signOut: () => Promise<void>;\n getToken: () => string | null;\n}\n\nexport const AuthonContext = createContext<AuthonContextValue | null>(null);\n\ninterface AuthonProviderProps extends AuthonReactNativeConfig {\n children: React.ReactNode;\n storage?: {\n getItem(key: string): Promise<string | null>;\n setItem(key: string, value: string): Promise<void>;\n removeItem(key: string): Promise<void>;\n };\n}\n\nexport function AuthonProvider({ children, storage, ...config }: AuthonProviderProps) {\n const clientRef = useRef<AuthonMobileClient | null>(null);\n const [authState, setAuthState] = useState<AuthState>({\n isLoaded: false,\n isSignedIn: false,\n userId: null,\n sessionId: null,\n accessToken: null,\n });\n const [user, setUser] = useState<AuthonUser | null>(null);\n\n if (!clientRef.current) {\n clientRef.current = new AuthonMobileClient(config);\n }\n\n const client = clientRef.current;\n\n useEffect(() => {\n if (storage) {\n client.setStorage(storage);\n }\n\n client.initialize().then(async (tokens) => {\n if (tokens) {\n const u = await client.getUser();\n setUser(u);\n setAuthState({\n isLoaded: true,\n isSignedIn: true,\n userId: u?.id || null,\n sessionId: null,\n accessToken: tokens.accessToken,\n });\n } else {\n setAuthState((prev) => ({ ...prev, isLoaded: true }));\n }\n });\n }, []);\n\n const signIn = useCallback(async (params: SignInParams) => {\n const tokens = await client.signIn(params);\n const u = await client.getUser();\n setUser(u);\n setAuthState({\n isLoaded: true,\n isSignedIn: true,\n userId: u?.id || null,\n sessionId: null,\n accessToken: tokens.accessToken,\n });\n }, [client]);\n\n const signUp = useCallback(async (params: SignUpParams) => {\n const tokens = await client.signUp(params);\n const u = await client.getUser();\n setUser(u);\n setAuthState({\n isLoaded: true,\n isSignedIn: true,\n userId: u?.id || null,\n sessionId: null,\n accessToken: tokens.accessToken,\n });\n }, [client]);\n\n const signOut = useCallback(async () => {\n await client.signOut();\n setUser(null);\n setAuthState({\n isLoaded: true,\n isSignedIn: false,\n userId: null,\n sessionId: null,\n accessToken: null,\n });\n }, [client]);\n\n const getToken = useCallback(() => {\n return client.getAccessToken();\n }, [client]);\n\n const value = useMemo<AuthonContextValue>(\n () => ({\n ...authState,\n user,\n signIn,\n signUp,\n signOut,\n getToken,\n }),\n [authState, user, signIn, signUp, signOut, getToken],\n );\n\n return <AuthonContext.Provider value={value}>{children}</AuthonContext.Provider>;\n}\n","import type { AuthonReactNativeConfig, AuthonUser, SignInParams, SignUpParams } from './types';\n\nconst DEFAULT_API_URL = 'https://api.authon.dev';\n\ninterface TokenPair {\n accessToken: string;\n refreshToken: string;\n expiresAt: number;\n}\n\ntype TokenStorage = {\n getItem(key: string): Promise<string | null>;\n setItem(key: string, value: string): Promise<void>;\n removeItem(key: string): Promise<void>;\n};\n\nconst STORAGE_KEY = '@authon/tokens';\n\nexport class AuthonMobileClient {\n private apiUrl: string;\n private publishableKey: string;\n private tokens: TokenPair | null = null;\n private storage: TokenStorage | null = null;\n\n constructor(config: AuthonReactNativeConfig) {\n this.publishableKey = config.publishableKey;\n this.apiUrl = (config.apiUrl || DEFAULT_API_URL).replace(/\\/$/, '');\n }\n\n setStorage(storage: TokenStorage) {\n this.storage = storage;\n }\n\n async initialize(): Promise<TokenPair | null> {\n if (!this.storage) return null;\n\n const stored = await this.storage.getItem(STORAGE_KEY);\n if (!stored) return null;\n\n try {\n const tokens: TokenPair = JSON.parse(stored);\n if (tokens.expiresAt > Date.now()) {\n this.tokens = tokens;\n return tokens;\n }\n // Try refreshing\n return await this.refreshToken(tokens.refreshToken);\n } catch {\n await this.storage.removeItem(STORAGE_KEY);\n return null;\n }\n }\n\n async signIn(params: SignInParams): Promise<TokenPair> {\n const res = await this.request('POST', '/v1/auth/sign-in', params);\n this.tokens = res as TokenPair;\n await this.persistTokens();\n return this.tokens;\n }\n\n async signUp(params: SignUpParams): Promise<TokenPair> {\n const res = await this.request('POST', '/v1/auth/sign-up', params);\n this.tokens = res as TokenPair;\n await this.persistTokens();\n return this.tokens;\n }\n\n async signOut(): Promise<void> {\n if (this.tokens) {\n try {\n await this.request('POST', '/v1/auth/sign-out', undefined);\n } catch {\n // Ignore sign-out errors\n }\n }\n this.tokens = null;\n if (this.storage) {\n await this.storage.removeItem(STORAGE_KEY);\n }\n }\n\n async getUser(): Promise<AuthonUser | null> {\n if (!this.tokens) return null;\n try {\n return (await this.request('GET', '/v1/auth/me')) as AuthonUser;\n } catch {\n return null;\n }\n }\n\n async refreshToken(refreshToken?: string): Promise<TokenPair | null> {\n const token = refreshToken || this.tokens?.refreshToken;\n if (!token) return null;\n\n try {\n const res = await fetch(`${this.apiUrl}/v1/auth/refresh`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Publishable-Key': this.publishableKey,\n },\n body: JSON.stringify({ refreshToken: token }),\n });\n\n if (!res.ok) {\n this.tokens = null;\n if (this.storage) await this.storage.removeItem(STORAGE_KEY);\n return null;\n }\n\n this.tokens = (await res.json()) as TokenPair;\n await this.persistTokens();\n return this.tokens;\n } catch {\n return null;\n }\n }\n\n getAccessToken(): string | null {\n return this.tokens?.accessToken || null;\n }\n\n isAuthenticated(): boolean {\n return this.tokens !== null && this.tokens.expiresAt > Date.now();\n }\n\n private async persistTokens(): Promise<void> {\n if (this.storage && this.tokens) {\n await this.storage.setItem(STORAGE_KEY, JSON.stringify(this.tokens));\n }\n }\n\n private async request(method: string, path: string, body?: unknown): Promise<unknown> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-Publishable-Key': this.publishableKey,\n };\n\n if (this.tokens?.accessToken) {\n headers['Authorization'] = `Bearer ${this.tokens.accessToken}`;\n }\n\n const res = await fetch(`${this.apiUrl}${path}`, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!res.ok) {\n const error = await res.json().catch(() => ({ message: res.statusText }));\n throw new Error(error.message || `Request failed with status ${res.status}`);\n }\n\n const text = await res.text();\n return text ? JSON.parse(text) : undefined;\n }\n}\n","import { useContext } from 'react';\nimport { AuthonContext, type AuthonContextValue } from './AuthonProvider';\n\nexport function useAuthon(): AuthonContextValue {\n const context = useContext(AuthonContext);\n if (!context) {\n throw new Error('useAuthon must be used within an <AuthonProvider>');\n }\n return context;\n}\n","import { useAuthon } from './useAuthon';\nimport type { AuthonUser } from './types';\n\nexport function useUser(): {\n isLoaded: boolean;\n isSignedIn: boolean;\n user: AuthonUser | null;\n} {\n const { isLoaded, isSignedIn, user } = useAuthon();\n return { isLoaded, isSignedIn, user };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/AuthonProvider.tsx","../src/client.ts","../src/useAuthon.ts","../src/useUser.ts"],"sourcesContent":["import React, { createContext, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { AuthonMobileClient } from './client';\nimport type { AuthState, AuthonReactNativeConfig, AuthonUser, SignInParams, SignUpParams } from './types';\n\nexport interface AuthonContextValue extends AuthState {\n user: AuthonUser | null;\n signIn: (params: SignInParams) => Promise<void>;\n signUp: (params: SignUpParams) => Promise<void>;\n signOut: () => Promise<void>;\n getToken: () => string | null;\n}\n\nexport const AuthonContext = createContext<AuthonContextValue | null>(null);\n\ninterface AuthonProviderProps extends AuthonReactNativeConfig {\n children: React.ReactNode;\n storage?: {\n getItem(key: string): Promise<string | null>;\n setItem(key: string, value: string): Promise<void>;\n removeItem(key: string): Promise<void>;\n };\n}\n\nexport function AuthonProvider({ children, storage, ...config }: AuthonProviderProps) {\n const clientRef = useRef<AuthonMobileClient | null>(null);\n const [authState, setAuthState] = useState<AuthState>({\n isLoaded: false,\n isSignedIn: false,\n userId: null,\n sessionId: null,\n accessToken: null,\n });\n const [user, setUser] = useState<AuthonUser | null>(null);\n\n if (!clientRef.current) {\n clientRef.current = new AuthonMobileClient(config);\n }\n\n const client = clientRef.current;\n\n useEffect(() => {\n if (storage) {\n client.setStorage(storage);\n }\n\n client.initialize().then(async (tokens) => {\n if (tokens) {\n const u = await client.getUser();\n setUser(u);\n setAuthState({\n isLoaded: true,\n isSignedIn: true,\n userId: u?.id || null,\n sessionId: null,\n accessToken: tokens.accessToken,\n });\n } else {\n setAuthState((prev) => ({ ...prev, isLoaded: true }));\n }\n });\n }, []);\n\n const signIn = useCallback(async (params: SignInParams) => {\n const tokens = await client.signIn(params);\n const u = await client.getUser();\n setUser(u);\n setAuthState({\n isLoaded: true,\n isSignedIn: true,\n userId: u?.id || null,\n sessionId: null,\n accessToken: tokens.accessToken,\n });\n }, [client]);\n\n const signUp = useCallback(async (params: SignUpParams) => {\n const tokens = await client.signUp(params);\n const u = await client.getUser();\n setUser(u);\n setAuthState({\n isLoaded: true,\n isSignedIn: true,\n userId: u?.id || null,\n sessionId: null,\n accessToken: tokens.accessToken,\n });\n }, [client]);\n\n const signOut = useCallback(async () => {\n await client.signOut();\n setUser(null);\n setAuthState({\n isLoaded: true,\n isSignedIn: false,\n userId: null,\n sessionId: null,\n accessToken: null,\n });\n }, [client]);\n\n const getToken = useCallback(() => {\n return client.getAccessToken();\n }, [client]);\n\n const value = useMemo<AuthonContextValue>(\n () => ({\n ...authState,\n user,\n signIn,\n signUp,\n signOut,\n getToken,\n }),\n [authState, user, signIn, signUp, signOut, getToken],\n );\n\n return <AuthonContext.Provider value={value}>{children}</AuthonContext.Provider>;\n}\n","import type { AuthonReactNativeConfig, AuthonUser, SignInParams, SignUpParams } from './types';\n\nconst DEFAULT_API_URL = 'https://api.authon.dev';\n\ninterface TokenPair {\n accessToken: string;\n refreshToken: string;\n expiresAt: number;\n}\n\ninterface ApiAuthResponse {\n accessToken: string;\n refreshToken: string;\n expiresIn: number;\n user: AuthonUser;\n}\n\ntype TokenStorage = {\n getItem(key: string): Promise<string | null>;\n setItem(key: string, value: string): Promise<void>;\n removeItem(key: string): Promise<void>;\n};\n\nconst STORAGE_KEY = '@authon/tokens';\n\nexport class AuthonMobileClient {\n private apiUrl: string;\n private publishableKey: string;\n private tokens: TokenPair | null = null;\n private storage: TokenStorage | null = null;\n\n constructor(config: AuthonReactNativeConfig) {\n this.publishableKey = config.publishableKey;\n this.apiUrl = (config.apiUrl || DEFAULT_API_URL).replace(/\\/$/, '');\n }\n\n setStorage(storage: TokenStorage) {\n this.storage = storage;\n }\n\n async initialize(): Promise<TokenPair | null> {\n if (!this.storage) return null;\n\n const stored = await this.storage.getItem(STORAGE_KEY);\n if (!stored) return null;\n\n try {\n const tokens: TokenPair = JSON.parse(stored);\n if (tokens.expiresAt > Date.now()) {\n this.tokens = tokens;\n return tokens;\n }\n // Try refreshing\n return await this.refreshToken(tokens.refreshToken);\n } catch {\n await this.storage.removeItem(STORAGE_KEY);\n return null;\n }\n }\n\n async signIn(params: SignInParams): Promise<TokenPair> {\n const res = (await this.request('POST', '/v1/auth/signin', params)) as ApiAuthResponse;\n this.tokens = this.toTokenPair(res);\n await this.persistTokens();\n return this.tokens;\n }\n\n async signUp(params: SignUpParams): Promise<TokenPair> {\n const res = (await this.request('POST', '/v1/auth/signup', params)) as ApiAuthResponse;\n this.tokens = this.toTokenPair(res);\n await this.persistTokens();\n return this.tokens;\n }\n\n async signOut(): Promise<void> {\n if (this.tokens) {\n try {\n await this.request('POST', '/v1/auth/signout', undefined);\n } catch {\n // Ignore sign-out errors\n }\n }\n this.tokens = null;\n if (this.storage) {\n await this.storage.removeItem(STORAGE_KEY);\n }\n }\n\n async getUser(): Promise<AuthonUser | null> {\n if (!this.tokens) return null;\n try {\n return (await this.request('GET', '/v1/auth/me')) as AuthonUser;\n } catch {\n return null;\n }\n }\n\n async refreshToken(refreshToken?: string): Promise<TokenPair | null> {\n const token = refreshToken || this.tokens?.refreshToken;\n if (!token) return null;\n\n try {\n const res = await fetch(`${this.apiUrl}/v1/auth/token/refresh`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.publishableKey,\n },\n body: JSON.stringify({ refreshToken: token }),\n });\n\n if (!res.ok) {\n this.tokens = null;\n if (this.storage) await this.storage.removeItem(STORAGE_KEY);\n return null;\n }\n\n const data = (await res.json()) as ApiAuthResponse;\n this.tokens = this.toTokenPair(data);\n await this.persistTokens();\n return this.tokens;\n } catch {\n return null;\n }\n }\n\n getAccessToken(): string | null {\n return this.tokens?.accessToken || null;\n }\n\n isAuthenticated(): boolean {\n return this.tokens !== null && this.tokens.expiresAt > Date.now();\n }\n\n private async persistTokens(): Promise<void> {\n if (this.storage && this.tokens) {\n await this.storage.setItem(STORAGE_KEY, JSON.stringify(this.tokens));\n }\n }\n\n private toTokenPair(res: ApiAuthResponse): TokenPair {\n return {\n accessToken: res.accessToken,\n refreshToken: res.refreshToken,\n expiresAt: Date.now() + res.expiresIn * 1000,\n };\n }\n\n private async request(method: string, path: string, body?: unknown): Promise<unknown> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-api-key': this.publishableKey,\n };\n\n if (this.tokens?.accessToken) {\n headers['Authorization'] = `Bearer ${this.tokens.accessToken}`;\n }\n\n const res = await fetch(`${this.apiUrl}${path}`, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!res.ok) {\n const error = await res.json().catch(() => ({ message: res.statusText }));\n throw new Error(error.message || `Request failed with status ${res.status}`);\n }\n\n const text = await res.text();\n return text ? JSON.parse(text) : undefined;\n }\n}\n","import { useContext } from 'react';\nimport { AuthonContext, type AuthonContextValue } from './AuthonProvider';\n\nexport function useAuthon(): AuthonContextValue {\n const context = useContext(AuthonContext);\n if (!context) {\n throw new Error('useAuthon must be used within an <AuthonProvider>');\n }\n return context;\n}\n","import { useAuthon } from './useAuthon';\nimport type { AuthonUser } from './types';\n\nexport function useUser(): {\n isLoaded: boolean;\n isSignedIn: boolean;\n user: AuthonUser | null;\n} {\n const { isLoaded, isSignedIn, user } = useAuthon();\n return { isLoaded, isSignedIn, user };\n}\n"],"mappings":"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","names":[]}
|