@multiplatform.one/auth 7.7.2
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/LICENSE +201 -0
- package/README.md +49 -0
- package/dist/cjs/accessTokenRefresh.cjs +70 -0
- package/dist/cjs/accessTokenRefresh.native.js +78 -0
- package/dist/cjs/accessTokenRefresh.native.js.map +1 -0
- package/dist/cjs/index.cjs +369 -0
- package/dist/cjs/index.native.js +411 -0
- package/dist/cjs/index.native.js.map +1 -0
- package/dist/esm/accessTokenRefresh.mjs +40 -0
- package/dist/esm/accessTokenRefresh.mjs.map +1 -0
- package/dist/esm/accessTokenRefresh.native.js +45 -0
- package/dist/esm/accessTokenRefresh.native.js.map +1 -0
- package/dist/esm/index.mjs +336 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/index.native.js +375 -0
- package/dist/esm/index.native.js.map +1 -0
- package/dist/jsx/accessTokenRefresh.mjs +40 -0
- package/dist/jsx/accessTokenRefresh.mjs.map +1 -0
- package/dist/jsx/accessTokenRefresh.native.js +78 -0
- package/dist/jsx/accessTokenRefresh.native.js.map +1 -0
- package/dist/jsx/index.js +336 -0
- package/dist/jsx/index.js.map +1 -0
- package/dist/jsx/index.mjs +336 -0
- package/dist/jsx/index.mjs.map +1 -0
- package/dist/jsx/index.native.js +411 -0
- package/dist/jsx/index.native.js.map +1 -0
- package/package.json +78 -0
- package/src/accessTokenRefresh.ts +80 -0
- package/src/index.ts +665 -0
- package/types/accessTokenRefresh.d.ts +45 -0
- package/types/accessTokenRefresh.d.ts.map +1 -0
- package/types/index.d.ts +108 -0
- package/types/index.d.ts.map +1 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Isomorphic helpers for Keycloak access-token refresh.
|
|
3
|
+
*
|
|
4
|
+
* better-auth's `/get-access-token` collapses every refresh failure into
|
|
5
|
+
* `FAILED_TO_GET_ACCESS_TOKEN` (400). The Keycloak SSO plugin in `createAuth`
|
|
6
|
+
* reclassifies: a dead refresh token (`invalid_grant`) stays 400 and revokes
|
|
7
|
+
* the session; a Keycloak blip (restart, 5xx, network) is rewritten to
|
|
8
|
+
* `TOKEN_REFRESH_UNAVAILABLE` so clients can retry instead of signing the
|
|
9
|
+
* user out.
|
|
10
|
+
*
|
|
11
|
+
* Web and native token getters share this classifier so a restart never
|
|
12
|
+
* looks like a logout. Stream 9 (native) can import
|
|
13
|
+
* `@multiplatform.one/auth/access-token` without pulling Node `async_hooks`.
|
|
14
|
+
*/
|
|
15
|
+
export declare const FAILED_TO_GET_ACCESS_TOKEN = "FAILED_TO_GET_ACCESS_TOKEN";
|
|
16
|
+
export declare const TOKEN_REFRESH_UNAVAILABLE = "TOKEN_REFRESH_UNAVAILABLE";
|
|
17
|
+
export type AccessTokenFailureKind = "signed-out" | "transient";
|
|
18
|
+
/** First attempt is immediate; later attempts wait out a Keycloak bounce. */
|
|
19
|
+
export declare const ACCESS_TOKEN_RETRY_DELAYS_MS: readonly [0, 400, 1000];
|
|
20
|
+
export declare function classifyAccessTokenResponse(status: number, body?: {
|
|
21
|
+
code?: string;
|
|
22
|
+
} | null): AccessTokenFailureKind;
|
|
23
|
+
export type RetryAttemptResult<T> = {
|
|
24
|
+
ok: true;
|
|
25
|
+
value: T;
|
|
26
|
+
} | {
|
|
27
|
+
ok: false;
|
|
28
|
+
kind: AccessTokenFailureKind;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Retry an access-token fetch while the failure is transient (Keycloak
|
|
32
|
+
* restart, 5xx, network). A definitive signed-out answer stops immediately
|
|
33
|
+
* so we never hammer a revoked session.
|
|
34
|
+
*/
|
|
35
|
+
export declare function retryWhileTransient<T>(attempt: () => Promise<RetryAttemptResult<T>>, opts?: {
|
|
36
|
+
delaysMs?: readonly number[];
|
|
37
|
+
sleep?: (ms: number) => Promise<void>;
|
|
38
|
+
}): Promise<RetryAttemptResult<T>>;
|
|
39
|
+
/**
|
|
40
|
+
* Revalidate when the tab becomes visible again (GitHub / Linear / Figma
|
|
41
|
+
* style: a backgrounded tab notices IdP logout or a recovered Keycloak
|
|
42
|
+
* without a full reload). Returns an unsubscribe. No-op on the server.
|
|
43
|
+
*/
|
|
44
|
+
export declare function watchDocumentVisible(revalidate: () => void): () => void;
|
|
45
|
+
//# sourceMappingURL=accessTokenRefresh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accessTokenRefresh.d.ts","sourceRoot":"","sources":["../src/accessTokenRefresh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,eAAO,MAAM,0BAA0B,+BAA+B,CAAC;AACvE,eAAO,MAAM,yBAAyB,8BAA8B,CAAC;AAErE,MAAM,MAAM,sBAAsB,GAAG,YAAY,GAAG,WAAW,CAAC;AAEhE,6EAA6E;AAC7E,eAAO,MAAM,4BAA4B,yBAA0B,CAAC;AAEpE,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,GAC9B,sBAAsB,CAIxB;AAED,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAC5B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GACtB;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,sBAAsB,CAAA;CAAE,CAAC;AAEhD;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,EACzC,OAAO,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,EAC7C,IAAI,CAAC,EAAE;IACL,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC,GACA,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAYhC;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAavE"}
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @multiplatform.one/auth
|
|
3
|
+
*
|
|
4
|
+
* Better Auth helpers for multiplatform.one apps with Keycloak.
|
|
5
|
+
* Provides factory functions for auth instances, route handlers, and session helpers.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { createAuth, createAuthRouteHandler, createSessionHelpers } from "@multiplatform.one/auth";
|
|
10
|
+
*
|
|
11
|
+
* export const auth = createAuth();
|
|
12
|
+
* export const { GET, POST } = createAuthRouteHandler(auth);
|
|
13
|
+
* export const { verifyAuth, getSession } = createSessionHelpers(auth);
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
import { betterAuth } from "better-auth";
|
|
17
|
+
export { ACCESS_TOKEN_RETRY_DELAYS_MS, FAILED_TO_GET_ACCESS_TOKEN, TOKEN_REFRESH_UNAVAILABLE, classifyAccessTokenResponse, retryWhileTransient, watchDocumentVisible, } from "./accessTokenRefresh";
|
|
18
|
+
export type { AccessTokenFailureKind, RetryAttemptResult } from "./accessTokenRefresh";
|
|
19
|
+
export interface KeycloakOptions {
|
|
20
|
+
baseUrl?: string;
|
|
21
|
+
realm?: string;
|
|
22
|
+
clientId?: string;
|
|
23
|
+
clientSecret?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface CreateAuthOptions {
|
|
26
|
+
/** Base path for auth routes (default: "/api/auth") */
|
|
27
|
+
basePath?: string;
|
|
28
|
+
/** Base URL of the app (reads BASE_URL env var, or defaults to localhost:ONE_PORT) */
|
|
29
|
+
baseUrl?: string;
|
|
30
|
+
/** Auth secret (reads SECRET env var) */
|
|
31
|
+
secret?: string;
|
|
32
|
+
/** Trusted origins for CORS (auto-includes baseUrl and keycloak URL) */
|
|
33
|
+
trustedOrigins?: string[];
|
|
34
|
+
/** Keycloak configuration (reads env vars by default) */
|
|
35
|
+
keycloak?: KeycloakOptions;
|
|
36
|
+
/** Session cookie max age in seconds (default: 7 days) */
|
|
37
|
+
sessionMaxAge?: number;
|
|
38
|
+
/** Include @better-auth/expo plugin (default: true) */
|
|
39
|
+
enableExpo?: boolean;
|
|
40
|
+
/** Additional better-auth plugins */
|
|
41
|
+
plugins?: Parameters<typeof betterAuth>[0]["plugins"];
|
|
42
|
+
/**
|
|
43
|
+
* Database URL or Kysely adapter.
|
|
44
|
+
* Defaults to a SQLite file at `$DATA_DIR/better-auth.db` (or `./better-auth.db`).
|
|
45
|
+
*/
|
|
46
|
+
database?: Parameters<typeof betterAuth>[0]["database"];
|
|
47
|
+
}
|
|
48
|
+
/** Structural type for a Better Auth instance used by helpers. */
|
|
49
|
+
export interface AuthLike {
|
|
50
|
+
handler: (request: Request) => Promise<Response> | Response;
|
|
51
|
+
api: {
|
|
52
|
+
getSession: (opts: {
|
|
53
|
+
headers: Headers;
|
|
54
|
+
}) => Promise<unknown>;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Create a Better Auth instance configured for Keycloak.
|
|
59
|
+
* Keycloak is expected at ${BASE_URL}/auth (proxied by Frappe in dev).
|
|
60
|
+
*/
|
|
61
|
+
export declare function createAuth(options?: CreateAuthOptions): import("better-auth").Auth<{
|
|
62
|
+
secret: string;
|
|
63
|
+
trustedOrigins: string[];
|
|
64
|
+
session: {
|
|
65
|
+
cookieCache: {
|
|
66
|
+
enabled: true;
|
|
67
|
+
maxAge: number;
|
|
68
|
+
strategy: "jwe";
|
|
69
|
+
refreshCache: true;
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
account: {
|
|
73
|
+
storeStateStrategy: "cookie";
|
|
74
|
+
storeAccountCookie: true;
|
|
75
|
+
};
|
|
76
|
+
plugins: any[];
|
|
77
|
+
database?: any;
|
|
78
|
+
basePath: string;
|
|
79
|
+
baseURL: string;
|
|
80
|
+
}>;
|
|
81
|
+
/** The return type of `createAuth()`. */
|
|
82
|
+
export type AuthInstance = ReturnType<typeof createAuth>;
|
|
83
|
+
/**
|
|
84
|
+
* Create GET and POST route handlers for One framework `+api.ts` files.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```ts
|
|
88
|
+
* // lib/server/auth.ts
|
|
89
|
+
* export const { GET, POST } = createAuthRouteHandler(auth);
|
|
90
|
+
*
|
|
91
|
+
* // routes/api/auth/[route]+api.ts
|
|
92
|
+
* export { GET, POST } from "../../../lib/server/auth";
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
export declare function createAuthRouteHandler(auth: AuthLike): {
|
|
96
|
+
readonly GET: (req: Request) => Response | Promise<Response>;
|
|
97
|
+
readonly POST: (req: Request) => Response | Promise<Response>;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Create session verification helpers bound to an auth instance.
|
|
101
|
+
*
|
|
102
|
+
* @returns `verifyAuth` (throws 401 Response) and `getSession` (returns session or null)
|
|
103
|
+
*/
|
|
104
|
+
export declare function createSessionHelpers(auth: AuthLike): {
|
|
105
|
+
verifyAuth: (req: Request) => Promise<{}>;
|
|
106
|
+
getSession: (req: Request) => Promise<unknown>;
|
|
107
|
+
};
|
|
108
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,UAAU,EAAsB,MAAM,aAAa,CAAC;AAc7D,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,EAC1B,yBAAyB,EACzB,2BAA2B,EAC3B,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAmDvF,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sFAAsF;IACtF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,yDAAyD;IACzD,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,0DAA0D;IAC1D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uDAAuD;IACvD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,qCAAqC;IACrC,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACtD;;;OAGG;IACH,QAAQ,CAAC,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;CACzD;AAED,kEAAkE;AAClE,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC;IAC5D,GAAG,EAAE;QACH,UAAU,EAAE,CAAC,IAAI,EAAE;YAAE,OAAO,EAAE,OAAO,CAAA;SAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;KAC9D,CAAC;CACH;AA2QD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB;;;;;;;;;;;;;;;;;;;GAoNzD;AAED,yCAAyC;AACzC,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAIzD;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,QAAQ;wBAK7B,OAAO;yBAAP,OAAO;EAK9B;AAID;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,QAAQ;sBAOlB,OAAO;sBALP,OAAO;EAcvC"}
|