@motherbase/client 2.2.1 → 2.2.3
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/COMPATIBILITY.md +157 -0
- package/LICENSE +21 -21
- package/README.md +52 -4
- package/dist/admin/auth-admin-client.d.ts +43 -0
- package/dist/admin/auth-admin-client.d.ts.map +1 -0
- package/dist/admin/auth-admin-client.js +62 -0
- package/dist/admin/auth-admin-client.js.map +1 -0
- package/dist/admin/auth-admin-mfa-client.d.ts +22 -0
- package/dist/admin/auth-admin-mfa-client.d.ts.map +1 -0
- package/dist/admin/auth-admin-mfa-client.js +17 -0
- package/dist/admin/auth-admin-mfa-client.js.map +1 -0
- package/dist/admin/types.d.ts +85 -0
- package/dist/admin/types.d.ts.map +1 -0
- package/dist/admin/types.js +3 -0
- package/dist/admin/types.js.map +1 -0
- package/dist/auth/constants.d.ts +21 -0
- package/dist/auth/constants.d.ts.map +1 -0
- package/dist/auth/constants.js +34 -0
- package/dist/auth/constants.js.map +1 -0
- package/dist/auth/index.d.ts +5 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +34 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/motherbase-plugin.d.ts +6 -0
- package/dist/auth/motherbase-plugin.d.ts.map +1 -0
- package/dist/auth/motherbase-plugin.js +80 -0
- package/dist/auth/motherbase-plugin.js.map +1 -0
- package/dist/auth/pkce.d.ts +19 -0
- package/dist/auth/pkce.d.ts.map +1 -0
- package/dist/auth/pkce.js +89 -0
- package/dist/auth/pkce.js.map +1 -0
- package/dist/auth/session-utils.d.ts +29 -0
- package/dist/auth/session-utils.d.ts.map +1 -0
- package/dist/auth/session-utils.js +123 -0
- package/dist/auth/session-utils.js.map +1 -0
- package/dist/auth/session.d.ts +51 -0
- package/dist/auth/session.d.ts.map +1 -0
- package/dist/auth/session.js +161 -0
- package/dist/auth/session.js.map +1 -0
- package/dist/auth/types.d.ts +341 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +2 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/auth/utils.d.ts +28 -0
- package/dist/auth/utils.d.ts.map +1 -0
- package/dist/auth/utils.js +70 -0
- package/dist/auth/utils.js.map +1 -0
- package/dist/auth.d.ts +3 -2
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +27 -11
- package/dist/auth.js.map +1 -1
- package/dist/channel.d.ts +11 -0
- package/dist/channel.d.ts.map +1 -1
- package/dist/channel.js +26 -2
- package/dist/channel.js.map +1 -1
- package/dist/cookies/cookie-storage.d.ts +12 -0
- package/dist/cookies/cookie-storage.d.ts.map +1 -0
- package/dist/cookies/cookie-storage.js +35 -0
- package/dist/cookies/cookie-storage.js.map +1 -0
- package/dist/cookies/index.d.ts +5 -0
- package/dist/cookies/index.d.ts.map +1 -0
- package/dist/cookies/index.js +5 -0
- package/dist/cookies/index.js.map +1 -0
- package/dist/cookies/server-cookie-storage.d.ts +20 -0
- package/dist/cookies/server-cookie-storage.d.ts.map +1 -0
- package/dist/cookies/server-cookie-storage.js +60 -0
- package/dist/cookies/server-cookie-storage.js.map +1 -0
- package/dist/cookies/types.d.ts +33 -0
- package/dist/cookies/types.d.ts.map +1 -0
- package/dist/cookies/types.js +8 -0
- package/dist/cookies/types.js.map +1 -0
- package/dist/cookies/utils.d.ts +23 -0
- package/dist/cookies/utils.d.ts.map +1 -0
- package/dist/cookies/utils.js +67 -0
- package/dist/cookies/utils.js.map +1 -0
- package/dist/database/database.d.ts +197 -0
- package/dist/database/database.d.ts.map +1 -0
- package/dist/database/database.js +2 -0
- package/dist/database/database.js.map +1 -0
- package/dist/database/facade.d.ts +144 -0
- package/dist/database/facade.d.ts.map +1 -0
- package/dist/database/facade.js +147 -0
- package/dist/database/facade.js.map +1 -0
- package/dist/database/query.d.ts +97 -0
- package/dist/database/query.d.ts.map +1 -0
- package/dist/database/query.js +94 -0
- package/dist/database/query.js.map +1 -0
- package/dist/database/types.d.ts +314 -0
- package/dist/database/types.d.ts.map +1 -0
- package/dist/database/types.js +2 -0
- package/dist/database/types.js.map +1 -0
- package/dist/functions/errors.d.ts +28 -0
- package/dist/functions/errors.d.ts.map +1 -0
- package/dist/functions/errors.js +37 -0
- package/dist/functions/errors.js.map +1 -0
- package/dist/functions/index.d.ts +9 -0
- package/dist/functions/index.d.ts.map +1 -0
- package/dist/functions/index.js +40 -0
- package/dist/functions/index.js.map +1 -0
- package/dist/functions/types.d.ts +25 -0
- package/dist/functions/types.d.ts.map +1 -0
- package/dist/functions/types.js +2 -0
- package/dist/functions/types.js.map +1 -0
- package/dist/http/backend-error.d.ts +17 -0
- package/dist/http/backend-error.d.ts.map +1 -0
- package/dist/http/backend-error.js +11 -0
- package/dist/http/backend-error.js.map +1 -0
- package/dist/http/index.d.ts +59 -0
- package/dist/http/index.d.ts.map +1 -0
- package/dist/http/index.js +175 -0
- package/dist/http/index.js.map +1 -0
- package/dist/http/types.d.ts +45 -0
- package/dist/http/types.d.ts.map +1 -0
- package/dist/http/types.js +2 -0
- package/dist/http/types.js.map +1 -0
- package/dist/http/utils.d.ts +14 -0
- package/dist/http/utils.d.ts.map +1 -0
- package/dist/http/utils.js +37 -0
- package/dist/http/utils.js.map +1 -0
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +2 -1
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +47 -77
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +58 -73
- package/dist/index.js.map +1 -1
- package/dist/pkce.js +4 -4
- package/dist/postgrest/index.d.ts +4 -0
- package/dist/postgrest/index.d.ts.map +1 -0
- package/dist/postgrest/index.js +4 -0
- package/dist/postgrest/index.js.map +1 -0
- package/dist/postgrest/query-builder.d.ts +224 -0
- package/dist/postgrest/query-builder.d.ts.map +1 -0
- package/dist/postgrest/query-builder.js +544 -0
- package/dist/postgrest/query-builder.js.map +1 -0
- package/dist/postgrest/rpc.d.ts +12 -0
- package/dist/postgrest/rpc.d.ts.map +1 -0
- package/dist/postgrest/rpc.js +42 -0
- package/dist/postgrest/rpc.js.map +1 -0
- package/dist/postgrest/types.d.ts +88 -0
- package/dist/postgrest/types.d.ts.map +1 -0
- package/dist/postgrest/types.js +2 -0
- package/dist/postgrest/types.js.map +1 -0
- package/dist/postgrest/utils.d.ts +23 -0
- package/dist/postgrest/utils.d.ts.map +1 -0
- package/dist/postgrest/utils.js +87 -0
- package/dist/postgrest/utils.js.map +1 -0
- package/dist/postgrest.d.ts +5 -1
- package/dist/postgrest.d.ts.map +1 -1
- package/dist/postgrest.js +17 -10
- package/dist/postgrest.js.map +1 -1
- package/dist/realtime/channel.d.ts +83 -0
- package/dist/realtime/channel.d.ts.map +1 -0
- package/dist/realtime/channel.js +240 -0
- package/dist/realtime/channel.js.map +1 -0
- package/dist/realtime/index.d.ts +94 -0
- package/dist/realtime/index.d.ts.map +1 -0
- package/dist/realtime/index.js +455 -0
- package/dist/realtime/index.js.map +1 -0
- package/dist/realtime/types.d.ts +120 -0
- package/dist/realtime/types.d.ts.map +1 -0
- package/dist/realtime/types.js +2 -0
- package/dist/realtime/types.js.map +1 -0
- package/dist/realtime.d.ts +1 -0
- package/dist/realtime.d.ts.map +1 -1
- package/dist/realtime.js +26 -1
- package/dist/realtime.js.map +1 -1
- package/dist/runtime.d.ts +13 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +15 -0
- package/dist/runtime.js.map +1 -0
- package/dist/session.d.ts +2 -0
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +11 -2
- package/dist/session.js.map +1 -1
- package/dist/storage/bucket.d.ts +166 -0
- package/dist/storage/bucket.d.ts.map +1 -0
- package/dist/storage/bucket.js +294 -0
- package/dist/storage/bucket.js.map +1 -0
- package/dist/storage/index.d.ts +45 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +55 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/types.d.ts +131 -0
- package/dist/storage/types.d.ts.map +1 -0
- package/dist/storage/types.js +2 -0
- package/dist/storage/types.js.map +1 -0
- package/dist/storage/utils.d.ts +27 -0
- package/dist/storage/utils.d.ts.map +1 -0
- package/dist/storage/utils.js +43 -0
- package/dist/storage/utils.js.map +1 -0
- package/dist/test.d.ts +2 -0
- package/dist/test.d.ts.map +1 -0
- package/dist/test.js +3 -0
- package/dist/test.js.map +1 -0
- package/dist/types.d.ts +14 -249
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/compat.d.ts +40 -0
- package/dist/utils/compat.d.ts.map +1 -0
- package/dist/utils/compat.js +100 -0
- package/dist/utils/compat.js.map +1 -0
- package/dist/utils/runtime.d.ts +13 -0
- package/dist/utils/runtime.d.ts.map +1 -0
- package/dist/utils/runtime.js +15 -0
- package/dist/utils/runtime.js.map +1 -0
- package/dist/utils/testing.d.ts +38 -0
- package/dist/utils/testing.d.ts.map +1 -0
- package/dist/utils/testing.js +50 -0
- package/dist/utils/testing.js.map +1 -0
- package/dist/utils/warn.d.ts +2 -0
- package/dist/utils/warn.d.ts.map +1 -0
- package/dist/utils/warn.js +23 -0
- package/dist/utils/warn.js.map +1 -0
- package/package.json +13 -11
- package/dist/devices.d.ts +0 -13
- package/dist/devices.d.ts.map +0 -1
- package/dist/devices.js +0 -13
- package/dist/devices.js.map +0 -1
- package/dist/profile.d.ts +0 -16
- package/dist/profile.d.ts.map +0 -1
- package/dist/profile.js +0 -26
- package/dist/profile.js.map +0 -1
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export const EVENT_MAP = {
|
|
2
|
+
signIn: 'SIGNED_IN',
|
|
3
|
+
signOut: 'SIGNED_OUT',
|
|
4
|
+
tokenRefreshed: 'TOKEN_REFRESHED',
|
|
5
|
+
userUpdated: 'USER_UPDATED',
|
|
6
|
+
mfaVerified: 'MFA_CHALLENGE_VERIFIED',
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Endpoints whose next step needs a cookie set on the response: the OAuth
|
|
10
|
+
* state, the WebAuthn challenge, or the pending second factor a password
|
|
11
|
+
* sign-in leaves for `twoFactor.verify*`. Cross-origin, fetch only keeps and
|
|
12
|
+
* resends a cookie with `credentials: 'include'`. Everything else stays
|
|
13
|
+
* `same-origin`, so a backend that does not allow credentialed CORS still
|
|
14
|
+
* serves it.
|
|
15
|
+
*/
|
|
16
|
+
export const COOKIE_PATHS = [
|
|
17
|
+
'/sign-in/email',
|
|
18
|
+
'/sign-in/phone-number',
|
|
19
|
+
'/two-factor/',
|
|
20
|
+
'/sign-in/social',
|
|
21
|
+
'/sign-in/sso',
|
|
22
|
+
'/link-social',
|
|
23
|
+
'/passkey/',
|
|
24
|
+
];
|
|
25
|
+
/** Sign-ins that come back through the server's OAuth callback, where the PKCE challenge rides. */
|
|
26
|
+
export const REDIRECT_SIGN_IN_PATHS = ['/sign-in/social', '/sign-in/sso'];
|
|
27
|
+
/** Calls after which the session this client holds no longer exists. */
|
|
28
|
+
export const SIGN_OUT_PATHS = new Set(['/sign-out', '/revoke-sessions']);
|
|
29
|
+
/**
|
|
30
|
+
* Calls that change the user but answer without it (`{ status: true }`): the
|
|
31
|
+
* session is read again after them, so the stored user and USER_UPDATED follow.
|
|
32
|
+
*/
|
|
33
|
+
export const USER_CHANGE_PATHS = new Set(['/update-user', '/change-email', '/update-user-credentials', '/two-factor/disable']);
|
|
34
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/auth/constants.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,SAAS,GAAuC;IAC3D,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,YAAY;IACrB,cAAc,EAAE,iBAAiB;IACjC,WAAW,EAAE,cAAc;IAC3B,WAAW,EAAE,wBAAwB;CACtC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,gBAAgB;IAChB,uBAAuB;IACvB,cAAc;IACd,iBAAiB;IACjB,cAAc;IACd,cAAc;IACd,WAAW;CACZ,CAAC;AAEF,mGAAmG;AACnG,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC;AAE1E,wEAAwE;AACxE,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC,CAAC;AAEzE;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,eAAe,EAAE,0BAA0B,EAAE,qBAAqB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { HttpClient } from '../http/index.js';
|
|
2
|
+
import { SessionStore } from './session.js';
|
|
3
|
+
import type { AuthClient, AuthClientOptions } from './types.js';
|
|
4
|
+
export declare function createAuthClient(http: HttpClient, store: SessionStore, options: AuthClientOptions): AuthClient;
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAe,MAAM,YAAY,CAAC;AAE7E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,iBAAiB,GAAG,UAAU,CAwB9G"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { createAuthClient as createBetterAuthClient } from 'better-auth/client';
|
|
2
|
+
import { anonymousClient, emailOTPClient, jwtClient, magicLinkClient, organizationClient, phoneNumberClient, twoFactorClient } from 'better-auth/client/plugins';
|
|
3
|
+
import { apiKeyClient } from '@better-auth/api-key/client';
|
|
4
|
+
import { passkeyClient } from '@better-auth/passkey/client';
|
|
5
|
+
import { ssoClient } from '@better-auth/sso/client';
|
|
6
|
+
import { HTTP_ROUTES } from '@motherbase/contracts';
|
|
7
|
+
import { withoutTrailingSlash } from '../http/utils.js';
|
|
8
|
+
import { motherbaseClient } from './motherbase-plugin.js';
|
|
9
|
+
export function createAuthClient(http, store, options) {
|
|
10
|
+
// Must stay in step with `AuthPlugins`; the annotation makes the compiler check it.
|
|
11
|
+
const plugins = [
|
|
12
|
+
anonymousClient(),
|
|
13
|
+
emailOTPClient(),
|
|
14
|
+
magicLinkClient(),
|
|
15
|
+
phoneNumberClient(),
|
|
16
|
+
twoFactorClient(),
|
|
17
|
+
organizationClient({ teams: { enabled: true } }),
|
|
18
|
+
jwtClient(),
|
|
19
|
+
passkeyClient(),
|
|
20
|
+
ssoClient(),
|
|
21
|
+
apiKeyClient(),
|
|
22
|
+
motherbaseClient(http, store, options),
|
|
23
|
+
];
|
|
24
|
+
return createBetterAuthClient({
|
|
25
|
+
baseURL: `${withoutTrailingSlash(options.url)}${HTTP_ROUTES.auth}`,
|
|
26
|
+
fetchOptions: {
|
|
27
|
+
customFetchImpl: http.observedFetch(options.fetch),
|
|
28
|
+
headers: options.headers,
|
|
29
|
+
auth: { type: 'Bearer', token: async () => (await store.hydrate())?.accessToken },
|
|
30
|
+
},
|
|
31
|
+
plugins,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,IAAI,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,SAAS,EAAE,eAAe,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AACjK,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAI1D,MAAM,UAAU,gBAAgB,CAAC,IAAgB,EAAE,KAAmB,EAAE,OAA0B;IAChG,oFAAoF;IACpF,MAAM,OAAO,GAAgB;QAC3B,eAAe,EAAE;QACjB,cAAc,EAAE;QAChB,eAAe,EAAE;QACjB,iBAAiB,EAAE;QACnB,eAAe,EAAE;QACjB,kBAAkB,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;QAChD,SAAS,EAAE;QACX,aAAa,EAAE;QACf,SAAS,EAAE;QACX,YAAY,EAAE;QACd,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC;KACvC,CAAC;IACF,OAAO,sBAAsB,CAAC;QAC5B,OAAO,EAAE,GAAG,oBAAoB,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,IAAI,EAAE;QAClE,YAAY,EAAE;YACZ,eAAe,EAAE,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC;YAClD,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE;SAClF;QACD,OAAO;KACR,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { HttpClient } from "../http/index.js";
|
|
2
|
+
import { SessionStore } from "./session.js";
|
|
3
|
+
import { AuthClientOptions, MotherbaseClientPlugin } from "./types.js";
|
|
4
|
+
/** Motherbase's additions, as a Better Auth client plugin. */
|
|
5
|
+
export declare function motherbaseClient(http: HttpClient, store: SessionStore, options: AuthClientOptions): MotherbaseClientPlugin;
|
|
6
|
+
//# sourceMappingURL=motherbase-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"motherbase-plugin.d.ts","sourceRoot":"","sources":["../../src/auth/motherbase-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C,OAAO,EAAG,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAMxE,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,iBAAiB,GAAG,sBAAsB,CAwE1H"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { isBrowser } from "../utils/runtime.js";
|
|
2
|
+
import { EVENT_MAP } from "./constants.js";
|
|
3
|
+
import { adminActions, readAccessTokenFromUrl } from "./utils.js";
|
|
4
|
+
import { currentSession, sameSession, sessionFromResponse, sessionSync } from "./session-utils.js";
|
|
5
|
+
/** Motherbase's additions, as a Better Auth client plugin. */
|
|
6
|
+
export function motherbaseClient(http, store, options) {
|
|
7
|
+
// Bound when Better Auth hands over its fetch, which happens as the client
|
|
8
|
+
// is built, before any request can reach the session sync.
|
|
9
|
+
let revalidate = async () => undefined;
|
|
10
|
+
return {
|
|
11
|
+
id: 'motherbase',
|
|
12
|
+
fetchPlugins: [sessionSync(store, options, () => revalidate())],
|
|
13
|
+
getActions: $fetch => {
|
|
14
|
+
revalidate = () => $fetch('/get-session');
|
|
15
|
+
return {
|
|
16
|
+
onAuthStateChange(callback) {
|
|
17
|
+
let active = true;
|
|
18
|
+
const unsubscribe = store.subscribe((event, session) => {
|
|
19
|
+
if (active)
|
|
20
|
+
callback(EVENT_MAP[event], session);
|
|
21
|
+
});
|
|
22
|
+
void store.hydrate().then(session => {
|
|
23
|
+
if (active)
|
|
24
|
+
callback('INITIAL_SESSION', session);
|
|
25
|
+
});
|
|
26
|
+
return { data: { subscription: { unsubscribe: () => { active = false; unsubscribe(); } } } };
|
|
27
|
+
},
|
|
28
|
+
async getSessionFromUrl(href) {
|
|
29
|
+
const url = href ?? (isBrowser() ? window.location.href : undefined);
|
|
30
|
+
const found = url ? readAccessTokenFromUrl(url) : null;
|
|
31
|
+
if (!found)
|
|
32
|
+
return { data: null, error: null };
|
|
33
|
+
// Strip the token before the network call: a failed lookup must not
|
|
34
|
+
// leave a usable token in the address bar or the history.
|
|
35
|
+
if (!href && isBrowser()) {
|
|
36
|
+
window.history?.replaceState?.(window.history.state, '', found.cleanedHref);
|
|
37
|
+
}
|
|
38
|
+
// Checked before it is stored, so a rejected token never emits
|
|
39
|
+
// SIGNED_IN. On success, sessionSync adopts it from the response.
|
|
40
|
+
const { data, error } = await $fetch('/get-session', { auth: { type: 'Bearer', token: found.accessToken } });
|
|
41
|
+
if (error)
|
|
42
|
+
return { data: null, error };
|
|
43
|
+
const verified = sessionFromResponse(data);
|
|
44
|
+
if (!verified || !sameSession(verified.token, found.accessToken)
|
|
45
|
+
|| !sameSession(store.get()?.accessToken, verified.token)) {
|
|
46
|
+
return { data: null, error: { message: 'The session in the URL is no longer valid.' } };
|
|
47
|
+
}
|
|
48
|
+
return currentSession(store) ?? { data: null, error: { message: 'The session in the URL is no longer valid.' } };
|
|
49
|
+
},
|
|
50
|
+
async exchangeCodeForSession(authCode) {
|
|
51
|
+
const verifier = await options.verifiers.get();
|
|
52
|
+
if (!verifier) {
|
|
53
|
+
return { data: null, error: { message: 'No PKCE code verifier found: start the sign-in with flowType: "pkce" in this browser.' } };
|
|
54
|
+
}
|
|
55
|
+
const { data, error } = await $fetch('/exchange-code', {
|
|
56
|
+
method: 'POST',
|
|
57
|
+
body: { auth_code: authCode, code_verifier: verifier },
|
|
58
|
+
});
|
|
59
|
+
if (error)
|
|
60
|
+
return { data: null, error };
|
|
61
|
+
const verified = sessionFromResponse(data);
|
|
62
|
+
if (!verified || !sameSession(store.get()?.accessToken, verified.token)) {
|
|
63
|
+
return { data: null, error: { message: 'The code did not produce a session.' } };
|
|
64
|
+
}
|
|
65
|
+
await options.verifiers.clear();
|
|
66
|
+
return currentSession(store) ?? { data: null, error: { message: 'The code did not produce a session.' } };
|
|
67
|
+
},
|
|
68
|
+
// Better Auth 1.7 serves custom OAuth providers through signIn.social;
|
|
69
|
+
// kept so apps calling the 1.6 genericOAuthClient spelling keep working.
|
|
70
|
+
signIn: {
|
|
71
|
+
oauth2: ({ providerId, ...params }) => $fetch('/sign-in/social', { method: 'POST', body: { provider: providerId, ...params } }),
|
|
72
|
+
},
|
|
73
|
+
reauthenticate: () => $fetch('/reauthenticate', { method: 'POST' }),
|
|
74
|
+
updateUserCredentials: params => $fetch('/update-user-credentials', { method: 'POST', body: params }),
|
|
75
|
+
admin: adminActions(http),
|
|
76
|
+
};
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=motherbase-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"motherbase-plugin.js","sourceRoot":"","sources":["../../src/auth/motherbase-plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { KeyValueStorageAdapter } from './types.js';
|
|
2
|
+
/** 56 unreserved characters (RFC 7636 allows 43 to 128). */
|
|
3
|
+
export declare function generateCodeVerifier(): string;
|
|
4
|
+
export declare function codeChallengeFor(verifier: string): Promise<string>;
|
|
5
|
+
/** Append the challenge to the redirect URL, which is where the server looks for it. */
|
|
6
|
+
export declare function withCodeChallenge(redirectTo: string, challenge: string): string;
|
|
7
|
+
export interface VerifierStore {
|
|
8
|
+
get(): Promise<string | null>;
|
|
9
|
+
set(verifier: string): Promise<void>;
|
|
10
|
+
clear(): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The callback URL a PKCE sign-in should use: the given one, or this page, with
|
|
14
|
+
* a fresh challenge on it. The verifier waits in `verifiers` for
|
|
15
|
+
* `exchangeCodeForSession`.
|
|
16
|
+
*/
|
|
17
|
+
export declare function pkceCallback(callbackURL: string | undefined, verifiers: VerifierStore): Promise<string>;
|
|
18
|
+
export declare function verifierStore(storageKey: string, storage?: KeyValueStorageAdapter): VerifierStore;
|
|
19
|
+
//# sourceMappingURL=pkce.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pkce.d.ts","sourceRoot":"","sources":["../../src/auth/pkce.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAsBzD,4DAA4D;AAC5D,wBAAgB,oBAAoB,IAAI,MAAM,CAG7C;AAED,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGxE;AAED,wFAAwF;AACxF,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAM/E;AAED,MAAM,WAAW,aAAa;IAC1B,GAAG,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC9B,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAWD;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,SAAS,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAM7G;AAED,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,aAAa,CAuBjG"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { browserLocalStorage } from './session.js';
|
|
2
|
+
import { isBrowser } from '../utils/runtime.js';
|
|
3
|
+
/**
|
|
4
|
+
* The client half of the PKCE flow (`flowType: 'pkce'`).
|
|
5
|
+
*
|
|
6
|
+
* `signIn.social` (and `signIn.sso`) makes a verifier, keeps it, and sends
|
|
7
|
+
* only its SHA-256 challenge on the redirect URL. The provider callback comes
|
|
8
|
+
* back with `?code=`, and `exchangeCodeForSession(code)` proves possession of
|
|
9
|
+
* the verifier to get the session. The verifier has to outlive a full-page
|
|
10
|
+
* navigation, so it lives in the key/value storage the app passed, or in
|
|
11
|
+
* localStorage, the way supabase-js keeps `<storageKey>-code-verifier`.
|
|
12
|
+
*/
|
|
13
|
+
const VERIFIER_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';
|
|
14
|
+
function base64Url(bytes) {
|
|
15
|
+
let binary = '';
|
|
16
|
+
for (const byte of bytes)
|
|
17
|
+
binary += String.fromCharCode(byte);
|
|
18
|
+
return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
19
|
+
}
|
|
20
|
+
/** 56 unreserved characters (RFC 7636 allows 43 to 128). */
|
|
21
|
+
export function generateCodeVerifier() {
|
|
22
|
+
const bytes = crypto.getRandomValues(new Uint8Array(56));
|
|
23
|
+
return Array.from(bytes, b => VERIFIER_ALPHABET[b % VERIFIER_ALPHABET.length]).join('');
|
|
24
|
+
}
|
|
25
|
+
export async function codeChallengeFor(verifier) {
|
|
26
|
+
const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier));
|
|
27
|
+
return base64Url(new Uint8Array(digest));
|
|
28
|
+
}
|
|
29
|
+
/** Append the challenge to the redirect URL, which is where the server looks for it. */
|
|
30
|
+
export function withCodeChallenge(redirectTo, challenge) {
|
|
31
|
+
const hash = redirectTo.indexOf('#');
|
|
32
|
+
const base = hash === -1 ? redirectTo : redirectTo.slice(0, hash);
|
|
33
|
+
const fragment = hash === -1 ? '' : redirectTo.slice(hash);
|
|
34
|
+
const separator = base.includes('?') ? '&' : '?';
|
|
35
|
+
return `${base}${separator}code_challenge=${encodeURIComponent(challenge)}&code_challenge_method=s256${fragment}`;
|
|
36
|
+
}
|
|
37
|
+
function inMemory() {
|
|
38
|
+
const values = new Map();
|
|
39
|
+
return {
|
|
40
|
+
getItem: key => values.get(key) ?? null,
|
|
41
|
+
setItem: (key, value) => void values.set(key, value),
|
|
42
|
+
removeItem: key => void values.delete(key),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The callback URL a PKCE sign-in should use: the given one, or this page, with
|
|
47
|
+
* a fresh challenge on it. The verifier waits in `verifiers` for
|
|
48
|
+
* `exchangeCodeForSession`.
|
|
49
|
+
*/
|
|
50
|
+
export async function pkceCallback(callbackURL, verifiers) {
|
|
51
|
+
const target = callbackURL ?? (isBrowser() ? window.location.href.split('#')[0] : undefined);
|
|
52
|
+
if (!target)
|
|
53
|
+
throw new Error('flowType "pkce" needs a callbackURL outside a browser.');
|
|
54
|
+
const verifier = generateCodeVerifier();
|
|
55
|
+
await verifiers.set(verifier);
|
|
56
|
+
return withCodeChallenge(target, await codeChallengeFor(verifier));
|
|
57
|
+
}
|
|
58
|
+
export function verifierStore(storageKey, storage) {
|
|
59
|
+
const backing = storage ?? browserLocalStorage() ?? inMemory();
|
|
60
|
+
// The default localStorage can throw (blocked site data, quota); the verifier
|
|
61
|
+
// then lives in memory, which still serves a same-page exchange.
|
|
62
|
+
const fallback = inMemory();
|
|
63
|
+
const key = `${storageKey}-code-verifier`;
|
|
64
|
+
return {
|
|
65
|
+
get: async () => {
|
|
66
|
+
try {
|
|
67
|
+
return (await backing.getItem(key)) ?? (await fallback.getItem(key)) ?? null;
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return (await fallback.getItem(key)) ?? null;
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
set: async (verifier) => {
|
|
74
|
+
await fallback.setItem(key, verifier);
|
|
75
|
+
try {
|
|
76
|
+
await backing.setItem(key, verifier);
|
|
77
|
+
}
|
|
78
|
+
catch { /* memory only */ }
|
|
79
|
+
},
|
|
80
|
+
clear: async () => {
|
|
81
|
+
await fallback.removeItem(key);
|
|
82
|
+
try {
|
|
83
|
+
await backing.removeItem(key);
|
|
84
|
+
}
|
|
85
|
+
catch { /* nothing persisted */ }
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=pkce.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pkce.js","sourceRoot":"","sources":["../../src/auth/pkce.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { BetterFetchPlugin } from "@better-fetch/fetch";
|
|
2
|
+
import { SessionStore } from "./session.js";
|
|
3
|
+
import type { AuthClientOptions, AuthPayload, SessionResult } from "./types.js";
|
|
4
|
+
/**
|
|
5
|
+
* The session a successful auth response carries, if any.
|
|
6
|
+
*
|
|
7
|
+
* Better Auth answers a sign-in with `{ token, user }` (password, OTP, anonymous,
|
|
8
|
+
* id token, second factor) or `{ session: { token }, user }` (passkey,
|
|
9
|
+
* get-session). A `user` is required alongside: the jwt plugin's `/token`
|
|
10
|
+
* answers `{ token }` with a JWT, which is not a session.
|
|
11
|
+
*/
|
|
12
|
+
export declare function sessionFromResponse(data: unknown): AuthPayload | null;
|
|
13
|
+
/**
|
|
14
|
+
* Whether two tokens name the same session. The bearer the server hands out
|
|
15
|
+
* (`set-auth-token`, the OAuth fragment) is the signed cookie value,
|
|
16
|
+
* `<token>.<signature>`, while response bodies carry the bare `<token>`; the
|
|
17
|
+
* bearer plugin accepts either.
|
|
18
|
+
*/
|
|
19
|
+
export declare function sameSession(stored: string | undefined, token: string | undefined): boolean;
|
|
20
|
+
export declare function currentSession(store: SessionStore): SessionResult | null;
|
|
21
|
+
/**
|
|
22
|
+
* Keeps the SDK's session store and Better Auth's calls in step: the bearer
|
|
23
|
+
* goes out on every request, and every response that creates, replaces or ends
|
|
24
|
+
* the session is written back, which is what fires `onAuthStateChange`.
|
|
25
|
+
*/
|
|
26
|
+
export declare function sessionSync(store: SessionStore, options: AuthClientOptions,
|
|
27
|
+
/** Reads the session again; its response comes back through this plugin. */
|
|
28
|
+
revalidate: () => Promise<unknown>): BetterFetchPlugin;
|
|
29
|
+
//# sourceMappingURL=session-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-utils.d.ts","sourceRoot":"","sources":["../../src/auth/session-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE3E,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,aAAa,EAA0B,MAAM,YAAY,CAAC;AAMxG;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,WAAW,GAAG,IAAI,CAMrE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAG1F;AAGD,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa,GAAG,IAAI,CAGxE;AAGD;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,iBAAiB;AAC1B,4EAA4E;AAC5E,UAAU,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GACjC,iBAAiB,CA6EnB"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { COOKIE_PATHS, REDIRECT_SIGN_IN_PATHS, SIGN_OUT_PATHS, USER_CHANGE_PATHS } from "./constants.js";
|
|
2
|
+
import { authPath, revokedToken, socialStartUrl } from "./utils.js";
|
|
3
|
+
import { normalizeUser } from "../utils/compat.js";
|
|
4
|
+
import { isBrowser } from "../utils/runtime.js";
|
|
5
|
+
import { pkceCallback } from "./pkce.js";
|
|
6
|
+
/**
|
|
7
|
+
* The session a successful auth response carries, if any.
|
|
8
|
+
*
|
|
9
|
+
* Better Auth answers a sign-in with `{ token, user }` (password, OTP, anonymous,
|
|
10
|
+
* id token, second factor) or `{ session: { token }, user }` (passkey,
|
|
11
|
+
* get-session). A `user` is required alongside: the jwt plugin's `/token`
|
|
12
|
+
* answers `{ token }` with a JWT, which is not a session.
|
|
13
|
+
*/
|
|
14
|
+
export function sessionFromResponse(data) {
|
|
15
|
+
if (!data || typeof data !== 'object')
|
|
16
|
+
return null;
|
|
17
|
+
const body = data;
|
|
18
|
+
if (!body.user)
|
|
19
|
+
return null;
|
|
20
|
+
const token = typeof body.token === 'string' ? body.token : body.session?.token;
|
|
21
|
+
return typeof token === 'string' ? { token, user: body.user } : null;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Whether two tokens name the same session. The bearer the server hands out
|
|
25
|
+
* (`set-auth-token`, the OAuth fragment) is the signed cookie value,
|
|
26
|
+
* `<token>.<signature>`, while response bodies carry the bare `<token>`; the
|
|
27
|
+
* bearer plugin accepts either.
|
|
28
|
+
*/
|
|
29
|
+
export function sameSession(stored, token) {
|
|
30
|
+
if (!stored || !token)
|
|
31
|
+
return false;
|
|
32
|
+
return stored === token || stored.startsWith(`${token}.`) || token.startsWith(`${stored}.`);
|
|
33
|
+
}
|
|
34
|
+
export function currentSession(store) {
|
|
35
|
+
const session = store.get();
|
|
36
|
+
return session ? { data: { user: session.user, session }, error: null } : null;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Keeps the SDK's session store and Better Auth's calls in step: the bearer
|
|
40
|
+
* goes out on every request, and every response that creates, replaces or ends
|
|
41
|
+
* the session is written back, which is what fires `onAuthStateChange`.
|
|
42
|
+
*/
|
|
43
|
+
export function sessionSync(store, options,
|
|
44
|
+
/** Reads the session again; its response comes back through this plugin. */
|
|
45
|
+
revalidate) {
|
|
46
|
+
const { flowType, verifiers } = options;
|
|
47
|
+
const revisions = new WeakMap();
|
|
48
|
+
return {
|
|
49
|
+
id: 'motherbase-session',
|
|
50
|
+
name: 'Motherbase session',
|
|
51
|
+
// Edits the call's options in place rather than returning a copy: better-fetch
|
|
52
|
+
// runs its own schema plugin after this one, and it hands back the options
|
|
53
|
+
// object it was given. The object is built fresh for every call.
|
|
54
|
+
async init(url, fetchOptions = {}) {
|
|
55
|
+
const path = authPath(url);
|
|
56
|
+
fetchOptions.credentials = COOKIE_PATHS.some(prefix => path.startsWith(prefix)) ? 'include' : 'same-origin';
|
|
57
|
+
// Node does not send Origin, and Better Auth's CSRF check wants one on a
|
|
58
|
+
// mutation. Supply the project's own rather than turning the check off.
|
|
59
|
+
const headers = (fetchOptions.headers ?? {});
|
|
60
|
+
if (!isBrowser() && (fetchOptions.method ?? 'GET').toUpperCase() !== 'GET'
|
|
61
|
+
&& !Object.keys(headers).some(name => name.toLowerCase() === 'origin')) {
|
|
62
|
+
fetchOptions.headers = { ...headers, origin: new URL(options.url).origin };
|
|
63
|
+
}
|
|
64
|
+
const body = (fetchOptions.body ?? {});
|
|
65
|
+
// An id-token sign-in answers with the session directly: no redirect.
|
|
66
|
+
if (!REDIRECT_SIGN_IN_PATHS.includes(path) || body.idToken)
|
|
67
|
+
return { url, options: fetchOptions };
|
|
68
|
+
if (flowType === 'pkce') {
|
|
69
|
+
fetchOptions.body = { ...body, callbackURL: await pkceCallback(body.callbackURL, verifiers) };
|
|
70
|
+
}
|
|
71
|
+
if (path === '/sign-in/social' && isBrowser() && !body.disableRedirect) {
|
|
72
|
+
// Started with a fetch, the OAuth state cookie is a cross-site write
|
|
73
|
+
// that Safari and Firefox drop (Chrome too, in incognito), and the
|
|
74
|
+
// callback fails with state_mismatch. Navigating to the server's GET
|
|
75
|
+
// start route makes it first-party. The request is answered locally
|
|
76
|
+
// with Better Auth's own shape, `redirect: false` so it does not
|
|
77
|
+
// navigate a second time.
|
|
78
|
+
const href = socialStartUrl(options.url, fetchOptions.body);
|
|
79
|
+
window.location.href = href;
|
|
80
|
+
fetchOptions.customFetchImpl = async () => Response.json({ url: href, redirect: false });
|
|
81
|
+
}
|
|
82
|
+
return { url, options: fetchOptions };
|
|
83
|
+
},
|
|
84
|
+
hooks: {
|
|
85
|
+
onRequest(request) {
|
|
86
|
+
revisions.set(request, store.getRevision());
|
|
87
|
+
},
|
|
88
|
+
async onSuccess({ data, request }) {
|
|
89
|
+
const path = authPath(request.url);
|
|
90
|
+
const current = store.get();
|
|
91
|
+
// Do not let an older response replace a newer account or sign-out.
|
|
92
|
+
if (revisions.get(request) !== store.getRevision())
|
|
93
|
+
return;
|
|
94
|
+
const ended = SIGN_OUT_PATHS.has(path)
|
|
95
|
+
|| (path === '/revoke-session' && sameSession(current?.accessToken, revokedToken(request.body)))
|
|
96
|
+
|| (path === '/delete-user' && data?.message === 'User deleted')
|
|
97
|
+
// The stored token was revoked or expired elsewhere: the server answers
|
|
98
|
+
// null. Only for the stored token: getSessionFromUrl checks another one.
|
|
99
|
+
|| (path === '/get-session' && data === null
|
|
100
|
+
&& request.headers.get('authorization') === `Bearer ${current?.accessToken}`);
|
|
101
|
+
if (ended) {
|
|
102
|
+
await store.set(null, 'signOut');
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (USER_CHANGE_PATHS.has(path) && current) {
|
|
106
|
+
await revalidate();
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const next = sessionFromResponse(data);
|
|
110
|
+
if (!next)
|
|
111
|
+
return;
|
|
112
|
+
if (!current || !sameSession(current.accessToken, next.token)) {
|
|
113
|
+
await store.set({ accessToken: next.token, user: next.user }, path.startsWith('/two-factor/') ? 'mfaVerified' : 'signIn');
|
|
114
|
+
}
|
|
115
|
+
else if (JSON.stringify(normalizeUser(next.user)) !== JSON.stringify(current.user)) {
|
|
116
|
+
// Compared as the store holds it: normalised, aliases included.
|
|
117
|
+
await store.set({ ...current, user: next.user }, 'userUpdated');
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=session-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-utils.js","sourceRoot":"","sources":["../../src/auth/session-utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGzG,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAa;IAC/C,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACnD,MAAM,IAAI,GAAG,IAAqF,CAAC;IACnG,IAAI,CAAC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAC5B,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC;IAChF,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACvE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,MAA0B,EAAE,KAAyB;IAC/E,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACpC,OAAO,MAAM,KAAK,KAAK,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC;AAC9F,CAAC;AAGD,MAAM,UAAU,cAAc,CAAC,KAAmB;IAChD,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;IAC5B,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACjF,CAAC;AAGD;;;;GAIG;AACH,MAAM,UAAU,WAAW,CACzB,KAAmB,EACnB,OAA0B;AAC1B,4EAA4E;AAC5E,UAAkC;IAElC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IACxC,MAAM,SAAS,GAAG,IAAI,OAAO,EAAkB,CAAC;IAChD,OAAO;QACL,EAAE,EAAE,oBAAoB;QACxB,IAAI,EAAE,oBAAoB;QAC1B,+EAA+E;QAC/E,2EAA2E;QAC3E,iEAAiE;QACjE,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,eAAkC,EAAE;YAClD,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC3B,YAAY,CAAC,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC;YAE5G,yEAAyE;YACzE,wEAAwE;YACxE,MAAM,OAAO,GAAG,CAAC,YAAY,CAAC,OAAO,IAAI,EAAE,CAA2B,CAAC;YACvE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,KAAK,KAAK;mBACrE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAC,EAAE,CAAC;gBACzE,YAAY,CAAC,OAAO,GAAG,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;YAC7E,CAAC;YAED,MAAM,IAAI,GAAG,CAAC,YAAY,CAAC,IAAI,IAAI,EAAE,CAAqB,CAAC;YAC3D,sEAAsE;YACtE,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO;gBAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;YAElG,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;gBACxB,YAAY,CAAC,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,EAAE,CAAC;YAChG,CAAC;YACD,IAAI,IAAI,KAAK,iBAAiB,IAAI,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;gBACvE,qEAAqE;gBACrE,mEAAmE;gBACnE,qEAAqE;gBACrE,oEAAoE;gBACpE,iEAAiE;gBACjE,0BAA0B;gBAC1B,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,IAAwB,CAAC,CAAC;gBAChF,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC;gBAC5B,YAAY,CAAC,eAAe,GAAG,KAAK,IAAI,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;YAC3F,CAAC;YACD,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;QACxC,CAAC;QACD,KAAK,EAAE;YACL,SAAS,CAAC,OAAO;gBACf,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;YAC9C,CAAC;YACD,KAAK,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE;gBAC/B,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gBACnC,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;gBAC5B,oEAAoE;gBACpE,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,CAAC,WAAW,EAAE;oBAAE,OAAO;gBAC3D,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC;uBACjC,CAAC,IAAI,KAAK,iBAAiB,IAAI,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;uBAC7F,CAAC,IAAI,KAAK,cAAc,IAAK,IAAoC,EAAE,OAAO,KAAK,cAAc,CAAC;oBACjG,wEAAwE;oBACxE,yEAAyE;uBACtE,CAAC,IAAI,KAAK,cAAc,IAAI,IAAI,KAAK,IAAI;2BACvC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,UAAU,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;gBAClF,IAAI,KAAK,EAAE,CAAC;oBACV,MAAM,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;oBACjC,OAAO;gBACT,CAAC;gBACD,IAAI,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,OAAO,EAAE,CAAC;oBAC3C,MAAM,UAAU,EAAE,CAAC;oBACnB,OAAO;gBACT,CAAC;gBAED,MAAM,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;gBACvC,IAAI,CAAC,IAAI;oBAAE,OAAO;gBAClB,IAAI,CAAC,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC9D,MAAM,KAAK,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;gBAC5H,CAAC;qBAAM,IAAI,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;oBACrF,gEAAgE;oBAChE,MAAM,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,aAAa,CAAC,CAAC;gBAClE,CAAC;YACH,CAAC;SACF;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { AuthEvent, AuthListener, KeyValueStorageAdapter, Session, SessionStorageAdapter } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* The key every built-in storage adapter defaults to, for both the cookie and
|
|
4
|
+
* localStorage. Defined once: it is a contract between the browser half of an
|
|
5
|
+
* app and the server half, and a second copy of the literal is how the two
|
|
6
|
+
* drift apart. Re-exported from `cookie.ts` and from the package root.
|
|
7
|
+
*/
|
|
8
|
+
export declare const SESSION_COOKIE_KEY = "motherbase.session";
|
|
9
|
+
/** In-memory adapter. Safe everywhere (SSR, tests); does not survive reloads. */
|
|
10
|
+
export declare function memoryStorage(): SessionStorageAdapter;
|
|
11
|
+
/**
|
|
12
|
+
* Browser localStorage adapter. Falls back to memory when localStorage is
|
|
13
|
+
* unavailable (SSR, private mode), so it never throws on import or use.
|
|
14
|
+
*/
|
|
15
|
+
export declare function localStorageStorage(key?: string): SessionStorageAdapter;
|
|
16
|
+
/** `globalThis.localStorage`, or undefined when absent or when merely touching it throws. */
|
|
17
|
+
export declare function browserLocalStorage(): Storage | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* Wrap a supabase-js style key/value store (localStorage, React Native's
|
|
20
|
+
* AsyncStorage, a cookie shim) as a session adapter.
|
|
21
|
+
*
|
|
22
|
+
* This is what lets `createClient(url, key, { auth: { storage: AsyncStorage } })`
|
|
23
|
+
* work verbatim on a ported app. A value that will not parse is treated as no
|
|
24
|
+
* session rather than thrown: a corrupt entry must not brick every launch.
|
|
25
|
+
*/
|
|
26
|
+
export declare function keyValueStorage(store: KeyValueStorageAdapter, key?: string): SessionStorageAdapter;
|
|
27
|
+
/** Tell the two adapter shapes apart: supabase-js's is a key/value store. */
|
|
28
|
+
export declare function isKeyValueStorage(value: KeyValueStorageAdapter | SessionStorageAdapter): value is KeyValueStorageAdapter;
|
|
29
|
+
/**
|
|
30
|
+
* Holds the live session in memory, mirrors it to a storage adapter, and
|
|
31
|
+
* notifies listeners of auth changes. The in-memory copy is the source of truth
|
|
32
|
+
* for synchronous reads (e.g. attaching the bearer header).
|
|
33
|
+
*/
|
|
34
|
+
export declare class SessionStore {
|
|
35
|
+
private readonly storage;
|
|
36
|
+
private current;
|
|
37
|
+
private readonly listeners;
|
|
38
|
+
private hydrated;
|
|
39
|
+
private revision;
|
|
40
|
+
constructor(storage: SessionStorageAdapter);
|
|
41
|
+
/** Load the persisted session once. Idempotent. */
|
|
42
|
+
hydrate(): Promise<Session | null>;
|
|
43
|
+
get(): Session | null;
|
|
44
|
+
getRevision(): number;
|
|
45
|
+
set(session: Session | null, event: AuthEvent): Promise<void>;
|
|
46
|
+
/** Replace only the tokens, keeping the existing user (used after refresh). */
|
|
47
|
+
setTokens(accessToken: string, refreshToken: string): Promise<void>;
|
|
48
|
+
subscribe(listener: AuthListener): () => void;
|
|
49
|
+
private emit;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/auth/session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,SAAS,EACT,YAAY,EACZ,sBAAsB,EACtB,OAAO,EACP,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAEpB;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAEvD,iFAAiF;AACjF,wBAAgB,aAAa,IAAI,qBAAqB,CAQrD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,SAAqB,GAAG,qBAAqB,CAyBnF;AAED,6FAA6F;AAC7F,wBAAgB,mBAAmB,IAAI,OAAO,GAAG,SAAS,CAMzD;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,sBAAsB,EAAE,GAAG,SAAqB,GAAG,qBAAqB,CAgB9G;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,sBAAsB,GAAG,qBAAqB,GACpD,KAAK,IAAI,sBAAsB,CAEjC;AAED;;;;GAIG;AACH,qBAAa,YAAY;IAMX,OAAO,CAAC,QAAQ,CAAC,OAAO;IALpC,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA2B;IACrD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAK;gBAEQ,OAAO,EAAE,qBAAqB;IAE3D,mDAAmD;IAC7C,OAAO,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAoBxC,GAAG,IAAI,OAAO,GAAG,IAAI;IAIrB,WAAW,IAAI,MAAM;IAIf,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAWnE,+EAA+E;IACzE,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKzE,SAAS,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,IAAI;IAK7C,OAAO,CAAC,IAAI;CAGb"}
|