@atlasauth/expo 0.1.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 +143 -0
- package/dist/AtlasProvider.d.ts +35 -0
- package/dist/AtlasProvider.js +20 -0
- package/dist/AtlasProvider.js.map +1 -0
- package/dist/cache-fetch.d.ts +27 -0
- package/dist/cache-fetch.js +53 -0
- package/dist/cache-fetch.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/dist/native-session.d.ts +49 -0
- package/dist/native-session.js +59 -0
- package/dist/native-session.js.map +1 -0
- package/dist/token-cache.d.ts +89 -0
- package/dist/token-cache.js +84 -0
- package/dist/token-cache.js.map +1 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# @atlasauth/expo
|
|
2
|
+
|
|
3
|
+
The official Atlas SDK for **Expo** — the Expo-native peer of
|
|
4
|
+
[`@atlasauth/react`](../react) and the Expo sibling of
|
|
5
|
+
[`@atlasauth/react-native`](../react-native). It wraps the React provider and
|
|
6
|
+
re-exports the same headless hooks and control components (`useAuth`, `useUser`,
|
|
7
|
+
`useSession`, `SignedIn`, `SignedOut`, `<Protect>`), so auth reads identically to
|
|
8
|
+
the web — swapping only the one thing Expo must change: **how the session is
|
|
9
|
+
carried.**
|
|
10
|
+
|
|
11
|
+
The web SDK keeps the session in an HttpOnly cookie. Expo / React Native has no
|
|
12
|
+
cookie jar, so `@atlasauth/expo` carries the session token in a **`tokenCache`**
|
|
13
|
+
backed by [`expo-secure-store`](https://docs.expo.dev/versions/latest/sdk/securestore/)
|
|
14
|
+
(hardware-backed Keychain / Keystore) and sends it as a bearer header.
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
npx expo install @atlasauth/expo expo-secure-store
|
|
20
|
+
# plus, as you use them:
|
|
21
|
+
# expo-web-browser expo-auth-session (OAuth)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`react` and `react-native` come from your Expo app. `expo-secure-store`,
|
|
25
|
+
`expo-web-browser` and `expo-auth-session` are all **optional peers** — install
|
|
26
|
+
only what you use.
|
|
27
|
+
|
|
28
|
+
## Token cache
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
// lib/tokenCache.ts
|
|
32
|
+
import * as SecureStore from 'expo-secure-store';
|
|
33
|
+
import { createSecureStoreTokenCache } from '@atlasauth/expo';
|
|
34
|
+
|
|
35
|
+
export const tokenCache = createSecureStoreTokenCache(SecureStore);
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The package ships a non-persistent in-memory cache so it runs out of the box in
|
|
39
|
+
Expo Go and tests, but **production apps must pass a persistent cache** — the
|
|
40
|
+
secure-store one above.
|
|
41
|
+
|
|
42
|
+
## Provider (Expo Router)
|
|
43
|
+
|
|
44
|
+
Mount it once at the app root:
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
// app/_layout.tsx
|
|
48
|
+
import { Slot } from 'expo-router';
|
|
49
|
+
import { AtlasProvider } from '@atlasauth/expo';
|
|
50
|
+
import { tokenCache } from '../lib/tokenCache';
|
|
51
|
+
|
|
52
|
+
export default function RootLayout() {
|
|
53
|
+
return (
|
|
54
|
+
<AtlasProvider
|
|
55
|
+
publishableKey="pk_live_…"
|
|
56
|
+
frontendApi="https://fapi.your-instance.atlasauth.net"
|
|
57
|
+
tokenCache={tokenCache}
|
|
58
|
+
>
|
|
59
|
+
<Slot />
|
|
60
|
+
</AtlasProvider>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`frontendApi` is required — the publishable key encodes the instance id but not a
|
|
66
|
+
host. Use `https://atlasauth.net` before you verify a custom domain, your custom
|
|
67
|
+
domain after.
|
|
68
|
+
|
|
69
|
+
## Reading auth
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
import { Text } from 'react-native';
|
|
73
|
+
import { useAuth, useUser, SignedIn, SignedOut } from '@atlasauth/expo';
|
|
74
|
+
|
|
75
|
+
function Screen() {
|
|
76
|
+
const { isLoaded, isSignedIn, signOut } = useAuth();
|
|
77
|
+
const { user } = useUser();
|
|
78
|
+
if (!isLoaded) return <Text>Loading…</Text>;
|
|
79
|
+
return (
|
|
80
|
+
<>
|
|
81
|
+
<SignedIn>
|
|
82
|
+
<Text>Hello {user?.first_name}</Text>
|
|
83
|
+
</SignedIn>
|
|
84
|
+
<SignedOut>
|
|
85
|
+
<Text>Please sign in</Text>
|
|
86
|
+
</SignedOut>
|
|
87
|
+
</>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
`getToken()` from `useAuth()` returns the stored session JWT for your own API
|
|
93
|
+
calls; `getProviderToken(provider)` returns the user's own live token at a
|
|
94
|
+
connected social provider.
|
|
95
|
+
|
|
96
|
+
> **Headless only on native.** The hooks and the conditional-render controls
|
|
97
|
+
> (`SignedIn` / `SignedOut` / `Protect` / `AtlasLoading` / `AtlasLoaded`) render
|
|
98
|
+
> no host element, so they run under React Native. The prebuilt web UI
|
|
99
|
+
> components (`<SignIn>`, `<UserButton>`, …) render DOM and are **web-only** —
|
|
100
|
+
> build those screens with React Native primitives and these hooks.
|
|
101
|
+
|
|
102
|
+
## OAuth with expo-web-browser
|
|
103
|
+
|
|
104
|
+
The provider exposes the same flow helpers as the web SDK; open the authorization
|
|
105
|
+
URL with `expo-web-browser` and let the provider complete the redirect. See
|
|
106
|
+
[`@atlasauth/react-native`](../react-native#oauth-with-expo-auth-session) for the
|
|
107
|
+
full pattern — it is identical here.
|
|
108
|
+
|
|
109
|
+
## Native session (first-party OAuth → session)
|
|
110
|
+
|
|
111
|
+
A first-party app that already holds an Atlas OAuth access token can trade it for
|
|
112
|
+
a cookie-free session with `createNativeSessionManager` — it exchanges once, then
|
|
113
|
+
auto-refreshes the short-lived JWT and persists each rotated refresh token into
|
|
114
|
+
the secure store:
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
import {
|
|
118
|
+
createNativeSessionManager,
|
|
119
|
+
exchangeForSession,
|
|
120
|
+
tokenStorageFor,
|
|
121
|
+
} from '@atlasauth/expo';
|
|
122
|
+
import { tokenCache } from '../lib/tokenCache';
|
|
123
|
+
|
|
124
|
+
const mgr = await createNativeSessionManager({
|
|
125
|
+
frontendApi: 'https://fapi.your-instance.atlasauth.net',
|
|
126
|
+
publishableKey: 'pk_…',
|
|
127
|
+
// a slot DEDICATED to the native session, separate from the provider's.
|
|
128
|
+
storage: tokenStorageFor(tokenCache, 'atlas.native-session'),
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const session = await exchangeForSession({ baseUrl, clientId, accessToken });
|
|
132
|
+
if (session) mgr.setSession(session);
|
|
133
|
+
|
|
134
|
+
const headers = await mgr.authHeaders(); // { Authorization, 'x-publishable-key' }
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Companion packages
|
|
138
|
+
|
|
139
|
+
| Package | What it adds |
|
|
140
|
+
| --- | --- |
|
|
141
|
+
| [`@atlasauth/expo-passkeys`](../expo-passkeys) | Passkey register / sign-in via `react-native-passkey` |
|
|
142
|
+
| [`@atlasauth/expo-biometrics`](../expo-biometrics) | Gate a stored session behind Face ID / Touch ID |
|
|
143
|
+
| [`@atlasauth/expo-google-signin`](../expo-google-signin) | Native Google sign-in → Atlas id_token sign-in |
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type ReactElement } from 'react';
|
|
2
|
+
import { type AtlasProviderProps as ReactAtlasProviderProps } from '@atlasauth/react';
|
|
3
|
+
import { type TokenCache } from './token-cache';
|
|
4
|
+
/**
|
|
5
|
+
* `<AtlasProvider>` — the Expo peer of the web provider.
|
|
6
|
+
*
|
|
7
|
+
* It does NOT re-implement the auth state machine: it wraps `@atlasauth/react`'s
|
|
8
|
+
* provider (so every hook and control component in this package is the exact web
|
|
9
|
+
* one) and swaps one thing — the transport. The web provider carries the session
|
|
10
|
+
* in an HttpOnly cookie; Expo has no cookie jar, so this provider injects a
|
|
11
|
+
* {@link createCacheFetch} that bearer-authenticates from, and persists rotated
|
|
12
|
+
* tokens into, an `expo-secure-store`-backed {@link TokenCache}.
|
|
13
|
+
*
|
|
14
|
+
* Expo Router friendly: mount it once at the app root (e.g. in `app/_layout.tsx`)
|
|
15
|
+
* and read auth anywhere with `useAuth()` / `useUser()` / `<SignedIn>` — the
|
|
16
|
+
* token cache, not a cookie, is what carries the session across a cold start.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Props mirror `@atlasauth/react`'s provider (publishableKey, frontendApi,
|
|
20
|
+
* appearance, localization, oauthMode, onSignedIn) and add the two Expo knobs.
|
|
21
|
+
* `fetchImpl` is replaced by the cache-backed fetch, so it is not forwardable.
|
|
22
|
+
*/
|
|
23
|
+
export interface AtlasProviderProps extends Omit<ReactAtlasProviderProps, 'fetchImpl'> {
|
|
24
|
+
/**
|
|
25
|
+
* Where the session token is kept. Defaults to a NON-persistent in-memory
|
|
26
|
+
* cache — pass `createSecureStoreTokenCache(SecureStore)` in production so the
|
|
27
|
+
* session survives an app restart.
|
|
28
|
+
*/
|
|
29
|
+
tokenCache?: TokenCache;
|
|
30
|
+
/** The cache key the session token is stored under. */
|
|
31
|
+
tokenKey?: string;
|
|
32
|
+
/** Injectable for tests; defaults to the platform `fetch`. */
|
|
33
|
+
fetchImpl?: typeof fetch;
|
|
34
|
+
}
|
|
35
|
+
export declare function AtlasProvider(props: AtlasProviderProps): ReactElement;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AtlasProvider = AtlasProvider;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const react_2 = require("@atlasauth/react");
|
|
6
|
+
const cache_fetch_1 = require("./cache-fetch");
|
|
7
|
+
const token_cache_1 = require("./token-cache");
|
|
8
|
+
function AtlasProvider(props) {
|
|
9
|
+
const { tokenCache, tokenKey = token_cache_1.DEFAULT_SESSION_KEY, fetchImpl, ...rest } = props;
|
|
10
|
+
// Built exactly once — the initializer runs on first render only, so the cache
|
|
11
|
+
// (and the default in-memory one, when no adapter is passed) survives
|
|
12
|
+
// re-renders rather than being re-created and losing the session every render.
|
|
13
|
+
const [cacheFetch] = (0, react_1.useState)(() => (0, cache_fetch_1.createCacheFetch)({
|
|
14
|
+
cache: tokenCache ?? (0, token_cache_1.createInMemoryTokenCache)(),
|
|
15
|
+
key: tokenKey,
|
|
16
|
+
fetchImpl: fetchImpl ?? fetch,
|
|
17
|
+
}));
|
|
18
|
+
return (0, react_1.createElement)(react_2.AtlasProvider, { ...rest, fetchImpl: cacheFetch });
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=AtlasProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AtlasProvider.js","sourceRoot":"","sources":["../src/AtlasProvider.tsx"],"names":[],"mappings":";;AA6CA,sCAeC;AA5DD,iCAAmE;AACnE,4CAG0B;AAC1B,+CAAiD;AACjD,+CAIuB;AAmCvB,SAAgB,aAAa,CAAC,KAAyB;IACrD,MAAM,EAAE,UAAU,EAAE,QAAQ,GAAG,iCAAmB,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;IAEjF,+EAA+E;IAC/E,sEAAsE;IACtE,+EAA+E;IAC/E,MAAM,CAAC,UAAU,CAAC,GAAG,IAAA,gBAAQ,EAAC,GAAG,EAAE,CACjC,IAAA,8BAAgB,EAAC;QACf,KAAK,EAAE,UAAU,IAAI,IAAA,sCAAwB,GAAE;QAC/C,GAAG,EAAE,QAAQ;QACb,SAAS,EAAE,SAAS,IAAI,KAAK;KAC9B,CAAC,CACH,CAAC;IAEF,OAAO,IAAA,qBAAa,EAAC,qBAAkB,EAAE,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC;AAC/E,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { TokenCache } from './token-cache';
|
|
2
|
+
/**
|
|
3
|
+
* The bridge that makes `@atlasauth/react`'s cookie-based provider work on Expo.
|
|
4
|
+
*
|
|
5
|
+
* The web provider authenticates with an HttpOnly cookie (`credentials:
|
|
6
|
+
* 'include'`) and reads the rotated `jwt` out of each `/v1/client*` response into
|
|
7
|
+
* an in-memory cache. React Native has no cookie jar, so neither half survives on
|
|
8
|
+
* its own:
|
|
9
|
+
*
|
|
10
|
+
* 1. REQUEST — attach the session token from the {@link TokenCache} as an
|
|
11
|
+
* `Authorization: Bearer` header, so an authenticated call is recognised
|
|
12
|
+
* without a cookie. The token is read FRESH on every call (never captured),
|
|
13
|
+
* so a refresh or sign-out between requests is always reflected.
|
|
14
|
+
* 2. RESPONSE — when a JSON body carries a fresh `jwt`, persist it back to the
|
|
15
|
+
* cache so the rotated session survives an app restart. The web provider
|
|
16
|
+
* also keeps that jwt in memory for the tab's lifetime; this adds the
|
|
17
|
+
* durable copy native needs. Reading the body is done on a `clone()` so the
|
|
18
|
+
* provider still gets to consume the original.
|
|
19
|
+
*
|
|
20
|
+
* The persist is fire-and-forget: a secure-store write failure must not break a
|
|
21
|
+
* live, already-parsed response.
|
|
22
|
+
*/
|
|
23
|
+
export declare function createCacheFetch(opts: {
|
|
24
|
+
cache: TokenCache;
|
|
25
|
+
key: string;
|
|
26
|
+
fetchImpl: typeof fetch;
|
|
27
|
+
}): typeof fetch;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createCacheFetch = createCacheFetch;
|
|
4
|
+
/**
|
|
5
|
+
* The bridge that makes `@atlasauth/react`'s cookie-based provider work on Expo.
|
|
6
|
+
*
|
|
7
|
+
* The web provider authenticates with an HttpOnly cookie (`credentials:
|
|
8
|
+
* 'include'`) and reads the rotated `jwt` out of each `/v1/client*` response into
|
|
9
|
+
* an in-memory cache. React Native has no cookie jar, so neither half survives on
|
|
10
|
+
* its own:
|
|
11
|
+
*
|
|
12
|
+
* 1. REQUEST — attach the session token from the {@link TokenCache} as an
|
|
13
|
+
* `Authorization: Bearer` header, so an authenticated call is recognised
|
|
14
|
+
* without a cookie. The token is read FRESH on every call (never captured),
|
|
15
|
+
* so a refresh or sign-out between requests is always reflected.
|
|
16
|
+
* 2. RESPONSE — when a JSON body carries a fresh `jwt`, persist it back to the
|
|
17
|
+
* cache so the rotated session survives an app restart. The web provider
|
|
18
|
+
* also keeps that jwt in memory for the tab's lifetime; this adds the
|
|
19
|
+
* durable copy native needs. Reading the body is done on a `clone()` so the
|
|
20
|
+
* provider still gets to consume the original.
|
|
21
|
+
*
|
|
22
|
+
* The persist is fire-and-forget: a secure-store write failure must not break a
|
|
23
|
+
* live, already-parsed response.
|
|
24
|
+
*/
|
|
25
|
+
function createCacheFetch(opts) {
|
|
26
|
+
const { cache, key, fetchImpl } = opts;
|
|
27
|
+
return async (input, init) => {
|
|
28
|
+
const token = (await cache.getToken(key)) ?? null;
|
|
29
|
+
const headers = new Headers(init?.headers);
|
|
30
|
+
if (token)
|
|
31
|
+
headers.set('authorization', `Bearer ${token}`);
|
|
32
|
+
const response = await fetchImpl(input, { ...init, headers });
|
|
33
|
+
// Capture a rotated session token for persistence, without consuming the
|
|
34
|
+
// body the caller still needs.
|
|
35
|
+
const contentType = response.headers.get('content-type') ?? '';
|
|
36
|
+
if (response.ok && contentType.includes('application/json')) {
|
|
37
|
+
void (async () => {
|
|
38
|
+
try {
|
|
39
|
+
const body = (await response.clone().json());
|
|
40
|
+
if (typeof body.jwt === 'string' && body.jwt) {
|
|
41
|
+
await cache.saveToken(key, body.jwt);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// Not JSON, an empty body, or a secure-store write failure — the live
|
|
46
|
+
// response is unaffected.
|
|
47
|
+
}
|
|
48
|
+
})();
|
|
49
|
+
}
|
|
50
|
+
return response;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=cache-fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-fetch.js","sourceRoot":"","sources":["../src/cache-fetch.ts"],"names":[],"mappings":";;AAuBA,4CAiCC;AAtDD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,SAAgB,gBAAgB,CAAC,IAIhC;IACC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;IAEvC,OAAO,KAAK,EAAE,KAAwB,EAAE,IAAkB,EAAqB,EAAE;QAC/E,MAAM,KAAK,GAAG,CAAC,MAAM,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC;QAClD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC3C,IAAI,KAAK;YAAE,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,KAAK,EAAE,CAAC,CAAC;QAE3D,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAE9D,yEAAyE;QACzE,+BAA+B;QAC/B,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;QAC/D,IAAI,QAAQ,CAAC,EAAE,IAAI,WAAW,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAC5D,KAAK,CAAC,KAAK,IAAI,EAAE;gBACf,IAAI,CAAC;oBACH,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAsB,CAAC;oBAClE,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;wBAC7C,MAAM,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;oBACvC,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,sEAAsE;oBACtE,0BAA0B;gBAC5B,CAAC;YACH,CAAC,CAAC,EAAE,CAAC;QACP,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export * from './token-cache';
|
|
2
|
+
export * from './cache-fetch';
|
|
3
|
+
export * from './AtlasProvider';
|
|
4
|
+
export * from './native-session';
|
|
5
|
+
export { useAuth, useUser, useSession, useSessionList, useOrganization, SignedIn, SignedOut, Protect, AtlasLoading, AtlasLoaded, } from '@atlasauth/react';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.AtlasLoaded = exports.AtlasLoading = exports.Protect = exports.SignedOut = exports.SignedIn = exports.useOrganization = exports.useSessionList = exports.useSession = exports.useUser = exports.useAuth = void 0;
|
|
18
|
+
// Expo provider (wraps @atlasauth/react, swaps the cookie transport for an
|
|
19
|
+
// expo-secure-store-backed token cache) + the token cache itself.
|
|
20
|
+
__exportStar(require("./token-cache"), exports);
|
|
21
|
+
__exportStar(require("./cache-fetch"), exports);
|
|
22
|
+
__exportStar(require("./AtlasProvider"), exports);
|
|
23
|
+
// Native session (first-party OAuth → cookie-free session with auto-refresh).
|
|
24
|
+
__exportStar(require("./native-session"), exports);
|
|
25
|
+
/*
|
|
26
|
+
* Re-export the NATIVE-SAFE React surface from @atlasauth/react, so an Expo app
|
|
27
|
+
* reads auth with the very same hooks and control components a web app does.
|
|
28
|
+
*
|
|
29
|
+
* Deliberately a NAMED re-export, not `export *`: the hooks and the
|
|
30
|
+
* conditional-render controls (`SignedIn` / `SignedOut` / `Protect`) decide
|
|
31
|
+
* whether their children appear and render no host element, so they run fine
|
|
32
|
+
* under React Native. The prebuilt UI components (`<SignIn>`, `<UserButton>`, …)
|
|
33
|
+
* render DOM (`<div>`, `<input>`, `<style>`) and are web-only — build those
|
|
34
|
+
* screens with React Native primitives and these headless hooks instead.
|
|
35
|
+
*/
|
|
36
|
+
var react_1 = require("@atlasauth/react");
|
|
37
|
+
Object.defineProperty(exports, "useAuth", { enumerable: true, get: function () { return react_1.useAuth; } });
|
|
38
|
+
Object.defineProperty(exports, "useUser", { enumerable: true, get: function () { return react_1.useUser; } });
|
|
39
|
+
Object.defineProperty(exports, "useSession", { enumerable: true, get: function () { return react_1.useSession; } });
|
|
40
|
+
Object.defineProperty(exports, "useSessionList", { enumerable: true, get: function () { return react_1.useSessionList; } });
|
|
41
|
+
Object.defineProperty(exports, "useOrganization", { enumerable: true, get: function () { return react_1.useOrganization; } });
|
|
42
|
+
Object.defineProperty(exports, "SignedIn", { enumerable: true, get: function () { return react_1.SignedIn; } });
|
|
43
|
+
Object.defineProperty(exports, "SignedOut", { enumerable: true, get: function () { return react_1.SignedOut; } });
|
|
44
|
+
Object.defineProperty(exports, "Protect", { enumerable: true, get: function () { return react_1.Protect; } });
|
|
45
|
+
Object.defineProperty(exports, "AtlasLoading", { enumerable: true, get: function () { return react_1.AtlasLoading; } });
|
|
46
|
+
Object.defineProperty(exports, "AtlasLoaded", { enumerable: true, get: function () { return react_1.AtlasLoaded; } });
|
|
47
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,2EAA2E;AAC3E,kEAAkE;AAClE,gDAA8B;AAC9B,gDAA8B;AAC9B,kDAAgC;AAEhC,8EAA8E;AAC9E,mDAAiC;AAEjC;;;;;;;;;;GAUG;AACH,0CAW0B;AAVxB,gGAAA,OAAO,OAAA;AACP,gGAAA,OAAO,OAAA;AACP,mGAAA,UAAU,OAAA;AACV,uGAAA,cAAc,OAAA;AACd,wGAAA,eAAe,OAAA;AACf,iGAAA,QAAQ,OAAA;AACR,kGAAA,SAAS,OAAA;AACT,gGAAA,OAAO,OAAA;AACP,qGAAA,YAAY,OAAA;AACZ,oGAAA,WAAW,OAAA"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native session for Expo / React Native.
|
|
3
|
+
*
|
|
4
|
+
* A thin wiring of the framework-agnostic {@link NativeSessionManager} from
|
|
5
|
+
* `@atlasauth/js` to this package's {@link TokenStorage} secure-store adapter.
|
|
6
|
+
* The core manager owns the exchange / refresh / rotation logic; this file's only
|
|
7
|
+
* job is to PERSIST each rotated session into `expo-secure-store` (or whatever
|
|
8
|
+
* adapter the app wired) and to rehydrate the manager from it on boot.
|
|
9
|
+
*
|
|
10
|
+
* The whole session is stored as one JSON string under the adapter's single
|
|
11
|
+
* slot — the refresh token (which rotates and must survive a restart) alongside
|
|
12
|
+
* the session id the refresh call needs and the current JWT. Use a storage slot
|
|
13
|
+
* DEDICATED to the native session (its own key), separate from the one you pass
|
|
14
|
+
* to `AtlasProvider`, since each slot holds one value. `tokenStorageFor(cache,
|
|
15
|
+
* 'atlas.native-session')` builds such a slot from the same token cache.
|
|
16
|
+
*/
|
|
17
|
+
import { NativeSessionManager } from '@atlasauth/js';
|
|
18
|
+
import { type TokenStorage } from './token-cache';
|
|
19
|
+
export interface NativeSessionConfig {
|
|
20
|
+
/** The instance's FAPI origin, e.g. `https://fapi.acme.atlasauth.net`. */
|
|
21
|
+
frontendApi: string;
|
|
22
|
+
/** The publishable key — sent on the refresh call and in `authHeaders()`. */
|
|
23
|
+
publishableKey: string;
|
|
24
|
+
/** The first-party OAuth client id (for a later in-manager exchange). */
|
|
25
|
+
clientId?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Where the rotated session is persisted. Defaults to a NON-persistent
|
|
28
|
+
* in-memory store — ship an `expo-secure-store` adapter (see {@link
|
|
29
|
+
* TokenStorage}) in production, dedicated to the native session.
|
|
30
|
+
*/
|
|
31
|
+
storage?: TokenStorage;
|
|
32
|
+
/** Injectable for tests; defaults to the platform `fetch`. */
|
|
33
|
+
fetchImpl?: typeof fetch;
|
|
34
|
+
/** Injectable clock, epoch ms. Defaults to `Date.now`. */
|
|
35
|
+
now?: () => number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Build a {@link NativeSessionManager} wired to an Expo secure store.
|
|
39
|
+
*
|
|
40
|
+
* Async because the secure store is async: it reads whatever session the adapter
|
|
41
|
+
* holds and seeds the manager with it, so a returning user is signed in before
|
|
42
|
+
* the first request. Thereafter every rotation is written straight back to the
|
|
43
|
+
* adapter via the manager's `persist` hook.
|
|
44
|
+
*/
|
|
45
|
+
export declare function createNativeSessionManager(config: NativeSessionConfig): Promise<NativeSessionManager>;
|
|
46
|
+
/** Clear the persisted native session (sign-out). */
|
|
47
|
+
export declare function clearNativeSession(storage: TokenStorage): Promise<void>;
|
|
48
|
+
export { NativeSessionManager, type NativeSession } from '@atlasauth/js';
|
|
49
|
+
export { exchangeForSession, refreshNativeSession } from '@atlasauth/js';
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Native session for Expo / React Native.
|
|
4
|
+
*
|
|
5
|
+
* A thin wiring of the framework-agnostic {@link NativeSessionManager} from
|
|
6
|
+
* `@atlasauth/js` to this package's {@link TokenStorage} secure-store adapter.
|
|
7
|
+
* The core manager owns the exchange / refresh / rotation logic; this file's only
|
|
8
|
+
* job is to PERSIST each rotated session into `expo-secure-store` (or whatever
|
|
9
|
+
* adapter the app wired) and to rehydrate the manager from it on boot.
|
|
10
|
+
*
|
|
11
|
+
* The whole session is stored as one JSON string under the adapter's single
|
|
12
|
+
* slot — the refresh token (which rotates and must survive a restart) alongside
|
|
13
|
+
* the session id the refresh call needs and the current JWT. Use a storage slot
|
|
14
|
+
* DEDICATED to the native session (its own key), separate from the one you pass
|
|
15
|
+
* to `AtlasProvider`, since each slot holds one value. `tokenStorageFor(cache,
|
|
16
|
+
* 'atlas.native-session')` builds such a slot from the same token cache.
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.refreshNativeSession = exports.exchangeForSession = exports.NativeSessionManager = void 0;
|
|
20
|
+
exports.createNativeSessionManager = createNativeSessionManager;
|
|
21
|
+
exports.clearNativeSession = clearNativeSession;
|
|
22
|
+
const js_1 = require("@atlasauth/js");
|
|
23
|
+
const token_cache_1 = require("./token-cache");
|
|
24
|
+
/**
|
|
25
|
+
* Build a {@link NativeSessionManager} wired to an Expo secure store.
|
|
26
|
+
*
|
|
27
|
+
* Async because the secure store is async: it reads whatever session the adapter
|
|
28
|
+
* holds and seeds the manager with it, so a returning user is signed in before
|
|
29
|
+
* the first request. Thereafter every rotation is written straight back to the
|
|
30
|
+
* adapter via the manager's `persist` hook.
|
|
31
|
+
*/
|
|
32
|
+
async function createNativeSessionManager(config) {
|
|
33
|
+
const storage = config.storage ?? (0, token_cache_1.createInMemoryStorage)();
|
|
34
|
+
const initial = (0, js_1.parseNativeSession)(await storage.getToken()) ?? undefined;
|
|
35
|
+
return new js_1.NativeSessionManager({
|
|
36
|
+
baseUrl: config.frontendApi,
|
|
37
|
+
publishableKey: config.publishableKey,
|
|
38
|
+
clientId: config.clientId,
|
|
39
|
+
initial,
|
|
40
|
+
fetchImpl: config.fetchImpl,
|
|
41
|
+
now: config.now,
|
|
42
|
+
// The manager calls this on every set/rotate; persist the fresh session so
|
|
43
|
+
// the rotated refresh token survives an app restart. Fire-and-forget — the
|
|
44
|
+
// adapter may be async, and a write failure must not break the live session.
|
|
45
|
+
persist: (session) => {
|
|
46
|
+
void Promise.resolve(storage.setToken((0, js_1.serializeNativeSession)(session))).catch(() => undefined);
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/** Clear the persisted native session (sign-out). */
|
|
51
|
+
async function clearNativeSession(storage) {
|
|
52
|
+
await storage.clearToken();
|
|
53
|
+
}
|
|
54
|
+
var js_2 = require("@atlasauth/js");
|
|
55
|
+
Object.defineProperty(exports, "NativeSessionManager", { enumerable: true, get: function () { return js_2.NativeSessionManager; } });
|
|
56
|
+
var js_3 = require("@atlasauth/js");
|
|
57
|
+
Object.defineProperty(exports, "exchangeForSession", { enumerable: true, get: function () { return js_3.exchangeForSession; } });
|
|
58
|
+
Object.defineProperty(exports, "refreshNativeSession", { enumerable: true, get: function () { return js_3.refreshNativeSession; } });
|
|
59
|
+
//# sourceMappingURL=native-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-session.js","sourceRoot":"","sources":["../src/native-session.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAqCH,gEAsBC;AAGD,gDAEC;AA9DD,sCAKuB;AACvB,+CAAyE;AAqBzE;;;;;;;GAOG;AACI,KAAK,UAAU,0BAA0B,CAC9C,MAA2B;IAE3B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,IAAA,mCAAqB,GAAE,CAAC;IAC1D,MAAM,OAAO,GAAG,IAAA,uBAAkB,EAAC,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC,IAAI,SAAS,CAAC;IAE1E,OAAO,IAAI,yBAAoB,CAAC;QAC9B,OAAO,EAAE,MAAM,CAAC,WAAW;QAC3B,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,OAAO;QACP,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,2EAA2E;QAC3E,2EAA2E;QAC3E,6EAA6E;QAC7E,OAAO,EAAE,CAAC,OAAsB,EAAE,EAAE;YAClC,KAAK,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAA,2BAAsB,EAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAC3E,GAAG,EAAE,CAAC,SAAS,CAChB,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,qDAAqD;AAC9C,KAAK,UAAU,kBAAkB,CAAC,OAAqB;IAC5D,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;AAC7B,CAAC;AAED,oCAAyE;AAAhE,0GAAA,oBAAoB,OAAA;AAC7B,oCAAyE;AAAhE,wGAAA,kBAAkB,OAAA;AAAE,0GAAA,oBAAoB,OAAA"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Expo session token cache.
|
|
3
|
+
*
|
|
4
|
+
* The web SDK keeps its short-lived JWT in memory and lets the browser carry the
|
|
5
|
+
* refresh token in an HttpOnly cookie. Expo / React Native has neither a cookie
|
|
6
|
+
* jar nor `localStorage`, so the session token has to live somewhere the app
|
|
7
|
+
* chooses — and where it lives is a security decision this SDK must not make for
|
|
8
|
+
* the app. A token in AsyncStorage is readable by any code in the process; a
|
|
9
|
+
* token in `expo-secure-store` is hardware-backed (Keychain / Keystore).
|
|
10
|
+
*
|
|
11
|
+
* So the SDK depends only on the small {@link TokenCache} interface below and
|
|
12
|
+
* ships an in-memory default plus an `expo-secure-store` adapter. The
|
|
13
|
+
* `expo-secure-store` module is an OPTIONAL peer, so its surface is declared
|
|
14
|
+
* structurally ({@link SecureStore}) and the app passes the real module in — the
|
|
15
|
+
* package compiles, typechecks and tests without `expo-secure-store` installed.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* A key→token cache, the shape `<AtlasProvider tokenCache>` and the native
|
|
19
|
+
* session wiring both consume. Mirrors Clerk's Expo `tokenCache` contract
|
|
20
|
+
* (`getToken` / `saveToken` / `clearToken`). Every method may be sync or async,
|
|
21
|
+
* so the same adapter fits an async `expo-secure-store` and a synchronous MMKV
|
|
22
|
+
* store alike.
|
|
23
|
+
*/
|
|
24
|
+
export interface TokenCache {
|
|
25
|
+
/** The token stored under `key`, or null/undefined when absent. */
|
|
26
|
+
getToken(key: string): string | null | undefined | Promise<string | null | undefined>;
|
|
27
|
+
/** Persist `value` under `key`. Called on every successful sign-in / refresh. */
|
|
28
|
+
saveToken(key: string, value: string): void | Promise<void>;
|
|
29
|
+
/** Drop whatever is stored under `key` (sign-out, or a rejected session). */
|
|
30
|
+
clearToken(key: string): void | Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The slice of `expo-secure-store` this package uses, declared structurally so
|
|
34
|
+
* the package needs no dependency on it. The real module (and a fake in tests)
|
|
35
|
+
* is structurally compatible.
|
|
36
|
+
*
|
|
37
|
+
* Every method is optional-arg-compatible with `expo-secure-store`'s
|
|
38
|
+
* `SecureStoreOptions` (keychain accessibility, service, etc.), which the app
|
|
39
|
+
* may pass through via {@link SecureStoreTokenCacheOptions.secureStoreOptions}.
|
|
40
|
+
*/
|
|
41
|
+
export interface SecureStore {
|
|
42
|
+
getItemAsync(key: string, options?: unknown): Promise<string | null>;
|
|
43
|
+
setItemAsync(key: string, value: string, options?: unknown): Promise<void>;
|
|
44
|
+
deleteItemAsync(key: string, options?: unknown): Promise<void>;
|
|
45
|
+
}
|
|
46
|
+
export interface SecureStoreTokenCacheOptions {
|
|
47
|
+
/**
|
|
48
|
+
* Pass-through `SecureStoreOptions` (e.g. `{ keychainAccessible:
|
|
49
|
+
* SecureStore.WHEN_UNLOCKED_THIS_DEVICE_ONLY }`). Forwarded verbatim to every
|
|
50
|
+
* `expo-secure-store` call.
|
|
51
|
+
*/
|
|
52
|
+
secureStoreOptions?: unknown;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Build a {@link TokenCache} backed by `expo-secure-store` (hardware-backed
|
|
56
|
+
* Keychain / Keystore). The app imports the module and passes it in — the SDK
|
|
57
|
+
* never imports `expo-secure-store` itself, so it stays an optional peer:
|
|
58
|
+
*
|
|
59
|
+
* ```ts
|
|
60
|
+
* import * as SecureStore from 'expo-secure-store';
|
|
61
|
+
* import { createSecureStoreTokenCache } from '@atlasauth/expo';
|
|
62
|
+
*
|
|
63
|
+
* export const tokenCache = createSecureStoreTokenCache(SecureStore);
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export declare function createSecureStoreTokenCache(store: SecureStore, options?: SecureStoreTokenCacheOptions): TokenCache;
|
|
67
|
+
/**
|
|
68
|
+
* A process-memory token cache. The zero-config default so the SDK runs out of
|
|
69
|
+
* the box in tests, prototypes and Expo Go — but it does NOT survive an app
|
|
70
|
+
* restart, so ship {@link createSecureStoreTokenCache} in production.
|
|
71
|
+
*/
|
|
72
|
+
export declare function createInMemoryTokenCache(): TokenCache;
|
|
73
|
+
/**
|
|
74
|
+
* Adapt a single-slot {@link TokenCache} (plus a fixed key) to the three-method
|
|
75
|
+
* {@link TokenStorage} the native-session manager wants. The native session is
|
|
76
|
+
* kept under its OWN key, separate from the `AtlasProvider` session, because the
|
|
77
|
+
* adapter holds one value per slot.
|
|
78
|
+
*/
|
|
79
|
+
export interface TokenStorage {
|
|
80
|
+
getToken(): string | null | Promise<string | null>;
|
|
81
|
+
setToken(token: string): void | Promise<void>;
|
|
82
|
+
clearToken(): void | Promise<void>;
|
|
83
|
+
}
|
|
84
|
+
/** View a {@link TokenCache} + one key as a single-slot {@link TokenStorage}. */
|
|
85
|
+
export declare function tokenStorageFor(cache: TokenCache, key: string): TokenStorage;
|
|
86
|
+
/** A process-memory {@link TokenStorage}. Non-persistent — see note above. */
|
|
87
|
+
export declare function createInMemoryStorage(): TokenStorage;
|
|
88
|
+
/** The default cache key the `<AtlasProvider>` session is stored under. */
|
|
89
|
+
export declare const DEFAULT_SESSION_KEY = "atlas.session";
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The Expo session token cache.
|
|
4
|
+
*
|
|
5
|
+
* The web SDK keeps its short-lived JWT in memory and lets the browser carry the
|
|
6
|
+
* refresh token in an HttpOnly cookie. Expo / React Native has neither a cookie
|
|
7
|
+
* jar nor `localStorage`, so the session token has to live somewhere the app
|
|
8
|
+
* chooses — and where it lives is a security decision this SDK must not make for
|
|
9
|
+
* the app. A token in AsyncStorage is readable by any code in the process; a
|
|
10
|
+
* token in `expo-secure-store` is hardware-backed (Keychain / Keystore).
|
|
11
|
+
*
|
|
12
|
+
* So the SDK depends only on the small {@link TokenCache} interface below and
|
|
13
|
+
* ships an in-memory default plus an `expo-secure-store` adapter. The
|
|
14
|
+
* `expo-secure-store` module is an OPTIONAL peer, so its surface is declared
|
|
15
|
+
* structurally ({@link SecureStore}) and the app passes the real module in — the
|
|
16
|
+
* package compiles, typechecks and tests without `expo-secure-store` installed.
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.DEFAULT_SESSION_KEY = void 0;
|
|
20
|
+
exports.createSecureStoreTokenCache = createSecureStoreTokenCache;
|
|
21
|
+
exports.createInMemoryTokenCache = createInMemoryTokenCache;
|
|
22
|
+
exports.tokenStorageFor = tokenStorageFor;
|
|
23
|
+
exports.createInMemoryStorage = createInMemoryStorage;
|
|
24
|
+
/**
|
|
25
|
+
* Build a {@link TokenCache} backed by `expo-secure-store` (hardware-backed
|
|
26
|
+
* Keychain / Keystore). The app imports the module and passes it in — the SDK
|
|
27
|
+
* never imports `expo-secure-store` itself, so it stays an optional peer:
|
|
28
|
+
*
|
|
29
|
+
* ```ts
|
|
30
|
+
* import * as SecureStore from 'expo-secure-store';
|
|
31
|
+
* import { createSecureStoreTokenCache } from '@atlasauth/expo';
|
|
32
|
+
*
|
|
33
|
+
* export const tokenCache = createSecureStoreTokenCache(SecureStore);
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
function createSecureStoreTokenCache(store, options = {}) {
|
|
37
|
+
const opts = options.secureStoreOptions;
|
|
38
|
+
return {
|
|
39
|
+
getToken: (key) => store.getItemAsync(key, opts),
|
|
40
|
+
saveToken: (key, value) => store.setItemAsync(key, value, opts),
|
|
41
|
+
clearToken: (key) => store.deleteItemAsync(key, opts),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* A process-memory token cache. The zero-config default so the SDK runs out of
|
|
46
|
+
* the box in tests, prototypes and Expo Go — but it does NOT survive an app
|
|
47
|
+
* restart, so ship {@link createSecureStoreTokenCache} in production.
|
|
48
|
+
*/
|
|
49
|
+
function createInMemoryTokenCache() {
|
|
50
|
+
const map = new Map();
|
|
51
|
+
return {
|
|
52
|
+
getToken: (key) => map.get(key) ?? null,
|
|
53
|
+
saveToken: (key, value) => {
|
|
54
|
+
map.set(key, value);
|
|
55
|
+
},
|
|
56
|
+
clearToken: (key) => {
|
|
57
|
+
map.delete(key);
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/** View a {@link TokenCache} + one key as a single-slot {@link TokenStorage}. */
|
|
62
|
+
function tokenStorageFor(cache, key) {
|
|
63
|
+
return {
|
|
64
|
+
getToken: async () => (await cache.getToken(key)) ?? null,
|
|
65
|
+
setToken: (token) => cache.saveToken(key, token),
|
|
66
|
+
clearToken: () => cache.clearToken(key),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/** A process-memory {@link TokenStorage}. Non-persistent — see note above. */
|
|
70
|
+
function createInMemoryStorage() {
|
|
71
|
+
let token = null;
|
|
72
|
+
return {
|
|
73
|
+
getToken: () => token,
|
|
74
|
+
setToken: (next) => {
|
|
75
|
+
token = next;
|
|
76
|
+
},
|
|
77
|
+
clearToken: () => {
|
|
78
|
+
token = null;
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/** The default cache key the `<AtlasProvider>` session is stored under. */
|
|
83
|
+
exports.DEFAULT_SESSION_KEY = 'atlas.session';
|
|
84
|
+
//# sourceMappingURL=token-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-cache.js","sourceRoot":"","sources":["../src/token-cache.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAsDH,kEAUC;AAOD,4DAWC;AAeD,0CAMC;AAGD,sDAWC;AA3ED;;;;;;;;;;;GAWG;AACH,SAAgB,2BAA2B,CACzC,KAAkB,EAClB,UAAwC,EAAE;IAE1C,MAAM,IAAI,GAAG,OAAO,CAAC,kBAAkB,CAAC;IACxC,OAAO;QACL,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC;QAChD,SAAS,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC;QAC/D,UAAU,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,EAAE,IAAI,CAAC;KACtD,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAgB,wBAAwB;IACtC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;IACtC,OAAO;QACL,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI;QACvC,SAAS,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;YACxB,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACtB,CAAC;QACD,UAAU,EAAE,CAAC,GAAG,EAAE,EAAE;YAClB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAClB,CAAC;KACF,CAAC;AACJ,CAAC;AAcD,iFAAiF;AACjF,SAAgB,eAAe,CAAC,KAAiB,EAAE,GAAW;IAC5D,OAAO;QACL,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI;QACzD,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC;QAChD,UAAU,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;KACxC,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,SAAgB,qBAAqB;IACnC,IAAI,KAAK,GAAkB,IAAI,CAAC;IAChC,OAAO;QACL,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK;QACrB,QAAQ,EAAE,CAAC,IAAY,EAAE,EAAE;YACzB,KAAK,GAAG,IAAI,CAAC;QACf,CAAC;QACD,UAAU,EAAE,GAAG,EAAE;YACf,KAAK,GAAG,IAAI,CAAC;QACf,CAAC;KACF,CAAC;AACJ,CAAC;AAED,2EAA2E;AAC9D,QAAA,mBAAmB,GAAG,eAAe,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@atlasauth/expo",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"main": "./dist/index.js",
|
|
5
|
+
"types": "./dist/index.d.ts",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"@atlasauth/js": "0.2.0",
|
|
8
|
+
"@atlasauth/react": "0.1.30"
|
|
9
|
+
},
|
|
10
|
+
"peerDependencies": {
|
|
11
|
+
"react": ">=18",
|
|
12
|
+
"react-native": ">=0.73",
|
|
13
|
+
"expo-secure-store": ">=12",
|
|
14
|
+
"expo-web-browser": ">=12",
|
|
15
|
+
"expo-auth-session": ">=5"
|
|
16
|
+
},
|
|
17
|
+
"peerDependenciesMeta": {
|
|
18
|
+
"react": {
|
|
19
|
+
"optional": true
|
|
20
|
+
},
|
|
21
|
+
"react-native": {
|
|
22
|
+
"optional": true
|
|
23
|
+
},
|
|
24
|
+
"expo-secure-store": {
|
|
25
|
+
"optional": true
|
|
26
|
+
},
|
|
27
|
+
"expo-web-browser": {
|
|
28
|
+
"optional": true
|
|
29
|
+
},
|
|
30
|
+
"expo-auth-session": {
|
|
31
|
+
"optional": true
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/react": "^18.3.12",
|
|
36
|
+
"react": "^18.3.1",
|
|
37
|
+
"typescript": "^5.6.3",
|
|
38
|
+
"vitest": "^2.1.4"
|
|
39
|
+
},
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"access": "public"
|
|
42
|
+
},
|
|
43
|
+
"files": [
|
|
44
|
+
"dist",
|
|
45
|
+
"README.md"
|
|
46
|
+
],
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "tsc -p tsconfig.build.json",
|
|
49
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
50
|
+
"test": "vitest run"
|
|
51
|
+
}
|
|
52
|
+
}
|