@atlasauth/capacitor 0.1.1 → 0.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/CHANGELOG.md CHANGED
@@ -1,5 +1,37 @@
1
1
  # @atlasauth/capacitor changelog
2
2
 
3
+ ## 0.3.0 — 2026-10-24
4
+ Requires `@atlasauth/js` with policy acceptance.
5
+ - **Policy acceptance** (terms of service, privacy, any policy the app defines). The system-browser sign-in runs on Atlas's
6
+ hosted pages, which collect and hold for the policies themselves. For the app's own WebView screens, the handle gains
7
+ `policies()` (a `PolicyAcceptanceController` for a sign-up form), `pendingPolicies(attempt)`, `policyGate()` (in-app
8
+ re-acceptance with the session's bearer token) and `fapi`; new `locale` option. `mountPolicyGate(host, gate)` draws the
9
+ signed-in banner, and the DOM pieces (`mountPolicyConsent`, `mountPolicyClickwrap`, `mountPolicyAcceptStep`) are re-exported.
10
+
11
+ ## 0.2.0
12
+
13
+ ### Changed
14
+ - **`signOut(options?: SignOutOptions)` now resolves `Promise<SignOutResult>`** (`{ revoked: boolean; activeSessionId?: string }`)
15
+ instead of `Promise<void>`, and revokes the session on the Frontend API (it used to only clear local state). Existing
16
+ `await atlas.signOut()` call sites keep working. The revoke is authenticated as the session being dropped, retried once,
17
+ then re-tried in the background (a 401 from an expired JWT rotates it once with the refresh token). `{ strict: true }`
18
+ rejects with `SignOutError` (`code: 'SIGN_OUT_REVOKE_FAILED'`, `sessionId`, `status`) after the local sign-out.
19
+ `activeSessionId` (a server-promoted session) is reported but not adopted: the bearer revoke never returns a credential
20
+ for it.
21
+ - **A signed-out session is never re-adopted.** Its id is remembered (a tombstone, via `SignOutGuard` from
22
+ `@atlasauth/js`) in the platform store before the revoke; the next app start refuses a stored session that is tombstoned
23
+ (and clears it), and a refresh still in flight at sign-out can no longer write the session back or resurrect it in
24
+ memory. A refused session's revoke is re-tried in the background and its tombstone dropped once the server confirms.
25
+ - `getToken()` / `authHeaders()` return no bearer for a session signed out while a refresh was in flight; `onChange()`
26
+ listeners are not called for a signed-out session.
27
+
28
+ ### Added
29
+ - `CreateAtlasCapacitorConfig.tombstoneStore?: TombstoneStore` (default: `@capacitor/preferences` when present, else the
30
+ WebView's `localStorage`) and `CreateAtlasCapacitorConfig.signOutRetryDelaysMs?: number[]`.
31
+ - `createPreferencesTombstoneStore(preferences)` and `tombstoneStoreFromTokenStore(store)` adapters.
32
+ - `NativeSessionConfig.refuse?: (session: NativeSession) => boolean` on `createNativeSessionManager()`.
33
+ - Re-exports `SignOutError`, `SignOutOptions`, `SignOutResult` and `TombstoneStore` from `@atlasauth/js`.
34
+
3
35
  ## 0.1.1
4
36
  - **`frontendApi` is validated at `createAtlasCapacitor()`.** A missing, empty or malformed value now throws an
5
37
  `AtlasConfigError` (from `@atlasauth/js`; `code: 'FRONTEND_API_REQUIRED'` or `'FRONTEND_API_INVALID'`)
package/README.md CHANGED
@@ -109,6 +109,23 @@ const secureStore: TokenStore = {
109
109
  const atlas = await createAtlasCapacitor({ /* … */ storage: secureStore });
110
110
  ```
111
111
 
112
+ ## Policy acceptance (terms of service, privacy)
113
+
114
+ The system-browser sign-in (`atlas.signIn()`) happens on Atlas's hosted pages, which already collect the acceptances at sign-up
115
+ and hold a sign-in until a newer version is accepted. For screens in your own WebView:
116
+
117
+ ```ts
118
+ // A custom sign-up form
119
+ const policies = await atlas.policies();
120
+ mountPolicyConsent(consentHost, policies, { t: policyText() });
121
+ // on submit: send policies.build() as policy_acceptances
122
+
123
+ // A signed-in user whose policies changed
124
+ mountPolicyGate(gateHost, atlas.policyGate(), { onAccepted: () => refresh() });
125
+ ```
126
+
127
+ Pass `locale` to `createAtlasCapacitor` to get translated policy versions.
128
+
112
129
  ## Driving the pieces yourself
113
130
 
114
131
  The flow is also exposed à la carte: `createPkcePair`, `buildAuthorizeUrl`,
package/dist/index.d.ts CHANGED
@@ -16,10 +16,11 @@
16
16
  * (the sign-in flow, the token store, the PKCE helpers) is exposed for apps that
17
17
  * want to drive the pieces themselves.
18
18
  */
19
- import { type NativeSession, type NativeSessionManager } from '@atlasauth/js';
19
+ import { NativeSessionManager, type NativeSession, type SignOutOptions, type SignOutResult, type TombstoneStore } from '@atlasauth/js';
20
20
  import { type CapacitorPlugins } from './plugins';
21
21
  import { type SignInOutcome } from './sign-in';
22
22
  import { type TokenStore } from './token-store';
23
+ import { type PolicyApi } from './policies';
23
24
  export interface CreateAtlasCapacitorConfig {
24
25
  /** The instance publishable key (`pk_…`). */
25
26
  publishableKey: string;
@@ -40,10 +41,28 @@ export interface CreateAtlasCapacitorConfig {
40
41
  storage?: TokenStore;
41
42
  /** Where the transient PKCE material is stashed on the WEB redirect path. */
42
43
  pkceStore?: TokenStore;
44
+ /**
45
+ * Where the ids of sessions this app signed out of are kept, so a restart
46
+ * never re-adopts one (even when the revoke never reached the server).
47
+ * Defaults to `@capacitor/preferences` when present, else the WebView's
48
+ * `localStorage`. Adapt a secure-storage {@link TokenStore} with
49
+ * `tombstoneStoreFromTokenStore()` (give it its own slot).
50
+ */
51
+ tombstoneStore?: TombstoneStore;
52
+ /**
53
+ * Delays (ms) between background re-tries of a revoke `signOut()` could not
54
+ * complete. @default `[15_000, 60_000, 300_000]`
55
+ */
56
+ signOutRetryDelaysMs?: number[];
43
57
  /** Inject the Capacitor plugins (tests). Defaults to a lazy, guarded load. */
44
58
  plugins?: CapacitorPlugins;
45
59
  /** Injectable for tests; defaults to the platform `fetch`. */
46
60
  fetchImpl?: typeof fetch;
61
+ /**
62
+ * The app's UI language (`"es"`), sent as `Accept-Language` on the policy calls
63
+ * so the server picks a translated policy version. @default none
64
+ */
65
+ locale?: string;
47
66
  /** Injectable clock, epoch ms. Defaults to `Date.now`. */
48
67
  now?: () => number;
49
68
  /** Navigate the page on the web redirect path. @default `window.location.assign` */
@@ -61,7 +80,7 @@ export interface SignInOptions {
61
80
  * the manager, {@link getToken} hands out a live (auto-refreshing) JWT, and
62
81
  * {@link onChange} fires on every session change.
63
82
  */
64
- export interface AtlasCapacitor {
83
+ export interface AtlasCapacitor extends PolicyApi {
65
84
  /**
66
85
  * Run the native-session sign-in: open the system browser, catch the deep-link
67
86
  * callback, complete PKCE, exchange for a session, and store it. On the web
@@ -75,8 +94,18 @@ export interface AtlasCapacitor {
75
94
  * (or null when there is nothing to complete).
76
95
  */
77
96
  handleRedirectCallback(url?: string): Promise<NativeSession | null>;
78
- /** Forget the session and clear the store (sign-out). */
79
- signOut(): Promise<void>;
97
+ /**
98
+ * Sign out: remember the session id (so nothing re-adopts it — not a refresh
99
+ * in flight, not the next app start), revoke it on the Frontend API (retried
100
+ * once, then in the background, authenticated as the dropped session), and
101
+ * forget it locally. Resolves `{ revoked }` — `false` when the server could
102
+ * not be reached (the app is signed out regardless). With `{ strict: true }`
103
+ * it rejects with a `SignOutError` instead, after the local sign-out.
104
+ *
105
+ * A bearer client never gets a server-promoted session's credential back from
106
+ * the revoke, so `activeSessionId` is reported (when present) but not adopted.
107
+ */
108
+ signOut(options?: SignOutOptions): Promise<SignOutResult>;
80
109
  /** The current session JWT, auto-refreshed near expiry; null when signed out. */
81
110
  getToken(): Promise<string | null>;
82
111
  /** The headers an authenticated `/v1/client/me/*` call needs (bearer + pk). */
@@ -109,8 +138,10 @@ export interface AtlasCapacitor {
109
138
  * ```
110
139
  */
111
140
  export declare function createAtlasCapacitor(config: CreateAtlasCapacitorConfig): Promise<AtlasCapacitor>;
141
+ export { SignOutError, type SignOutOptions, type SignOutResult, type TombstoneStore, } from '@atlasauth/js';
112
142
  export * from './plugins';
113
143
  export * from './pkce';
114
144
  export * from './token-store';
115
145
  export * from './sign-in';
116
146
  export { createNativeSessionManager, clearNativeSession, NativeSessionManager, exchangeForSession, refreshNativeSession, type NativeSession, type NativeSessionConfig, } from './native-session';
147
+ export * from './policies';
package/dist/index.js CHANGED
@@ -32,13 +32,14 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
32
32
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
33
33
  };
34
34
  Object.defineProperty(exports, "__esModule", { value: true });
35
- exports.refreshNativeSession = exports.exchangeForSession = exports.NativeSessionManager = exports.clearNativeSession = exports.createNativeSessionManager = void 0;
35
+ exports.refreshNativeSession = exports.exchangeForSession = exports.NativeSessionManager = exports.clearNativeSession = exports.createNativeSessionManager = exports.SignOutError = void 0;
36
36
  exports.createAtlasCapacitor = createAtlasCapacitor;
37
37
  const js_1 = require("@atlasauth/js");
38
38
  const plugins_1 = require("./plugins");
39
39
  const sign_in_1 = require("./sign-in");
40
40
  const token_store_1 = require("./token-store");
41
41
  const native_session_1 = require("./native-session");
42
+ const policies_1 = require("./policies");
42
43
  /**
43
44
  * Create the Atlas handle for a Capacitor app.
44
45
  *
@@ -77,6 +78,47 @@ async function createAtlasCapacitor(config) {
77
78
  (plugins.Preferences
78
79
  ? (0, token_store_1.createPreferencesTokenStore)(plugins.Preferences, sign_in_1.PKCE_STASH_KEY)
79
80
  : (0, token_store_1.createInMemoryTokenStore)());
81
+ const doFetch = config.fetchImpl ?? ((input, init) => fetch(input, init));
82
+ /**
83
+ * A Frontend API request authenticated as `session` — and only it. Holds its
84
+ * own copy (never persisted), so a revoke re-tried after sign-out dropped the
85
+ * session can still authenticate: a 401 (the short-lived JWT expired) rotates
86
+ * it once with the refresh token and tries again.
87
+ */
88
+ const sessionBoundRequest = (session) => {
89
+ const holder = new js_1.NativeSessionManager({
90
+ baseUrl: frontendApi,
91
+ publishableKey: config.publishableKey,
92
+ initial: session,
93
+ fetchImpl: config.fetchImpl,
94
+ now: config.now,
95
+ });
96
+ return async (path, init) => {
97
+ const send = async () => doFetch(`${frontendApi}${path}`, {
98
+ ...init,
99
+ headers: { ...(await holder.authHeaders()), ...init?.headers },
100
+ });
101
+ const response = await send();
102
+ if (response.status !== 401 || !(await holder.refresh()))
103
+ return response;
104
+ return send();
105
+ };
106
+ };
107
+ // The sessions this app signed out of, kept in the platform store so a
108
+ // restart never re-adopts one. Loaded before the stored session is trusted.
109
+ const tombstoneStore = config.tombstoneStore ??
110
+ (plugins.Preferences ? (0, token_store_1.createPreferencesTombstoneStore)(plugins.Preferences) : undefined);
111
+ const guard = new js_1.SignOutGuard({
112
+ // Every revoke passes its own session-bound request; this one carries none.
113
+ request: (path, init) => doFetch(`${frontendApi}${path}`, {
114
+ ...init,
115
+ headers: { 'x-publishable-key': config.publishableKey, ...init?.headers },
116
+ }),
117
+ frontendApi,
118
+ ...(tombstoneStore ? { store: tombstoneStore } : {}),
119
+ ...(config.signOutRetryDelaysMs ? { retryDelaysMs: config.signOutRetryDelaysMs } : {}),
120
+ });
121
+ await guard.ready;
80
122
  const manager = await (0, native_session_1.createNativeSessionManager)({
81
123
  frontendApi,
82
124
  publishableKey: config.publishableKey,
@@ -84,14 +126,39 @@ async function createAtlasCapacitor(config) {
84
126
  storage,
85
127
  fetchImpl: config.fetchImpl,
86
128
  now: config.now,
129
+ // Never adopt (nor write back) a session this app signed out of; a stored
130
+ // one is revoked again in the background, as itself.
131
+ refuse: (session) => guard.isSignedOut(session.sessionId) && guard.refuse(session.sessionId, sessionBoundRequest(session)),
87
132
  });
133
+ // A refresh still in flight at sign-out must not put the session back in memory.
134
+ manager.onChange((session) => {
135
+ if (guard.isSignedOut(session.sessionId))
136
+ manager.clear();
137
+ });
138
+ const getToken = async () => {
139
+ const token = await manager.getToken();
140
+ // Signed out while a refresh was in flight: the rotated token is not ours.
141
+ return token && manager.current ? token : null;
142
+ };
88
143
  const requireString = (value, name) => {
89
144
  if (!value)
90
145
  throw new Error(`Atlas: \`${name}\` is required to sign in.`);
91
146
  return value;
92
147
  };
148
+ // Policy acceptance (terms, privacy, any policy) over the same bearer session.
149
+ const policyApi = (0, policies_1.createPolicyApi)({
150
+ publishableKey: config.publishableKey,
151
+ frontendApi,
152
+ authHeaders: async () => {
153
+ const token = await getToken();
154
+ return token ? { Authorization: `Bearer ${token}` } : {};
155
+ },
156
+ fetchImpl: config.fetchImpl,
157
+ locale: config.locale,
158
+ });
93
159
  return {
94
160
  manager,
161
+ ...policyApi,
95
162
  async signIn(options = {}) {
96
163
  const clientId = requireString(options.clientId ?? config.clientId, 'clientId');
97
164
  const redirectUri = requireString(options.redirectUri ?? config.redirectUri, 'redirectUri');
@@ -132,25 +199,47 @@ async function createAtlasCapacitor(config) {
132
199
  manager.setSession(session);
133
200
  return session;
134
201
  },
135
- async signOut() {
202
+ async signOut(options = {}) {
203
+ const session = manager.current;
204
+ // Tombstones the session synchronously, before anything below can yield;
205
+ // the revoke itself rides on the session being dropped.
206
+ const pending = session
207
+ ? guard.revoke(session.sessionId, { ...options, request: sessionBoundRequest(session) })
208
+ : null;
136
209
  manager.clear();
137
- await (0, native_session_1.clearNativeSession)(storage);
138
- },
139
- getToken() {
140
- return manager.getToken();
210
+ // The tombstone already keeps a restart from re-adopting a session this
211
+ // clear fails to remove, so a store error does not fail the sign-out.
212
+ await Promise.resolve()
213
+ .then(() => (0, native_session_1.clearNativeSession)(storage))
214
+ .catch(() => undefined);
215
+ // Nothing to revoke when signed out (a bearer client has no cookie to find one by).
216
+ const attempt = pending ? await pending : { sessionId: null, outcome: { revoked: true, status: 200 } };
217
+ // A promoted session (`activeSessionId`) comes with cookies only — the
218
+ // bearer revoke never hands this client a credential for it — so it is
219
+ // reported, not adopted.
220
+ return guard.settle(attempt, options);
141
221
  },
142
- authHeaders() {
143
- return manager.authHeaders();
222
+ getToken,
223
+ async authHeaders() {
224
+ const token = await getToken();
225
+ return token
226
+ ? { Authorization: `Bearer ${token}`, 'x-publishable-key': config.publishableKey }
227
+ : { 'x-publishable-key': config.publishableKey };
144
228
  },
145
229
  getSession() {
146
230
  return manager.current;
147
231
  },
148
232
  onChange(listener) {
149
- return manager.onChange(listener);
233
+ return manager.onChange((session) => {
234
+ if (!guard.isSignedOut(session.sessionId))
235
+ listener(session);
236
+ });
150
237
  },
151
238
  };
152
239
  }
153
240
  // ── Re-exports: the pieces, for apps that drive the flow themselves ──────────
241
+ var js_2 = require("@atlasauth/js");
242
+ Object.defineProperty(exports, "SignOutError", { enumerable: true, get: function () { return js_2.SignOutError; } });
154
243
  __exportStar(require("./plugins"), exports);
155
244
  __exportStar(require("./pkce"), exports);
156
245
  __exportStar(require("./token-store"), exports);
@@ -161,4 +250,6 @@ Object.defineProperty(exports, "clearNativeSession", { enumerable: true, get: fu
161
250
  Object.defineProperty(exports, "NativeSessionManager", { enumerable: true, get: function () { return native_session_2.NativeSessionManager; } });
162
251
  Object.defineProperty(exports, "exchangeForSession", { enumerable: true, get: function () { return native_session_2.exchangeForSession; } });
163
252
  Object.defineProperty(exports, "refreshNativeSession", { enumerable: true, get: function () { return native_session_2.refreshNativeSession; } });
253
+ // Policy acceptance: the DOM pieces for a WebView screen, the gate banner, and the API builder.
254
+ __exportStar(require("./policies"), exports);
164
255
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -12,7 +12,7 @@
12
12
  * session id the refresh call needs and the current JWT. Give the native session
13
13
  * its OWN store/key, separate from any other value the app keeps.
14
14
  */
15
- import { NativeSessionManager } from '@atlasauth/js';
15
+ import { NativeSessionManager, type NativeSession } from '@atlasauth/js';
16
16
  import { type TokenStore } from './token-store';
17
17
  export interface NativeSessionConfig {
18
18
  /** The instance's FAPI origin, e.g. `https://fapi.acme.atlasauth.net`. */
@@ -31,6 +31,14 @@ export interface NativeSessionConfig {
31
31
  fetchImpl?: typeof fetch;
32
32
  /** Injectable clock, epoch ms. Defaults to `Date.now`. */
33
33
  now?: () => number;
34
+ /**
35
+ * Asked before a session is adopted from the store on boot, and before a
36
+ * (rotated) session is persisted. Return true for a session the app signed
37
+ * out of: it is not seeded (and is cleared from the store), nor written back
38
+ * by a refresh that was still in flight at sign-out. `createAtlasCapacitor`
39
+ * wires this to its `SignOutGuard`.
40
+ */
41
+ refuse?: (session: NativeSession) => boolean;
34
42
  }
35
43
  /**
36
44
  * Build a {@link NativeSessionManager} wired to a Capacitor token store.
@@ -35,7 +35,15 @@ async function createNativeSessionManager(config) {
35
35
  allowSameOrigin: false,
36
36
  });
37
37
  const storage = config.storage ?? (0, token_store_1.createInMemoryTokenStore)();
38
- const initial = (0, js_1.parseNativeSession)(await storage.getToken()) ?? undefined;
38
+ let initial = (0, js_1.parseNativeSession)(await storage.getToken()) ?? undefined;
39
+ if (initial && config.refuse?.(initial)) {
40
+ // A session this app signed out of (the clear never landed, or a refresh
41
+ // in flight at sign-out wrote it back): boot signed out.
42
+ initial = undefined;
43
+ await Promise.resolve()
44
+ .then(() => storage.clearToken())
45
+ .catch(() => undefined);
46
+ }
39
47
  return new js_1.NativeSessionManager({
40
48
  baseUrl,
41
49
  publishableKey: config.publishableKey,
@@ -47,6 +55,8 @@ async function createNativeSessionManager(config) {
47
55
  // the rotated refresh token survives an app restart. Fire-and-forget — the
48
56
  // store may be async, and a write failure must not break the live session.
49
57
  persist: (session) => {
58
+ if (config.refuse?.(session))
59
+ return;
50
60
  void Promise.resolve(storage.setToken((0, js_1.serializeNativeSession)(session))).catch(() => undefined);
51
61
  },
52
62
  });
@@ -1 +1 @@
1
- {"version":3,"file":"native-session.js","sourceRoot":"","sources":["../src/native-session.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;;AAsCH,gEA4BC;AAGD,gDAEC;AArED,sCAMuB;AACvB,+CAA0E;AAqB1E;;;;;;;GAOG;AACI,KAAK,UAAU,0BAA0B,CAC9C,MAA2B;IAE3B,2EAA2E;IAC3E,sCAAsC;IACtC,MAAM,OAAO,GAAG,IAAA,uBAAkB,EAAC,MAAM,CAAC,WAAW,EAAE;QACrD,SAAS,EAAE,8BAA8B;QACzC,eAAe,EAAE,KAAK;KACvB,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,IAAA,sCAAwB,GAAE,CAAC;IAC7D,MAAM,OAAO,GAAG,IAAA,uBAAkB,EAAC,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC,IAAI,SAAS,CAAC;IAE1E,OAAO,IAAI,yBAAoB,CAAC;QAC9B,OAAO;QACP,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,2EAA2E;QAC3E,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,OAAmB;IAC1D,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;AAC7B,CAAC;AAED,oCAKuB;AAJrB,0GAAA,oBAAoB,OAAA;AACpB,wGAAA,kBAAkB,OAAA;AAClB,0GAAA,oBAAoB,OAAA"}
1
+ {"version":3,"file":"native-session.js","sourceRoot":"","sources":["../src/native-session.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;;AA8CH,gEAqCC;AAGD,gDAEC;AAtFD,sCAMuB;AACvB,+CAA0E;AA6B1E;;;;;;;GAOG;AACI,KAAK,UAAU,0BAA0B,CAC9C,MAA2B;IAE3B,2EAA2E;IAC3E,sCAAsC;IACtC,MAAM,OAAO,GAAG,IAAA,uBAAkB,EAAC,MAAM,CAAC,WAAW,EAAE;QACrD,SAAS,EAAE,8BAA8B;QACzC,eAAe,EAAE,KAAK;KACvB,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,IAAA,sCAAwB,GAAE,CAAC;IAC7D,IAAI,OAAO,GAAG,IAAA,uBAAkB,EAAC,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC,IAAI,SAAS,CAAC;IACxE,IAAI,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;QACxC,yEAAyE;QACzE,yDAAyD;QACzD,OAAO,GAAG,SAAS,CAAC;QACpB,MAAM,OAAO,CAAC,OAAO,EAAE;aACpB,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;aAChC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC5B,CAAC;IAED,OAAO,IAAI,yBAAoB,CAAC;QAC9B,OAAO;QACP,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,2EAA2E;QAC3E,OAAO,EAAE,CAAC,OAAsB,EAAE,EAAE;YAClC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC;gBAAE,OAAO;YACrC,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,OAAmB;IAC1D,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;AAC7B,CAAC;AAED,oCAKuB;AAJrB,0GAAA,oBAAoB,OAAA;AACpB,wGAAA,kBAAkB,OAAA;AAClB,0GAAA,oBAAoB,OAAA"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Policy acceptance (terms of service, privacy, any policy) for Capacitor.
3
+ *
4
+ * The native-session sign-in runs in the SYSTEM browser on Atlas's hosted pages,
5
+ * which already collect the acceptances (sign-up) and hold a sign-in until a
6
+ * newer version is accepted, so {@link AtlasCapacitor.signIn} needs nothing more.
7
+ * What the app's own WebView layer needs is:
8
+ *
9
+ * - the policies for its own screens (a custom sign-up form): `policies()`
10
+ * returns a `PolicyAcceptanceController`, and the DOM pieces re-exported below
11
+ * (`mountPolicyConsent`, `mountPolicyClickwrap`, `mountPolicyAcceptStep`) draw
12
+ * it;
13
+ * - in-app re-acceptance for the signed-in user: `policyGate()` and
14
+ * {@link mountPolicyGate}'s banner, which post `/v1/client/me/policies/accept`
15
+ * with the session's bearer token.
16
+ *
17
+ * Everything is `@atlasauth/js`; this file only supplies a bearer-authenticated
18
+ * client (a Capacitor app has no cookie against the FAPI origin).
19
+ */
20
+ import { FapiClient, PolicyAcceptanceController, PolicyGateController, type PolicyClasses, type PolicyT } from '@atlasauth/js';
21
+ export interface PolicyApiConfig {
22
+ publishableKey: string;
23
+ frontendApi: string;
24
+ /** The headers an authenticated `/v1/client/me/*` call needs (bearer + pk); empty-bearer when signed out. */
25
+ authHeaders: () => Promise<Record<string, string>>;
26
+ fetchImpl?: typeof fetch;
27
+ /** The UI language, sent as `Accept-Language` and used to pick a translation. */
28
+ locale?: string;
29
+ }
30
+ /** What the Atlas handle exposes for policy acceptance. */
31
+ export interface PolicyApi {
32
+ /** The bearer-authenticated Frontend API client (for `@atlasauth/js` helpers). */
33
+ readonly fapi: FapiClient;
34
+ /**
35
+ * Load the instance's policies (`GET /v1/client/policies`) into a controller
36
+ * for a sign-up form of your own. `signIn` keeps only the policies that also
37
+ * apply at sign-in.
38
+ */
39
+ policies(options?: {
40
+ combined?: boolean;
41
+ signIn?: boolean;
42
+ locale?: string;
43
+ }): Promise<PolicyAcceptanceController>;
44
+ /**
45
+ * The controller for an attempt the server holds at `needs_policy_acceptance`
46
+ * (an attempt view with `pending_policies`), with the content filled in.
47
+ */
48
+ pendingPolicies(attempt: {
49
+ pending_policies?: unknown;
50
+ } | null | undefined, options?: {
51
+ combined?: boolean;
52
+ locale?: string;
53
+ }): Promise<PolicyAcceptanceController>;
54
+ /**
55
+ * In-app re-acceptance for the signed-in user: `load()` the standing,
56
+ * `begin()` a controller for what needs accepting, `accept(controller)` to send it.
57
+ */
58
+ policyGate(locale?: string): PolicyGateController;
59
+ }
60
+ /** Build the policy API over a bearer-authenticated client. */
61
+ export declare function createPolicyApi(config: PolicyApiConfig): PolicyApi;
62
+ /** The English policy strings, with any `policy.*` overrides on top. */
63
+ export declare function policyText(strings?: Record<string, string>): PolicyT;
64
+ export interface MountPolicyGateOptions {
65
+ /** Override any `policy.*` string. */
66
+ strings?: Record<string, string>;
67
+ /** Extra class names per element. */
68
+ classes?: PolicyClasses;
69
+ /** Called after the user accepted and the server confirmed. */
70
+ onAccepted?(): void;
71
+ }
72
+ /**
73
+ * Mount the signed-in re-acceptance banner into `host`: it loads the user's
74
+ * standing from `gate`, shows a banner when a policy needs accepting (with the
75
+ * end of any grace window), and "Review and accept" opens the acceptance step
76
+ * and posts the result. Draws nothing when there is nothing to accept. Call it
77
+ * only for a signed-in user; `ready` resolves once the standing has loaded.
78
+ */
79
+ export declare function mountPolicyGate(host: HTMLElement, gate: PolicyGateController, options?: MountPolicyGateOptions): {
80
+ destroy(): void;
81
+ ready: Promise<void>;
82
+ };
83
+ export { PolicyAcceptanceController, PolicyGateController, buildPolicyAcceptances, injectPolicyStyles, isPolicyAcceptanceRequired, mountPolicyAcceptStep, mountPolicyClickwrap, mountPolicyConsent, runScrollPolicies, type Policy, type PolicyAcceptancePayload, } from '@atlasauth/js';
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ /**
3
+ * Policy acceptance (terms of service, privacy, any policy) for Capacitor.
4
+ *
5
+ * The native-session sign-in runs in the SYSTEM browser on Atlas's hosted pages,
6
+ * which already collect the acceptances (sign-up) and hold a sign-in until a
7
+ * newer version is accepted, so {@link AtlasCapacitor.signIn} needs nothing more.
8
+ * What the app's own WebView layer needs is:
9
+ *
10
+ * - the policies for its own screens (a custom sign-up form): `policies()`
11
+ * returns a `PolicyAcceptanceController`, and the DOM pieces re-exported below
12
+ * (`mountPolicyConsent`, `mountPolicyClickwrap`, `mountPolicyAcceptStep`) draw
13
+ * it;
14
+ * - in-app re-acceptance for the signed-in user: `policyGate()` and
15
+ * {@link mountPolicyGate}'s banner, which post `/v1/client/me/policies/accept`
16
+ * with the session's bearer token.
17
+ *
18
+ * Everything is `@atlasauth/js`; this file only supplies a bearer-authenticated
19
+ * client (a Capacitor app has no cookie against the FAPI origin).
20
+ */
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.runScrollPolicies = exports.mountPolicyConsent = exports.mountPolicyClickwrap = exports.mountPolicyAcceptStep = exports.isPolicyAcceptanceRequired = exports.injectPolicyStyles = exports.buildPolicyAcceptances = exports.PolicyGateController = exports.PolicyAcceptanceController = void 0;
23
+ exports.createPolicyApi = createPolicyApi;
24
+ exports.policyText = policyText;
25
+ exports.mountPolicyGate = mountPolicyGate;
26
+ const js_1 = require("@atlasauth/js");
27
+ /** Build the policy API over a bearer-authenticated client. */
28
+ function createPolicyApi(config) {
29
+ const doFetch = config.fetchImpl ?? ((input, init) => fetch(input, init));
30
+ const fapi = new js_1.FapiClient({
31
+ publishableKey: config.publishableKey,
32
+ baseUrl: config.frontendApi,
33
+ locale: config.locale,
34
+ fetchImpl: async (input, init) => {
35
+ const headers = new Headers(init?.headers);
36
+ for (const [k, v] of Object.entries(await config.authHeaders()))
37
+ if (!headers.has(k))
38
+ headers.set(k, v);
39
+ return doFetch(input, { ...init, headers });
40
+ },
41
+ });
42
+ return {
43
+ fapi,
44
+ async policies(options = {}) {
45
+ const controller = new js_1.PolicyAcceptanceController([], { combined: options.combined });
46
+ controller.setPolicies(await (0, js_1.loadPolicies)(fapi, { locale: options.locale ?? config.locale, signIn: options.signIn }));
47
+ return controller;
48
+ },
49
+ pendingPolicies: (attempt, options = {}) => (0, js_1.controllerForPending)(fapi, attempt, { combined: options.combined, locale: options.locale ?? config.locale }),
50
+ policyGate: (locale) => new js_1.PolicyGateController(fapi, locale ?? config.locale),
51
+ };
52
+ }
53
+ /** The English policy strings, with any `policy.*` overrides on top. */
54
+ function policyText(strings) {
55
+ return (0, js_1.policyTranslator)((key, vars) => {
56
+ const template = strings?.[key];
57
+ return template ? template.replace(/\{(\w+)\}/g, (m, n) => vars?.[n] ?? m) : '';
58
+ });
59
+ }
60
+ /**
61
+ * Mount the signed-in re-acceptance banner into `host`: it loads the user's
62
+ * standing from `gate`, shows a banner when a policy needs accepting (with the
63
+ * end of any grace window), and "Review and accept" opens the acceptance step
64
+ * and posts the result. Draws nothing when there is nothing to accept. Call it
65
+ * only for a signed-in user; `ready` resolves once the standing has loaded.
66
+ */
67
+ function mountPolicyGate(host, gate, options = {}) {
68
+ const doc = host.ownerDocument;
69
+ const t = policyText(options.strings);
70
+ let step = null;
71
+ let open = false;
72
+ let alive = true;
73
+ (0, js_1.injectPolicyStyles)(doc);
74
+ const showError = (message) => {
75
+ const p = doc.createElement('p');
76
+ p.setAttribute('role', 'alert');
77
+ p.textContent = message;
78
+ host.append(p);
79
+ };
80
+ const draw = () => {
81
+ if (!alive || open)
82
+ return;
83
+ host.textContent = '';
84
+ host.setAttribute('data-atlas-policy-gate', '');
85
+ if (gate.pending.length === 0)
86
+ return;
87
+ const banner = doc.createElement('div');
88
+ banner.className = 'atlas-policy-banner';
89
+ banner.setAttribute('role', 'status');
90
+ banner.setAttribute('data-atlas-policy-banner', '');
91
+ const text = doc.createElement('span');
92
+ const strong = doc.createElement('strong');
93
+ strong.textContent = `${t('policy.bannerTitle')}. `;
94
+ text.append(strong, t('policy.bannerBody', { policies: (0, js_1.joinTitles)(gate.pending.map((p) => p.title), t('policy.and')) }));
95
+ if (gate.graceEndsAt)
96
+ text.append(` ${t('policy.bannerGrace', { date: (0, js_1.formatPolicyDate)(gate.graceEndsAt) })}`);
97
+ const button = doc.createElement('button');
98
+ button.type = 'button';
99
+ button.className = ['atlas-policy-link', options.classes?.link].filter(Boolean).join(' ');
100
+ button.textContent = t('policy.bannerReview');
101
+ button.addEventListener('click', () => void begin());
102
+ banner.append(text, button);
103
+ host.append(banner);
104
+ };
105
+ const close = () => {
106
+ step?.destroy();
107
+ step = null;
108
+ open = false;
109
+ draw();
110
+ };
111
+ const begin = async () => {
112
+ const controller = await gate.begin();
113
+ if (!alive)
114
+ return;
115
+ open = true;
116
+ host.textContent = '';
117
+ const stepHost = doc.createElement('div');
118
+ host.append(stepHost);
119
+ step = (0, js_1.mountPolicyAcceptStep)(stepHost, controller, {
120
+ t,
121
+ classes: options.classes,
122
+ onSubmit: async () => {
123
+ step?.setBusy(true);
124
+ const res = await gate.accept(controller);
125
+ step?.setBusy(false);
126
+ if (!res.ok) {
127
+ showError(res.errors[0]?.message ?? t('policy.requiredGeneric'));
128
+ return;
129
+ }
130
+ close();
131
+ options.onAccepted?.();
132
+ },
133
+ onDecline: close,
134
+ });
135
+ };
136
+ const off = gate.subscribe(draw);
137
+ const ready = gate.load().then(draw, draw);
138
+ return {
139
+ ready,
140
+ destroy() {
141
+ alive = false;
142
+ off();
143
+ step?.destroy();
144
+ host.textContent = '';
145
+ },
146
+ };
147
+ }
148
+ // The DOM pieces and helpers a WebView screen draws with (all from `@atlasauth/js`).
149
+ var js_2 = require("@atlasauth/js");
150
+ Object.defineProperty(exports, "PolicyAcceptanceController", { enumerable: true, get: function () { return js_2.PolicyAcceptanceController; } });
151
+ Object.defineProperty(exports, "PolicyGateController", { enumerable: true, get: function () { return js_2.PolicyGateController; } });
152
+ Object.defineProperty(exports, "buildPolicyAcceptances", { enumerable: true, get: function () { return js_2.buildPolicyAcceptances; } });
153
+ Object.defineProperty(exports, "injectPolicyStyles", { enumerable: true, get: function () { return js_2.injectPolicyStyles; } });
154
+ Object.defineProperty(exports, "isPolicyAcceptanceRequired", { enumerable: true, get: function () { return js_2.isPolicyAcceptanceRequired; } });
155
+ Object.defineProperty(exports, "mountPolicyAcceptStep", { enumerable: true, get: function () { return js_2.mountPolicyAcceptStep; } });
156
+ Object.defineProperty(exports, "mountPolicyClickwrap", { enumerable: true, get: function () { return js_2.mountPolicyClickwrap; } });
157
+ Object.defineProperty(exports, "mountPolicyConsent", { enumerable: true, get: function () { return js_2.mountPolicyConsent; } });
158
+ Object.defineProperty(exports, "runScrollPolicies", { enumerable: true, get: function () { return js_2.runScrollPolicies; } });
159
+ //# sourceMappingURL=policies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policies.js","sourceRoot":"","sources":["../src/policies.ts"],"names":[],"mappings":"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"}
@@ -20,6 +20,7 @@
20
20
  * `capacitor-secure-storage-plugin` — behind this same {@link TokenStore}
21
21
  * interface. See {@link createPreferencesTokenStore} for the drop-in shape.
22
22
  */
23
+ import type { TombstoneStore } from '@atlasauth/js';
23
24
  import type { PreferencesPlugin } from './plugins';
24
25
  /**
25
26
  * A single-slot token store: read, write, clear one string value. This is the
@@ -61,3 +62,16 @@ export declare function createPreferencesTokenStore(preferences: PreferencesPlug
61
62
  * adapter) in production.
62
63
  */
63
64
  export declare function createInMemoryTokenStore(): TokenStore;
65
+ /**
66
+ * A {@link TombstoneStore} over `@capacitor/preferences` — where the ids of the
67
+ * sessions this app signed out of are kept, so a restart never re-adopts one
68
+ * (see `SignOutGuard` in `@atlasauth/js`). The default when the plugin is
69
+ * present. Tombstones are session ids, never credentials, so plaintext is fine.
70
+ */
71
+ export declare function createPreferencesTombstoneStore(preferences: PreferencesPlugin): TombstoneStore;
72
+ /**
73
+ * Adapt a single-slot {@link TokenStore} (e.g. a secure-storage-backed one) to
74
+ * a {@link TombstoneStore}. Give it its OWN slot — never the session's: the
75
+ * key `SignOutGuard` asks for is ignored, every read and write hits that slot.
76
+ */
77
+ export declare function tombstoneStoreFromTokenStore(store: TokenStore): TombstoneStore;
@@ -25,6 +25,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
25
25
  exports.DEFAULT_SESSION_KEY = void 0;
26
26
  exports.createPreferencesTokenStore = createPreferencesTokenStore;
27
27
  exports.createInMemoryTokenStore = createInMemoryTokenStore;
28
+ exports.createPreferencesTombstoneStore = createPreferencesTombstoneStore;
29
+ exports.tombstoneStoreFromTokenStore = tombstoneStoreFromTokenStore;
28
30
  /** The default key the serialized native session is stored under. */
29
31
  exports.DEFAULT_SESSION_KEY = 'atlas.native_session';
30
32
  /**
@@ -67,4 +69,27 @@ function createInMemoryTokenStore() {
67
69
  },
68
70
  };
69
71
  }
72
+ /**
73
+ * A {@link TombstoneStore} over `@capacitor/preferences` — where the ids of the
74
+ * sessions this app signed out of are kept, so a restart never re-adopts one
75
+ * (see `SignOutGuard` in `@atlasauth/js`). The default when the plugin is
76
+ * present. Tombstones are session ids, never credentials, so plaintext is fine.
77
+ */
78
+ function createPreferencesTombstoneStore(preferences) {
79
+ return {
80
+ getItem: async (key) => (await preferences.get({ key })).value ?? null,
81
+ setItem: (key, value) => preferences.set({ key, value }),
82
+ };
83
+ }
84
+ /**
85
+ * Adapt a single-slot {@link TokenStore} (e.g. a secure-storage-backed one) to
86
+ * a {@link TombstoneStore}. Give it its OWN slot — never the session's: the
87
+ * key `SignOutGuard` asks for is ignored, every read and write hits that slot.
88
+ */
89
+ function tombstoneStoreFromTokenStore(store) {
90
+ return {
91
+ getItem: () => store.getToken(),
92
+ setItem: (_key, value) => store.setToken(value),
93
+ };
94
+ }
70
95
  //# sourceMappingURL=token-store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"token-store.js","sourceRoot":"","sources":["../src/token-store.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;;;AAsCH,kEASC;AAQD,4DAWC;AA9CD,qEAAqE;AACxD,QAAA,mBAAmB,GAAG,sBAAsB,CAAC;AAE1D;;;;;;;;;;;;;;GAcG;AACH,SAAgB,2BAA2B,CACzC,WAA8B,EAC9B,MAAc,2BAAmB;IAEjC,OAAO;QACL,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,WAAW,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI;QACpE,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;QACpD,UAAU,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,wBAAwB;IACtC,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"}
1
+ {"version":3,"file":"token-store.js","sourceRoot":"","sources":["../src/token-store.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;;;AAuCH,kEASC;AAQD,4DAWC;AAQD,0EAKC;AAOD,oEAKC;AAvED,qEAAqE;AACxD,QAAA,mBAAmB,GAAG,sBAAsB,CAAC;AAE1D;;;;;;;;;;;;;;GAcG;AACH,SAAgB,2BAA2B,CACzC,WAA8B,EAC9B,MAAc,2BAAmB;IAEjC,OAAO;QACL,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,WAAW,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI;QACpE,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;QACpD,UAAU,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,wBAAwB;IACtC,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;;;;;GAKG;AACH,SAAgB,+BAA+B,CAAC,WAA8B;IAC5E,OAAO;QACL,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,MAAM,WAAW,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI;QACtE,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;KACzD,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAgB,4BAA4B,CAAC,KAAiB;IAC5D,OAAO;QACL,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE;QAC/B,OAAO,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC;KAChD,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlasauth/capacitor",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "exports": {
@@ -11,7 +11,7 @@
11
11
  "./package.json": "./package.json"
12
12
  },
13
13
  "dependencies": {
14
- "@atlasauth/js": "0.6.0"
14
+ "@atlasauth/js": "0.19.0"
15
15
  },
16
16
  "peerDependencies": {
17
17
  "@capacitor/core": ">=6",