@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.
@@ -0,0 +1,411 @@
1
+ "use strict";
2
+
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all) __defProp(target, name, {
9
+ get: all[name],
10
+ enumerable: true
11
+ });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
16
+ get: () => from[key],
17
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
18
+ });
19
+ }
20
+ return to;
21
+ };
22
+ var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
23
+ value: true
24
+ }), mod);
25
+ var index_exports = {};
26
+ __export(index_exports, {
27
+ ACCESS_TOKEN_RETRY_DELAYS_MS: () => import_accessTokenRefresh2.ACCESS_TOKEN_RETRY_DELAYS_MS,
28
+ FAILED_TO_GET_ACCESS_TOKEN: () => import_accessTokenRefresh2.FAILED_TO_GET_ACCESS_TOKEN,
29
+ TOKEN_REFRESH_UNAVAILABLE: () => import_accessTokenRefresh2.TOKEN_REFRESH_UNAVAILABLE,
30
+ classifyAccessTokenResponse: () => import_accessTokenRefresh2.classifyAccessTokenResponse,
31
+ createAuth: () => createAuth,
32
+ createAuthRouteHandler: () => createAuthRouteHandler,
33
+ createSessionHelpers: () => createSessionHelpers,
34
+ retryWhileTransient: () => import_accessTokenRefresh2.retryWhileTransient,
35
+ watchDocumentVisible: () => import_accessTokenRefresh2.watchDocumentVisible
36
+ });
37
+ module.exports = __toCommonJS(index_exports);
38
+ var import_async_hooks = require("async_hooks");
39
+ var import_better_auth = require("better-auth");
40
+ var import_api = require("better-auth/api");
41
+ var import_cookies = require("better-auth/cookies");
42
+ var import_plugins = require("better-auth/plugins");
43
+ var import_expo = require("@better-auth/expo");
44
+ var import_accessTokenRefresh = require("./accessTokenRefresh.native.js");
45
+ var import_accessTokenRefresh2 = require("./accessTokenRefresh.native.js");
46
+ var requestOriginStorage = new import_async_hooks.AsyncLocalStorage();
47
+ function deriveRequestOrigin(req) {
48
+ var isDevHost = function isDevHost2(host) {
49
+ return DEV_LAN_HOST_PATTERNS.some(function (pattern) {
50
+ return (0, import_better_auth.matchesHostPattern)(host, pattern);
51
+ });
52
+ };
53
+ var forwardedHost = req.headers.get("x-forwarded-host");
54
+ if (forwardedHost && isDevHost(forwardedHost)) {
55
+ var proto = req.headers.get("x-forwarded-proto") === "https" ? "https" : "http";
56
+ return `${proto}://${forwardedHost}`;
57
+ }
58
+ var originHeader = req.headers.get("origin");
59
+ if (originHeader) {
60
+ try {
61
+ var url = new URL(originHeader);
62
+ if (isDevHost(url.host)) return url.origin;
63
+ } catch (unused) {}
64
+ }
65
+ try {
66
+ return new URL(req.url).origin;
67
+ } catch (unused) {
68
+ return void 0;
69
+ }
70
+ }
71
+ var DEV_LAN_HOST_PATTERNS = ["localhost", "localhost:*", "127.0.0.1", "127.0.0.1:*", "10.*", "192.168.*", "172.*", "*.local", "*.local:*"];
72
+ function createKeycloakSsoPlugin(options) {
73
+ var {
74
+ realm,
75
+ clientId,
76
+ clientSecret,
77
+ issuer,
78
+ baseUrl,
79
+ publicKeycloakBaseFor
80
+ } = options;
81
+ var tokenEndpoint = `${issuer}/protocol/openid-connect/token`;
82
+ var resolveVisitorOrigin = function resolveVisitorOrigin2(request) {
83
+ var _requestOriginStorage_getStore;
84
+ return (_requestOriginStorage_getStore = requestOriginStorage.getStore()) !== null && _requestOriginStorage_getStore !== void 0 ? _requestOriginStorage_getStore : request ? deriveRequestOrigin(request) : void 0;
85
+ };
86
+ var isRefreshDefinitivelyDead = async function isRefreshDefinitivelyDead2(refreshToken) {
87
+ try {
88
+ var res = await fetch(tokenEndpoint, {
89
+ method: "POST",
90
+ headers: {
91
+ "content-type": "application/x-www-form-urlencoded"
92
+ },
93
+ body: new URLSearchParams({
94
+ grant_type: "refresh_token",
95
+ refresh_token: refreshToken,
96
+ client_id: clientId,
97
+ client_secret: clientSecret
98
+ }),
99
+ signal: AbortSignal.timeout(5e3)
100
+ });
101
+ if (res.ok) return false;
102
+ if (res.status !== 400 && res.status !== 401) return false;
103
+ var body = await res.json().catch(function () {
104
+ return null;
105
+ });
106
+ return (body === null || body === void 0 ? void 0 : body.error) === "invalid_grant" || (body === null || body === void 0 ? void 0 : body.error) === "invalid_token";
107
+ } catch (unused) {
108
+ return false;
109
+ }
110
+ };
111
+ var signOutSso = (0, import_api.createAuthEndpoint)("/sign-out/sso", {
112
+ method: "GET"
113
+ }, async function (ctx) {
114
+ var _resolveVisitorOrigin, _ref;
115
+ var visitorOrigin = (_resolveVisitorOrigin = resolveVisitorOrigin(ctx.request)) !== null && _resolveVisitorOrigin !== void 0 ? _resolveVisitorOrigin : baseUrl;
116
+ var searchParams = ctx.request ? new URL(ctx.request.url).searchParams : void 0;
117
+ var rawCallback = (_ref = searchParams === null || searchParams === void 0 ? void 0 : searchParams.get("callbackURL")) !== null && _ref !== void 0 ? _ref : null;
118
+ var jsonMode = (searchParams === null || searchParams === void 0 ? void 0 : searchParams.get("mode")) === "json";
119
+ var answer = function answer2(url, redirect) {
120
+ if (jsonMode) return ctx.json({
121
+ redirect,
122
+ url
123
+ });
124
+ throw ctx.redirect(url);
125
+ };
126
+ var callbackURL = rawCallback || "/";
127
+ var postLogoutRedirect = callbackURL.startsWith("/") ? `${visitorOrigin}${callbackURL}` : callbackURL;
128
+ var idTokenHint;
129
+ var sessionToken = await ctx.getSignedCookie(ctx.context.authCookies.sessionToken.name, ctx.context.secret);
130
+ var session = await (0, import_api.getSessionFromCtx)(ctx).catch(function () {
131
+ return null;
132
+ });
133
+ if (session) {
134
+ var _ref1;
135
+ var _accounts_find;
136
+ var accounts = await ctx.context.internalAdapter.findAccounts(session.user.id).catch(function () {
137
+ return [];
138
+ });
139
+ idTokenHint = (_ref1 = (_accounts_find = accounts.find(function (account) {
140
+ return account.providerId === "keycloak";
141
+ })) === null || _accounts_find === void 0 ? void 0 : _accounts_find.idToken) !== null && _ref1 !== void 0 ? _ref1 : void 0;
142
+ }
143
+ if (!idTokenHint) {
144
+ var accountCookie = await (0, import_cookies.getAccountCookie)(ctx).catch(function () {
145
+ return null;
146
+ });
147
+ if ((accountCookie === null || accountCookie === void 0 ? void 0 : accountCookie.providerId) === "keycloak" && accountCookie.idToken) {
148
+ idTokenHint = accountCookie.idToken;
149
+ }
150
+ }
151
+ if (sessionToken) {
152
+ await ctx.context.internalAdapter.deleteSession(sessionToken).catch(function (error) {
153
+ ctx.context.logger.error("Failed to delete session during SSO sign-out", error);
154
+ });
155
+ }
156
+ (0, import_cookies.deleteSessionCookie)(ctx);
157
+ var keycloakBase = publicKeycloakBaseFor(visitorOrigin);
158
+ if (!keycloakBase || !session && !idTokenHint && !sessionToken) {
159
+ return answer(postLogoutRedirect, false);
160
+ }
161
+ var endSession = new URL(`${keycloakBase}/realms/${realm}/protocol/openid-connect/logout`);
162
+ endSession.searchParams.set("post_logout_redirect_uri", postLogoutRedirect);
163
+ endSession.searchParams.set("client_id", clientId);
164
+ if (idTokenHint) endSession.searchParams.set("id_token_hint", idTokenHint);
165
+ return answer(endSession.toString(), true);
166
+ });
167
+ return {
168
+ id: "keycloak-sso",
169
+ endpoints: {
170
+ signOutSso
171
+ },
172
+ hooks: {
173
+ after: [{
174
+ matcher: function matcher(ctx) {
175
+ return ctx.path === "/get-access-token";
176
+ },
177
+ handler: (0, import_api.createAuthMiddleware)(async function (ctx) {
178
+ var _ctx_body, _accounts_find;
179
+ var returned = ctx.context.returned;
180
+ if (!(0, import_api.isAPIError)(returned)) return;
181
+ var body = returned.body;
182
+ if ((body === null || body === void 0 ? void 0 : body.code) !== import_accessTokenRefresh.FAILED_TO_GET_ACCESS_TOKEN) return;
183
+ var providerId = (_ctx_body = ctx.body) === null || _ctx_body === void 0 ? void 0 : _ctx_body.providerId;
184
+ if (providerId && providerId !== "keycloak") return;
185
+ var session = await (0, import_api.getSessionFromCtx)(ctx).catch(function () {
186
+ return null;
187
+ });
188
+ if (!session) return;
189
+ var accounts = await ctx.context.internalAdapter.findAccounts(session.user.id).catch(function () {
190
+ return [];
191
+ });
192
+ var refreshToken = (_accounts_find = accounts.find(function (account) {
193
+ return account.providerId === "keycloak";
194
+ })) === null || _accounts_find === void 0 ? void 0 : _accounts_find.refreshToken;
195
+ if (!refreshToken) {
196
+ var accountCookie = await (0, import_cookies.getAccountCookie)(ctx).catch(function () {
197
+ return null;
198
+ });
199
+ if ((accountCookie === null || accountCookie === void 0 ? void 0 : accountCookie.providerId) === "keycloak") {
200
+ refreshToken = accountCookie.refreshToken;
201
+ }
202
+ }
203
+ var definitive = refreshToken ? await isRefreshDefinitivelyDead(refreshToken) : true;
204
+ if (!definitive) {
205
+ return new import_api.APIError("INTERNAL_SERVER_ERROR", {
206
+ message: "Keycloak token refresh temporarily unavailable",
207
+ code: import_accessTokenRefresh.TOKEN_REFRESH_UNAVAILABLE
208
+ });
209
+ }
210
+ ctx.context.logger.warn("Keycloak refresh token is dead (invalid_grant); revoking the stale Better Auth session");
211
+ var sessionToken = await ctx.getSignedCookie(ctx.context.authCookies.sessionToken.name, ctx.context.secret);
212
+ if (sessionToken) {
213
+ await ctx.context.internalAdapter.deleteSession(sessionToken).catch(function (error) {
214
+ ctx.context.logger.error("Failed to delete stale session", error);
215
+ });
216
+ }
217
+ (0, import_cookies.deleteSessionCookie)(ctx);
218
+ var headers = new Headers();
219
+ var accumulated = ctx.responseHeaders;
220
+ accumulated === null || accumulated === void 0 ? void 0 : accumulated.getSetCookie().forEach(function (cookie) {
221
+ headers.append("set-cookie", cookie);
222
+ });
223
+ return new import_api.APIError("BAD_REQUEST", {
224
+ message: (body === null || body === void 0 ? void 0 : body.message) || "Failed to get a valid access token",
225
+ code: import_accessTokenRefresh.FAILED_TO_GET_ACCESS_TOKEN
226
+ }, headers);
227
+ })
228
+ }]
229
+ }
230
+ };
231
+ }
232
+ function createAuth() {
233
+ var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
234
+ var _options_plugins, _options_database, _options_sessionMaxAge;
235
+ var _options_keycloak, _options_keycloak1, _options_keycloak2, _options_keycloak3;
236
+ var baseUrl = options.baseUrl || process.env.BASE_URL || `http://localhost:${process.env.ONE_PORT || "3000"}`;
237
+ var isProduction = process.env.NODE_ENV === "production";
238
+ var keycloakBaseUrl = ((_options_keycloak = options.keycloak) === null || _options_keycloak === void 0 ? void 0 : _options_keycloak.baseUrl) || process.env.KEYCLOAK_BACKCHANNEL_URL || `${baseUrl}/auth`;
239
+ var keycloakRealm = ((_options_keycloak1 = options.keycloak) === null || _options_keycloak1 === void 0 ? void 0 : _options_keycloak1.realm) || process.env.KEYCLOAK_REALM || "master";
240
+ var issuer = `${keycloakBaseUrl}/realms/${keycloakRealm}`;
241
+ var keycloakClientId = ((_options_keycloak2 = options.keycloak) === null || _options_keycloak2 === void 0 ? void 0 : _options_keycloak2.clientId) || process.env.KEYCLOAK_CLIENT_ID || "";
242
+ var keycloakClientSecret = ((_options_keycloak3 = options.keycloak) === null || _options_keycloak3 === void 0 ? void 0 : _options_keycloak3.clientSecret) || process.env.KEYCLOAK_CLIENT_SECRET || "";
243
+ var expoPlugin = options.enableExpo !== false ? (0, import_expo.expo)() : void 0;
244
+ var basePath = options.basePath || "/api/auth";
245
+ var keycloakProviderConfig = {
246
+ ...(0, import_plugins.keycloak)({
247
+ clientId: keycloakClientId,
248
+ clientSecret: keycloakClientSecret,
249
+ issuer
250
+ }),
251
+ // Backchannel token/userinfo: `/get-access-token` refresh keeps these
252
+ // when discovery fails (Keycloak restart), so we don't depend on the
253
+ // well-known document coming up in the same instant as the token
254
+ // endpoint. Browser-facing authorize/issuer stay on the public /auth
255
+ // proxy (getters below).
256
+ tokenUrl: `${issuer}/protocol/openid-connect/token`,
257
+ userInfoUrl: `${issuer}/protocol/openid-connect/userinfo`,
258
+ // Wallet (SIWE-style) users authenticate by signature and have NO email —
259
+ // Keycloak issues them a username = wallet address and no email claim.
260
+ // better-auth's genericOAuth callback hard-rejects a user with no email
261
+ // ("email_is_missing"), so synthesize a stable, unique placeholder from the
262
+ // wallet address / subject. `.wallet` is a non-routable placeholder domain;
263
+ // the address stays the stable identity.
264
+ mapProfileToUser: function mapProfileToUser(profile) {
265
+ var _profile_email_verified;
266
+ var handle = profile.preferred_username || profile.sub || profile.id || profile.name;
267
+ var email = profile.email || (handle ? `${handle}@wallet` : void 0);
268
+ return {
269
+ ...profile,
270
+ email,
271
+ emailVerified: (_profile_email_verified = profile.email_verified) !== null && _profile_email_verified !== void 0 ? _profile_email_verified : true,
272
+ name: profile.name || handle
273
+ };
274
+ }
275
+ };
276
+ var keycloakPublicPath = function () {
277
+ try {
278
+ var path = new URL(keycloakBaseUrl).pathname.replace(/\/+$/, "");
279
+ return path && path !== "/" ? path : void 0;
280
+ } catch (unused) {
281
+ return void 0;
282
+ }
283
+ }();
284
+ var publicKeycloakBaseFor = function publicKeycloakBaseFor2(requestOrigin) {
285
+ if (!keycloakPublicPath) return keycloakBaseUrl;
286
+ try {
287
+ var url = new URL(baseUrl);
288
+ if (!isProduction && requestOrigin) {
289
+ url.hostname = new URL(requestOrigin).hostname;
290
+ }
291
+ return `${url.origin}${keycloakPublicPath}`;
292
+ } catch (unused) {
293
+ return void 0;
294
+ }
295
+ };
296
+ if (!isProduction) {
297
+ Object.defineProperty(keycloakProviderConfig, "redirectURI", {
298
+ enumerable: true,
299
+ get() {
300
+ var origin = requestOriginStorage.getStore();
301
+ return origin ? `${origin}${basePath}/oauth2/callback/keycloak` : void 0;
302
+ }
303
+ });
304
+ var keycloakPublicBase = function keycloakPublicBase2() {
305
+ var origin = requestOriginStorage.getStore();
306
+ if (!origin || !keycloakPublicPath) return void 0;
307
+ return publicKeycloakBaseFor(origin);
308
+ };
309
+ if (keycloakPublicPath) {
310
+ Object.defineProperty(keycloakProviderConfig, "authorizationUrl", {
311
+ enumerable: true,
312
+ get() {
313
+ var base = keycloakPublicBase();
314
+ return base ? `${base}/realms/${keycloakRealm}/protocol/openid-connect/auth` : void 0;
315
+ }
316
+ });
317
+ Object.defineProperty(keycloakProviderConfig, "issuer", {
318
+ enumerable: true,
319
+ get() {
320
+ var base = keycloakPublicBase();
321
+ return base ? `${base}/realms/${keycloakRealm}` : void 0;
322
+ }
323
+ });
324
+ }
325
+ }
326
+ var oauthPlugin = (0, import_plugins.genericOAuth)({
327
+ config: [keycloakProviderConfig]
328
+ });
329
+ var keycloakSsoPlugin = createKeycloakSsoPlugin({
330
+ realm: keycloakRealm,
331
+ clientId: keycloakClientId,
332
+ clientSecret: keycloakClientSecret,
333
+ issuer,
334
+ baseUrl,
335
+ publicKeycloakBaseFor
336
+ });
337
+ var plugins = [...(expoPlugin ? [expoPlugin] : []), oauthPlugin, keycloakSsoPlugin, ...((_options_plugins = options.plugins) !== null && _options_plugins !== void 0 ? _options_plugins : [])];
338
+ var database = (_options_database = options.database) !== null && _options_database !== void 0 ? _options_database : process.env.DATABASE_URL || void 0;
339
+ return (0, import_better_auth.betterAuth)({
340
+ basePath,
341
+ // Static on purpose: better-auth's dynamic `baseURL` config (allowedHosts)
342
+ // is not honored by the genericOAuth plugin — it pins redirect URIs at
343
+ // init time, which turned them relative and bounced callbacks to the
344
+ // Keycloak host. Dev multi-host support comes from the per-request
345
+ // redirectURI getter above + the LAN trustedOrigins below instead.
346
+ baseURL: baseUrl,
347
+ ...(database ? {
348
+ database
349
+ } : {}),
350
+ secret: options.secret || process.env.SECRET || "",
351
+ trustedOrigins: options.trustedOrigins || [baseUrl, keycloakBaseUrl,
352
+ // In dev, ONE_PORT may differ from BASE_URL; ensure the dev server origin is trusted.
353
+ ...(process.env.ONE_PORT && !baseUrl.includes(`:${process.env.ONE_PORT}`) ? [`http://localhost:${process.env.ONE_PORT}`] : []), "multiplatform-one://",
354
+ // Expo Go (dev) receives OAuth returns on the exp:// scheme — the app
355
+ // derives its callbackURL via Linking.createURL, which yields
356
+ // exp://<host>:<port>/--/ there. Never trusted in production builds.
357
+ // Dev also trusts private-network origins (see DEV_LAN_HOST_PATTERNS)
358
+ // so sign-in from a phone / the machine's LAN IP is not rejected.
359
+ ...(isProduction ? [] : ["exp://", ...DEV_LAN_HOST_PATTERNS.map(function (host) {
360
+ return `http://${host}`;
361
+ })])],
362
+ session: {
363
+ cookieCache: {
364
+ enabled: true,
365
+ maxAge: (_options_sessionMaxAge = options.sessionMaxAge) !== null && _options_sessionMaxAge !== void 0 ? _options_sessionMaxAge : 7 * 24 * 60 * 60,
366
+ strategy: "jwe",
367
+ refreshCache: true
368
+ }
369
+ },
370
+ account: {
371
+ storeStateStrategy: "cookie",
372
+ storeAccountCookie: true
373
+ },
374
+ plugins
375
+ });
376
+ }
377
+ function createAuthRouteHandler(auth) {
378
+ var handler = function handler2(req) {
379
+ var origin = deriveRequestOrigin(req);
380
+ return origin ? requestOriginStorage.run(origin, function () {
381
+ return auth.handler(req);
382
+ }) : auth.handler(req);
383
+ };
384
+ return {
385
+ GET: handler,
386
+ POST: handler
387
+ };
388
+ }
389
+ function createSessionHelpers(auth) {
390
+ async function getSession(req) {
391
+ return auth.api.getSession({
392
+ headers: req.headers
393
+ });
394
+ }
395
+ async function verifyAuth(req) {
396
+ var session = await auth.api.getSession({
397
+ headers: req.headers
398
+ });
399
+ if (!session) {
400
+ throw new Response("Unauthorized", {
401
+ status: 401
402
+ });
403
+ }
404
+ return session;
405
+ }
406
+ return {
407
+ verifyAuth,
408
+ getSession
409
+ };
410
+ }
411
+ //# sourceMappingURL=index.native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["__defProp","Object","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","__copyProps","to","from","except","desc","key","call","__toCommonJS","mod","value","index_exports","ACCESS_TOKEN_RETRY_DELAYS_MS","import_accessTokenRefresh2","FAILED_TO_GET_ACCESS_TOKEN","TOKEN_REFRESH_UNAVAILABLE","classifyAccessTokenResponse","createAuth","createAuthRouteHandler","createSessionHelpers","retryWhileTransient","watchDocumentVisible","module","exports","import_async_hooks","require","import_better_auth","import_api","import_cookies","import_plugins","import_expo","import_accessTokenRefresh","requestOriginStorage","AsyncLocalStorage","deriveRequestOrigin","req","isDevHost","isDevHost2","host","DEV_LAN_HOST_PATTERNS","some","pattern","matchesHostPattern","forwardedHost","headers","proto","originHeader","url","URL","origin","unused","createKeycloakSsoPlugin","options","realm","clientId","clientSecret","issuer","baseUrl","publicKeycloakBaseFor","tokenEndpoint","resolveVisitorOrigin","resolveVisitorOrigin2","request","_requestOriginStorage_getStore","getStore","isRefreshDefinitivelyDead","isRefreshDefinitivelyDead2","refreshToken","res","fetch","method","body","URLSearchParams","grant_type","refresh_token","client_id","client_secret","signal","AbortSignal","timeout","ok","status","json","catch","error","signOutSso","createAuthEndpoint","ctx","_resolveVisitorOrigin","_ref","visitorOrigin","searchParams","rawCallback","jsonMode","answer","answer2","redirect","callbackURL","postLogoutRedirect","startsWith","idTokenHint","sessionToken","getSignedCookie","context","authCookies","secret","session","getSessionFromCtx","_ref1","_accounts_find","accounts","internalAdapter","findAccounts","user","id","find","account","providerId","idToken","accountCookie","getAccountCookie","deleteSession","logger","deleteSessionCookie","keycloakBase","endSession","set","toString","endpoints","hooks","after","matcher","path","handler","createAuthMiddleware","_ctx_body","returned","isAPIError","code","definitive","APIError","message","warn","Headers","accumulated","responseHeaders","getSetCookie","forEach","cookie","append","arguments","length","_options_plugins","_options_database","_options_sessionMaxAge","_options_keycloak","_options_keycloak1","_options_keycloak2","_options_keycloak3","process","env","BASE_URL","ONE_PORT","isProduction","NODE_ENV","keycloakBaseUrl","keycloak","KEYCLOAK_BACKCHANNEL_URL","keycloakRealm","KEYCLOAK_REALM","keycloakClientId","KEYCLOAK_CLIENT_ID","keycloakClientSecret","KEYCLOAK_CLIENT_SECRET","expoPlugin","enableExpo","expo","basePath","keycloakProviderConfig","tokenUrl","userInfoUrl","mapProfileToUser","profile","_profile_email_verified","handle","preferred_username","sub","email","emailVerified","email_verified","keycloakPublicPath","pathname","replace","publicKeycloakBaseFor2","requestOrigin","hostname","keycloakPublicBase","keycloakPublicBase2","base","oauthPlugin","genericOAuth","config","keycloakSsoPlugin","plugins","database","DATABASE_URL","betterAuth","baseURL","SECRET"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "@multiplatform.one/auth",
3
+ "version": "7.7.2",
4
+ "description": "Better Auth helpers for multiplatform.one apps with Keycloak",
5
+ "keywords": [
6
+ "auth",
7
+ "better-auth",
8
+ "keycloak",
9
+ "onestack"
10
+ ],
11
+ "homepage": "https://multiplatform.one",
12
+ "license": "Apache-2.0",
13
+ "author": "BitSpur",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://gitlab.com/bitspur/frappe/multiplatform.one.git",
17
+ "directory": "public/auth"
18
+ },
19
+ "source": "src/index.ts",
20
+ "files": [
21
+ "dist",
22
+ "src",
23
+ "types"
24
+ ],
25
+ "sideEffects": false,
26
+ "main": "src/index.ts",
27
+ "module": "src/index.ts",
28
+ "types": "src/index.ts",
29
+ "exports": {
30
+ "./package.json": "./package.json",
31
+ ".": {
32
+ "source": "./src/index.ts",
33
+ "types": "./src/index.ts",
34
+ "import": "./dist/esm/index.mjs",
35
+ "require": "./dist/cjs/index.cjs",
36
+ "default": "./src/index.ts"
37
+ },
38
+ "./access-token": {
39
+ "source": "./src/accessTokenRefresh.ts",
40
+ "types": "./src/accessTokenRefresh.ts",
41
+ "import": "./src/accessTokenRefresh.ts",
42
+ "require": "./src/accessTokenRefresh.ts",
43
+ "default": "./src/accessTokenRefresh.ts"
44
+ }
45
+ },
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "scripts": {
50
+ "build": "rm -rf dist types 2>/dev/null && tamagui-build --ts-project ./tsconfig.build.json",
51
+ "test": "vitest run --coverage --coverage.provider=v8 --coverage.reporter=text --coverage.reporter=lcov --coverage.reporter=html",
52
+ "typecheck": "tsgo --noEmit"
53
+ },
54
+ "devDependencies": {
55
+ "@better-auth/expo": "^1.6.9",
56
+ "@multiplatform.one/config": "7.7.2",
57
+ "@multiplatform.one/test-utils": "7.7.2",
58
+ "@tamagui/build": "2.7.6",
59
+ "@vitest/coverage-v8": "^4.1.5",
60
+ "better-auth": "^1.6.9",
61
+ "typescript": "~5.9.3",
62
+ "vitest": "^4.1.5"
63
+ },
64
+ "peerDependencies": {
65
+ "@better-auth/expo": "^1.4.0",
66
+ "@multiplatform.one/wallet": "7.7.2",
67
+ "better-auth": "^1.4.0"
68
+ },
69
+ "peerDependenciesMeta": {
70
+ "@multiplatform.one/wallet": {
71
+ "optional": true
72
+ }
73
+ },
74
+ "engines": {
75
+ "node": ">=18.0.0"
76
+ },
77
+ "module:jsx": "dist/jsx"
78
+ }
@@ -0,0 +1,80 @@
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
+
16
+ export const FAILED_TO_GET_ACCESS_TOKEN = "FAILED_TO_GET_ACCESS_TOKEN";
17
+ export const TOKEN_REFRESH_UNAVAILABLE = "TOKEN_REFRESH_UNAVAILABLE";
18
+
19
+ export type AccessTokenFailureKind = "signed-out" | "transient";
20
+
21
+ /** First attempt is immediate; later attempts wait out a Keycloak bounce. */
22
+ export const ACCESS_TOKEN_RETRY_DELAYS_MS = [0, 400, 1000] as const;
23
+
24
+ export function classifyAccessTokenResponse(
25
+ status: number,
26
+ body?: { code?: string } | null,
27
+ ): AccessTokenFailureKind {
28
+ if (status === 401 || status === 403) return "signed-out";
29
+ if (status === 400 && body?.code === FAILED_TO_GET_ACCESS_TOKEN) return "signed-out";
30
+ return "transient";
31
+ }
32
+
33
+ export type RetryAttemptResult<T> =
34
+ | { ok: true; value: T }
35
+ | { ok: false; kind: AccessTokenFailureKind };
36
+
37
+ /**
38
+ * Retry an access-token fetch while the failure is transient (Keycloak
39
+ * restart, 5xx, network). A definitive signed-out answer stops immediately
40
+ * so we never hammer a revoked session.
41
+ */
42
+ export async function retryWhileTransient<T>(
43
+ attempt: () => Promise<RetryAttemptResult<T>>,
44
+ opts?: {
45
+ delaysMs?: readonly number[];
46
+ sleep?: (ms: number) => Promise<void>;
47
+ },
48
+ ): Promise<RetryAttemptResult<T>> {
49
+ const delays = opts?.delaysMs ?? ACCESS_TOKEN_RETRY_DELAYS_MS;
50
+ const sleep = opts?.sleep ?? ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms)));
51
+ let last: RetryAttemptResult<T> = { ok: false, kind: "transient" };
52
+ for (let i = 0; i < delays.length; i++) {
53
+ const wait = delays[i];
54
+ if (wait) await sleep(wait);
55
+ last = await attempt();
56
+ if (last.ok) return last;
57
+ if (last.kind === "signed-out") return last;
58
+ }
59
+ return last;
60
+ }
61
+
62
+ /**
63
+ * Revalidate when the tab becomes visible again (GitHub / Linear / Figma
64
+ * style: a backgrounded tab notices IdP logout or a recovered Keycloak
65
+ * without a full reload). Returns an unsubscribe. No-op on the server.
66
+ */
67
+ export function watchDocumentVisible(revalidate: () => void): () => void {
68
+ if (typeof document === "undefined" || typeof window === "undefined") {
69
+ return () => {};
70
+ }
71
+ const onVisible = () => {
72
+ if (document.visibilityState === "visible") revalidate();
73
+ };
74
+ document.addEventListener("visibilitychange", onVisible);
75
+ window.addEventListener("focus", onVisible);
76
+ return () => {
77
+ document.removeEventListener("visibilitychange", onVisible);
78
+ window.removeEventListener("focus", onVisible);
79
+ };
80
+ }