use-convex 1.3.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +104 -59
- package/dist/module.d.mts +62 -39
- package/dist/module.mjs +68 -17
- package/dist/runtime/auth/oauth.d.ts +96 -0
- package/dist/runtime/auth/oauth.js +170 -0
- package/dist/runtime/auth/sessionRoutes.d.ts +37 -0
- package/dist/runtime/auth/sessionRoutes.js +41 -0
- package/dist/runtime/composables/useAuth.d.ts +81 -48
- package/dist/runtime/composables/useAuth.js +69 -461
- package/dist/runtime/composables/useAuthToken.d.ts +2 -2
- package/dist/runtime/composables/useAuthToken.js +4 -0
- package/dist/runtime/composables/useConvexAuth.js +1 -1
- package/dist/runtime/composables/useConvexPaginatedQuery.js +6 -1
- package/dist/runtime/composables/useConvexQuery.js +6 -1
- package/dist/runtime/plugin.auth.client.d.ts +8 -3
- package/dist/runtime/plugin.auth.client.js +207 -31
- package/dist/runtime/plugin.server.js +8 -2
- package/dist/runtime/server/auth.d.ts +7 -2
- package/dist/runtime/server/auth.js +14 -3
- package/dist/runtime/server/convexAuth/refresh.d.ts +3 -0
- package/dist/runtime/server/convexAuth/refresh.js +5 -0
- package/dist/runtime/server/convexAuth/session.middleware.d.ts +10 -0
- package/dist/runtime/server/convexAuth/session.middleware.js +37 -0
- package/dist/runtime/server/convexAuth/setup.d.ts +21 -0
- package/dist/runtime/server/convexAuth/setup.js +90 -0
- package/dist/runtime/server/convexAuth/signin.d.ts +3 -0
- package/dist/runtime/server/convexAuth/signin.js +5 -0
- package/dist/runtime/server/convexAuth/signout.d.ts +3 -0
- package/dist/runtime/server/convexAuth/signout.js +5 -0
- package/dist/runtime/server/convexConfig.d.ts +2 -6
- package/dist/runtime/server/fetch.d.ts +2 -1
- package/dist/runtime/server/fetch.js +3 -8
- package/dist/runtime/utils/authClientOptions.d.ts +33 -40
- package/dist/runtime/utils/authClientOptions.js +1 -64
- package/dist/runtime/utils/authCookie.d.ts +8 -14
- package/dist/runtime/utils/authCookie.js +23 -27
- package/dist/runtime/utils/authStorage.d.ts +76 -79
- package/dist/runtime/utils/authStorage.js +60 -141
- package/dist/runtime/utils/context.d.ts +40 -3
- package/dist/types.d.mts +4 -2
- package/package.json +10 -5
- package/dist/runtime/server/api/convex/auth/session.d.ts +0 -36
- package/dist/runtime/server/api/convex/auth/session.js +0 -90
- package/dist/runtime/server/authCookies.d.ts +0 -9
- package/dist/runtime/server/authCookies.js +0 -64
- package/dist/runtime/server/sameOrigin.d.ts +0 -14
- package/dist/runtime/server/sameOrigin.js +0 -29
- package/dist/runtime/utils/authMutex.d.ts +0 -15
- package/dist/runtime/utils/authMutex.js +0 -47
- package/dist/runtime/utils/oauthRedirect.d.ts +0 -5
- package/dist/runtime/utils/oauthRedirect.js +0 -13
|
@@ -1,61 +1,54 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Runtime Convex Auth client
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
* Runtime knobs for the Convex Auth client that can't live in serializable
|
|
3
|
+
* module options: a custom TokenStorage, extra ambient sign-ins, or a custom
|
|
4
|
+
* `replaceUrl`. Call {@link configureConvexAuth} from a client plugin with
|
|
5
|
+
* `enforce: 'pre'` so the options land before the auth plugin creates the
|
|
6
|
+
* client.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Token storage (`@convex-dev/auth/browser` `TokenStorage`). Methods may be
|
|
10
|
+
* sync or async, e.g. Capacitor Preferences or an encrypted store.
|
|
9
11
|
*/
|
|
10
12
|
export type ConvexAuthTokenStorage = {
|
|
11
|
-
getItem: (key: string) => string |
|
|
13
|
+
getItem: (key: string) => string | null | undefined | Promise<string | null | undefined>;
|
|
12
14
|
setItem: (key: string, value: string) => void | Promise<void>;
|
|
13
15
|
removeItem: (key: string) => void | Promise<void>;
|
|
14
16
|
};
|
|
15
|
-
export type ConvexAuthStorageMode
|
|
17
|
+
export type { ConvexAuthStorageMode } from './authStorage.js';
|
|
18
|
+
/**
|
|
19
|
+
* An ambient sign-in registration (`AmbientSignInClient` in
|
|
20
|
+
* `@convex-dev/auth`): a method that finishes on its own at startup, like
|
|
21
|
+
* an OAuth callback. Typed loosely here so this file needs no Convex Auth
|
|
22
|
+
* import; the auth plugin passes it straight to `AuthClient`.
|
|
23
|
+
*/
|
|
24
|
+
export type ConvexAmbientSignIn = {
|
|
25
|
+
id: string;
|
|
26
|
+
setup: (ctx: never) => void | {
|
|
27
|
+
onInit?: () => void;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
16
30
|
export type ConvexAuthClientOptions = {
|
|
17
31
|
/**
|
|
18
|
-
*
|
|
19
|
-
* callbacks. Defaults to handling the code when a verifier is stored.
|
|
32
|
+
* Custom token storage. Overrides `convex.auth.storage`.
|
|
20
33
|
*/
|
|
21
|
-
|
|
34
|
+
storage?: ConvexAuthTokenStorage;
|
|
22
35
|
/**
|
|
23
|
-
*
|
|
24
|
-
* `
|
|
36
|
+
* Replaces the default ambient sign-ins (`[oauth()]`). Pass `[]` to
|
|
37
|
+
* disable OAuth callback handling, or include `convexOAuth()` alongside
|
|
38
|
+
* your own.
|
|
25
39
|
*/
|
|
26
|
-
|
|
40
|
+
ambientSignIns?: ConvexAmbientSignIn[];
|
|
27
41
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
42
|
+
* Replace the page URL after an OAuth callback strips its params.
|
|
43
|
+
* Defaults to `history.replaceState`, then syncs `vue-router`.
|
|
30
44
|
*/
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Namespace for storage keys (non-alphanumeric chars stripped). Defaults
|
|
34
|
-
* to the Convex deployment URL.
|
|
35
|
-
*/
|
|
36
|
-
storageNamespace?: string;
|
|
37
|
-
};
|
|
38
|
-
/** Serializable subset safe for `runtimeConfig.public.convex.auth`. */
|
|
39
|
-
export type ConvexAuthModuleClientOptions = {
|
|
40
|
-
shouldHandleCode?: boolean;
|
|
41
|
-
storage?: ConvexAuthStorageMode;
|
|
42
|
-
storageNamespace?: string;
|
|
45
|
+
replaceUrl?: (url: string) => void;
|
|
43
46
|
};
|
|
44
47
|
/**
|
|
45
48
|
* Set runtime Convex Auth knobs. Merge is shallow — later calls override
|
|
46
|
-
* earlier keys.
|
|
47
|
-
* so options land before the auth plugin consumes OAuth codes.
|
|
49
|
+
* earlier keys.
|
|
48
50
|
*/
|
|
49
51
|
export declare function configureConvexAuth(options: ConvexAuthClientOptions): void;
|
|
50
|
-
/** @internal */
|
|
51
|
-
export declare function setConvexAuthModuleDefaults(options: ConvexAuthModuleClientOptions): void;
|
|
52
|
-
/** Merged module defaults + {@link configureConvexAuth} overrides. */
|
|
53
52
|
export declare function getConvexAuthClientOptions(): ConvexAuthClientOptions;
|
|
54
53
|
/** @internal */
|
|
55
54
|
export declare function resetConvexAuthClientOptionsForTests(): void;
|
|
56
|
-
/** @internal */
|
|
57
|
-
export declare function createInMemoryTokenStorage(): ConvexAuthTokenStorage;
|
|
58
|
-
/** @internal */
|
|
59
|
-
export declare function resetInMemoryTokenStorageForTests(): void;
|
|
60
|
-
/** Resolve the active token storage from merged auth options. */
|
|
61
|
-
export declare function resolveAuthTokenStorage(options?: ConvexAuthClientOptions): ConvexAuthTokenStorage;
|
|
@@ -1,73 +1,10 @@
|
|
|
1
1
|
let runtimeOverrides = {};
|
|
2
|
-
let moduleDefaults = {};
|
|
3
2
|
export function configureConvexAuth(options) {
|
|
4
3
|
runtimeOverrides = { ...runtimeOverrides, ...options };
|
|
5
4
|
}
|
|
6
|
-
export function setConvexAuthModuleDefaults(options) {
|
|
7
|
-
moduleDefaults = { ...options };
|
|
8
|
-
}
|
|
9
5
|
export function getConvexAuthClientOptions() {
|
|
10
|
-
return {
|
|
11
|
-
...moduleDefaults,
|
|
12
|
-
...runtimeOverrides
|
|
13
|
-
};
|
|
6
|
+
return { ...runtimeOverrides };
|
|
14
7
|
}
|
|
15
8
|
export function resetConvexAuthClientOptionsForTests() {
|
|
16
9
|
runtimeOverrides = {};
|
|
17
|
-
moduleDefaults = {};
|
|
18
|
-
}
|
|
19
|
-
const inMemory = /* @__PURE__ */ new Map();
|
|
20
|
-
export function createInMemoryTokenStorage() {
|
|
21
|
-
return {
|
|
22
|
-
getItem: (key) => inMemory.get(key) ?? null,
|
|
23
|
-
setItem: (key, value) => {
|
|
24
|
-
inMemory.set(key, value);
|
|
25
|
-
},
|
|
26
|
-
removeItem: (key) => {
|
|
27
|
-
inMemory.delete(key);
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
export function resetInMemoryTokenStorageForTests() {
|
|
32
|
-
inMemory.clear();
|
|
33
|
-
}
|
|
34
|
-
const localStorageAdapter = {
|
|
35
|
-
getItem: (key) => {
|
|
36
|
-
if (typeof window === "undefined") {
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
39
|
-
try {
|
|
40
|
-
return window.localStorage.getItem(key);
|
|
41
|
-
} catch {
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
setItem: (key, value) => {
|
|
46
|
-
if (typeof window === "undefined") {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
try {
|
|
50
|
-
window.localStorage.setItem(key, value);
|
|
51
|
-
} catch {
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
removeItem: (key) => {
|
|
55
|
-
if (typeof window === "undefined") {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
try {
|
|
59
|
-
window.localStorage.removeItem(key);
|
|
60
|
-
} catch {
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
export function resolveAuthTokenStorage(options = getConvexAuthClientOptions()) {
|
|
65
|
-
const storage = options.storage;
|
|
66
|
-
if (storage === "inMemory") {
|
|
67
|
-
return createInMemoryTokenStorage();
|
|
68
|
-
}
|
|
69
|
-
if (storage && typeof storage === "object") {
|
|
70
|
-
return storage;
|
|
71
|
-
}
|
|
72
|
-
return localStorageAdapter;
|
|
73
10
|
}
|
|
@@ -1,19 +1,13 @@
|
|
|
1
|
-
import { type ComputedRef } from 'vue';
|
|
1
|
+
import { type ComputedRef, type Ref } from 'vue';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* When `auth.httpOnly` is set, this cookie is HttpOnly (server-readable only).
|
|
3
|
+
* Convex Auth access token shared between server and client via the Nuxt
|
|
4
|
+
* payload. The server fills it from the (refreshed) SSR session; the client
|
|
5
|
+
* auth plugin keeps it in sync with the live `AuthClient` token.
|
|
7
6
|
*/
|
|
7
|
+
export declare function useConvexAuthTokenState(): Ref<string | null>;
|
|
8
|
+
/** BYO providers: readable JWT cookie written by the app after sign-in. */
|
|
8
9
|
export declare function useAuthJwtCookie(): import("nuxt/app").CookieRef<string | null> | undefined;
|
|
9
|
-
/**
|
|
10
|
-
* Readable presence marker used when JWT is HttpOnly so the client can still
|
|
11
|
-
* compute `hasSsrSession` / `showAuthedUi` without reading the token.
|
|
12
|
-
*/
|
|
13
|
-
export declare function useAuthPresentCookie(): import("nuxt/app").CookieRef<string | null> | undefined;
|
|
14
|
-
/** Reactive JWT for HttpClient + SSR. Empty on the client when HttpOnly. */
|
|
10
|
+
/** Reactive JWT for HttpClient + SSR. */
|
|
15
11
|
export declare function useSsrTokenRef(): ComputedRef<string | undefined>;
|
|
16
|
-
/**
|
|
17
|
-
* Session hint for UI gating: JWT readable, or HttpOnly presence cookie.
|
|
18
|
-
*/
|
|
12
|
+
/** Session hint for UI gating: a JWT is known for this request / client. */
|
|
19
13
|
export declare function useHasSsrSessionRef(): ComputedRef<boolean>;
|
|
@@ -1,46 +1,42 @@
|
|
|
1
1
|
import { computed } from "vue";
|
|
2
|
-
import { useCookie, useRuntimeConfig } from "nuxt/app";
|
|
2
|
+
import { useCookie, useRuntimeConfig, useState } from "nuxt/app";
|
|
3
3
|
import {
|
|
4
|
-
|
|
4
|
+
SSR_TOKEN_STATE_KEY,
|
|
5
5
|
cookieValueToSsrToken,
|
|
6
|
-
|
|
7
|
-
resolveAuthCookieName
|
|
8
|
-
resolveAuthPresentCookieName
|
|
6
|
+
isConvexAuth,
|
|
7
|
+
resolveAuthCookieName
|
|
9
8
|
} from "./authStorage.js";
|
|
10
|
-
function
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
httpOnly
|
|
17
|
-
};
|
|
9
|
+
function readAuthConfig() {
|
|
10
|
+
const config = useRuntimeConfig();
|
|
11
|
+
return config.public.convex?.auth;
|
|
12
|
+
}
|
|
13
|
+
export function useConvexAuthTokenState() {
|
|
14
|
+
return useState(SSR_TOKEN_STATE_KEY, () => null);
|
|
18
15
|
}
|
|
19
16
|
export function useAuthJwtCookie() {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
const name = resolveAuthCookieName(convexConfig?.auth);
|
|
23
|
-
if (!name) {
|
|
17
|
+
const auth = readAuthConfig();
|
|
18
|
+
if (isConvexAuth(auth)) {
|
|
24
19
|
return void 0;
|
|
25
20
|
}
|
|
26
|
-
const
|
|
27
|
-
return useCookie(name, cookieOptions(httpOnly));
|
|
28
|
-
}
|
|
29
|
-
export function useAuthPresentCookie() {
|
|
30
|
-
const config = useRuntimeConfig();
|
|
31
|
-
const convexConfig = config.public.convex;
|
|
32
|
-
const name = resolveAuthPresentCookieName(convexConfig?.auth);
|
|
21
|
+
const name = resolveAuthCookieName(auth);
|
|
33
22
|
if (!name) {
|
|
34
23
|
return void 0;
|
|
35
24
|
}
|
|
36
|
-
return useCookie(name,
|
|
25
|
+
return useCookie(name, {
|
|
26
|
+
sameSite: "lax",
|
|
27
|
+
secure: process.env.NODE_ENV === "production",
|
|
28
|
+
path: "/"
|
|
29
|
+
});
|
|
37
30
|
}
|
|
38
31
|
export function useSsrTokenRef() {
|
|
32
|
+
if (isConvexAuth(readAuthConfig())) {
|
|
33
|
+
const state = useConvexAuthTokenState();
|
|
34
|
+
return computed(() => state.value || void 0);
|
|
35
|
+
}
|
|
39
36
|
const cookie = useAuthJwtCookie();
|
|
40
37
|
return computed(() => cookieValueToSsrToken(cookie?.value));
|
|
41
38
|
}
|
|
42
39
|
export function useHasSsrSessionRef() {
|
|
43
40
|
const token = useSsrTokenRef();
|
|
44
|
-
|
|
45
|
-
return computed(() => !!token.value || present?.value === "1");
|
|
41
|
+
return computed(() => !!token.value);
|
|
46
42
|
}
|
|
@@ -1,96 +1,93 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Shared auth configuration helpers.
|
|
3
|
+
*
|
|
4
|
+
* Kept free of `@convex-dev/auth` imports: apps that bring their own provider
|
|
5
|
+
* (Clerk, Auth0, custom JWT) load this file without installing Convex Auth.
|
|
3
6
|
*/
|
|
4
|
-
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
7
|
+
/** Session model for first-party Convex Auth v2. */
|
|
8
|
+
export type ConvexAuthMode = 'ssr' | 'spa';
|
|
9
|
+
/** Client token storage for Convex Auth. */
|
|
10
|
+
export type ConvexAuthStorageMode = 'localStorage' | 'inMemory';
|
|
11
|
+
/**
|
|
12
|
+
* Names of the session functions `setupConvexAuth` returns, as exported from
|
|
13
|
+
* the app's Convex functions (e.g. `convex/auth.ts` → `'auth:refreshSession'`).
|
|
14
|
+
*/
|
|
15
|
+
export type ConvexAuthApiNames = {
|
|
16
|
+
refreshSession?: string;
|
|
17
|
+
signOut?: string;
|
|
18
|
+
isAuthenticated?: string;
|
|
19
|
+
};
|
|
16
20
|
export type ConvexAuthConfig = {
|
|
17
|
-
provider?:
|
|
18
|
-
cookie?: string;
|
|
21
|
+
provider?: 'convex-auth';
|
|
19
22
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* Prefer `true` in production. Does not make sessions XSS-proof.
|
|
24
|
-
*/
|
|
25
|
-
httpOnly?: boolean;
|
|
26
|
-
/** Readable presence cookie when `httpOnly` is set (UI only). */
|
|
27
|
-
presentCookie?: string;
|
|
28
|
-
/**
|
|
29
|
-
* Namespace for local token keys (React `storageNamespace` parity).
|
|
30
|
-
* Non-alphanumeric characters are stripped. Defaults to the deployment URL.
|
|
23
|
+
* BYO providers: cookie whose value is a JWT for SSR queries and Nitro
|
|
24
|
+
* `fetch*` helpers. Ignored for `provider: 'convex-auth'`, which manages
|
|
25
|
+
* its own cookies.
|
|
31
26
|
*/
|
|
27
|
+
cookie?: string;
|
|
28
|
+
/** @see ModuleAuthOptions.mode */
|
|
29
|
+
mode?: ConvexAuthMode;
|
|
30
|
+
/** @see ModuleAuthOptions.api */
|
|
31
|
+
api?: ConvexAuthApiNames;
|
|
32
|
+
/** @see ModuleAuthOptions.routePrefix */
|
|
33
|
+
routePrefix?: string;
|
|
34
|
+
/** @see ModuleAuthOptions.storageNamespace */
|
|
32
35
|
storageNamespace?: string;
|
|
33
|
-
/**
|
|
34
|
-
* Client token storage mode. Use {@link configureConvexAuth} for a custom
|
|
35
|
-
* {@link ConvexAuthTokenStorage}. Ignored when `httpOnly` is enabled.
|
|
36
|
-
* @default 'localStorage'
|
|
37
|
-
*/
|
|
36
|
+
/** @see ModuleAuthOptions.storage */
|
|
38
37
|
storage?: ConvexAuthStorageMode;
|
|
39
|
-
/**
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
/** @see ModuleAuthOptions.verbose */
|
|
39
|
+
verbose?: boolean;
|
|
40
|
+
};
|
|
41
|
+
/** Server-only Convex Auth options (`runtimeConfig.convexAuth`). */
|
|
42
|
+
export interface ConvexAuthServerRuntimeConfig {
|
|
43
|
+
/** Sign-in function names the auth proxy forwards, e.g. `'auth:signInWithUsernamePassword'`. */
|
|
44
|
+
signIn?: string[];
|
|
45
|
+
/** Origins trusted besides the request's own Host. */
|
|
46
|
+
allowedOrigins?: string[];
|
|
47
|
+
/** Cookie attributes. `secure` defaults to true except on localhost. */
|
|
48
|
+
cookie?: {
|
|
49
|
+
secure?: boolean;
|
|
50
|
+
domain?: string;
|
|
51
|
+
path?: string;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/** The Convex Auth v2 access-token cookie (fixed by `@convex-dev/auth/ssr`). */
|
|
55
|
+
export declare const CONVEX_AUTH_JWT_COOKIE = "__convexAuthJWT";
|
|
56
|
+
/** The Convex Auth v2 refresh-token cookie (fixed by `@convex-dev/auth/ssr`). */
|
|
57
|
+
export declare const CONVEX_AUTH_REFRESH_COOKIE = "__convexAuthRefreshToken";
|
|
58
|
+
export declare const DEFAULT_AUTH_ROUTE_PREFIX = "/api/convex/auth";
|
|
59
|
+
export declare const DEFAULT_CONVEX_AUTH_API: Required<ConvexAuthApiNames>;
|
|
60
|
+
/** `useState` key carrying the SSR access token to the client payload. */
|
|
61
|
+
export declare const SSR_TOKEN_STATE_KEY = "convex:auth-token";
|
|
62
|
+
export declare function isConvexAuth(auth?: ConvexAuthConfig): boolean;
|
|
63
|
+
/** SSR mode is the default for Convex Auth: Nuxt renders on the server. */
|
|
64
|
+
export declare function resolveAuthMode(auth?: ConvexAuthConfig): ConvexAuthMode;
|
|
65
|
+
export declare function isSsrConvexAuth(auth?: ConvexAuthConfig): boolean;
|
|
66
|
+
export declare function resolveAuthApiNames(auth?: ConvexAuthConfig): Required<ConvexAuthApiNames>;
|
|
67
|
+
export declare function resolveAuthRoutes(auth?: ConvexAuthConfig): {
|
|
68
|
+
signIn: string;
|
|
69
|
+
refresh: string;
|
|
70
|
+
signOut: string;
|
|
44
71
|
};
|
|
45
|
-
export type { ConvexAuthTokenStorage, ConvexAuthStorageMode };
|
|
46
|
-
export declare function storageNamespace(urlOrNamespace: string): string;
|
|
47
|
-
export declare function storageKey(base: string, urlOrNamespace: string): string;
|
|
48
|
-
/**
|
|
49
|
-
* Flatten FormData (or pass through a plain record) the same way the React
|
|
50
|
-
* Convex Auth client does before calling `auth:signIn`.
|
|
51
|
-
*/
|
|
52
|
-
export declare function flattenSignInParams(params?: FormData | Record<string, string>): Record<string, string>;
|
|
53
72
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
73
|
+
* Cookie holding the JWT for SSR reads: the Convex Auth access-token cookie
|
|
74
|
+
* in SSR mode, the configured cookie for BYO providers, otherwise none.
|
|
75
|
+
* Convex Auth SPA mode keeps tokens in browser storage, so it has no cookie.
|
|
57
76
|
*/
|
|
58
77
|
export declare function resolveAuthCookieName(auth?: ConvexAuthConfig): string | undefined;
|
|
59
|
-
export declare function resolveAuthPresentCookieName(auth?: ConvexAuthConfig): string | undefined;
|
|
60
|
-
export declare function resolveAuthRefreshCookieName(auth?: ConvexAuthConfig): string | undefined;
|
|
61
|
-
export declare function isHttpOnlyAuth(auth?: ConvexAuthConfig): boolean;
|
|
62
78
|
/** Empty / missing cookies are not a session. */
|
|
63
79
|
export declare function cookieValueToSsrToken(value: string | null | undefined): string | undefined;
|
|
64
80
|
/**
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
* returns a Promise — callers that can wait should use {@link readLocalAsync}.
|
|
68
|
-
*/
|
|
69
|
-
export declare function readStored(key: string): string | null | Promise<string | null>;
|
|
70
|
-
/** Sync read. Returns null when storage is async (use {@link readLocalAsync}). */
|
|
71
|
-
export declare function readLocal(key: string): string | null;
|
|
72
|
-
export declare function readLocalAsync(key: string): Promise<string | null>;
|
|
73
|
-
export declare function writeLocal(key: string, value: string | null): void;
|
|
74
|
-
export declare function writeLocalAsync(key: string, value: string | null): Promise<void>;
|
|
75
|
-
/**
|
|
76
|
-
* `storage: 'inMemory'` cannot survive the IdP redirect, so the OAuth
|
|
77
|
-
* verifier is kept in a short-lived cookie (Next.js in-memory parity).
|
|
78
|
-
* JWTs stay in memory. Other storage modes keep the verifier with the tokens.
|
|
81
|
+
* Whether a JWT's `exp` claim is within `skewSeconds` of now (or unreadable).
|
|
82
|
+
* Signature is not checked — this only decides whether to refresh.
|
|
79
83
|
*/
|
|
80
|
-
export declare function
|
|
81
|
-
export declare function readVerifierAsync(key: string): Promise<string | null>;
|
|
82
|
-
export declare function writeVerifier(key: string, value: string | null): Promise<void>;
|
|
83
|
-
/** @internal */
|
|
84
|
-
export declare function readBrowserCookie(name: string): string | null;
|
|
85
|
-
/** @internal */
|
|
86
|
-
export declare function writeBrowserCookie(name: string, value: string | null, maxAgeSeconds: number): void;
|
|
84
|
+
export declare function isJwtExpiring(token: string, skewSeconds?: number, nowMs?: number): boolean;
|
|
87
85
|
/**
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
86
|
+
* A stable identity for the session a JWT belongs to: `iss` + `sub`.
|
|
87
|
+
*
|
|
88
|
+
* Convex Auth rotates the access token every minute but keeps the session
|
|
89
|
+
* id in `sub`, so this changes on sign-in / sign-out / account switch, not
|
|
90
|
+
* on rotation. Tokens without readable claims fall back to the token itself
|
|
91
|
+
* (any change is treated as a new session). Empty for no token.
|
|
91
92
|
*/
|
|
92
|
-
export declare function
|
|
93
|
-
code: string | null;
|
|
94
|
-
verifier: string | null;
|
|
95
|
-
shouldHandleCode?: boolean | (() => boolean);
|
|
96
|
-
}): boolean;
|
|
93
|
+
export declare function sessionKeyFromToken(token: string | null | undefined): string;
|
|
@@ -1,156 +1,75 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export const
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export function
|
|
14
|
-
return
|
|
15
|
-
}
|
|
16
|
-
export function
|
|
17
|
-
return
|
|
18
|
-
}
|
|
19
|
-
export function
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
});
|
|
30
|
-
return out;
|
|
31
|
-
}
|
|
32
|
-
return { ...params };
|
|
1
|
+
export const CONVEX_AUTH_JWT_COOKIE = "__convexAuthJWT";
|
|
2
|
+
export const CONVEX_AUTH_REFRESH_COOKIE = "__convexAuthRefreshToken";
|
|
3
|
+
export const DEFAULT_AUTH_ROUTE_PREFIX = "/api/convex/auth";
|
|
4
|
+
export const DEFAULT_CONVEX_AUTH_API = {
|
|
5
|
+
refreshSession: "auth:refreshSession",
|
|
6
|
+
signOut: "auth:signOut",
|
|
7
|
+
isAuthenticated: "auth:isAuthenticated"
|
|
8
|
+
};
|
|
9
|
+
export const SSR_TOKEN_STATE_KEY = "convex:auth-token";
|
|
10
|
+
export function isConvexAuth(auth) {
|
|
11
|
+
return auth?.provider === "convex-auth";
|
|
12
|
+
}
|
|
13
|
+
export function resolveAuthMode(auth) {
|
|
14
|
+
return auth?.mode ?? "ssr";
|
|
15
|
+
}
|
|
16
|
+
export function isSsrConvexAuth(auth) {
|
|
17
|
+
return isConvexAuth(auth) && resolveAuthMode(auth) === "ssr";
|
|
18
|
+
}
|
|
19
|
+
export function resolveAuthApiNames(auth) {
|
|
20
|
+
return { ...DEFAULT_CONVEX_AUTH_API, ...auth?.api };
|
|
21
|
+
}
|
|
22
|
+
export function resolveAuthRoutes(auth) {
|
|
23
|
+
const prefix = (auth?.routePrefix ?? DEFAULT_AUTH_ROUTE_PREFIX).replace(/\/+$/, "");
|
|
24
|
+
return {
|
|
25
|
+
signIn: `${prefix}/signin`,
|
|
26
|
+
refresh: `${prefix}/refresh`,
|
|
27
|
+
signOut: `${prefix}/signout`
|
|
28
|
+
};
|
|
33
29
|
}
|
|
34
30
|
export function resolveAuthCookieName(auth) {
|
|
35
|
-
if (auth
|
|
36
|
-
return auth
|
|
31
|
+
if (isConvexAuth(auth)) {
|
|
32
|
+
return isSsrConvexAuth(auth) ? CONVEX_AUTH_JWT_COOKIE : void 0;
|
|
37
33
|
}
|
|
38
|
-
|
|
39
|
-
return auth.cookie;
|
|
40
|
-
}
|
|
41
|
-
if (auth?.provider === "convex-auth") {
|
|
42
|
-
return DEFAULT_CONVEX_AUTH_COOKIE;
|
|
43
|
-
}
|
|
44
|
-
return void 0;
|
|
45
|
-
}
|
|
46
|
-
export function resolveAuthPresentCookieName(auth) {
|
|
47
|
-
if (!auth?.httpOnly) {
|
|
48
|
-
return void 0;
|
|
49
|
-
}
|
|
50
|
-
return auth.presentCookie ?? DEFAULT_AUTH_PRESENT_COOKIE;
|
|
51
|
-
}
|
|
52
|
-
export function resolveAuthRefreshCookieName(auth) {
|
|
53
|
-
if (!auth?.httpOnly) {
|
|
54
|
-
return void 0;
|
|
55
|
-
}
|
|
56
|
-
return HTTPONLY_REFRESH_COOKIE;
|
|
57
|
-
}
|
|
58
|
-
export function isHttpOnlyAuth(auth) {
|
|
59
|
-
return auth?.httpOnly === true;
|
|
34
|
+
return auth?.cookie || void 0;
|
|
60
35
|
}
|
|
61
36
|
export function cookieValueToSsrToken(value) {
|
|
62
37
|
return value || void 0;
|
|
63
38
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
function authStorageIsInMemory() {
|
|
69
|
-
return getConvexAuthClientOptions().storage === "inMemory";
|
|
70
|
-
}
|
|
71
|
-
export function readStored(key) {
|
|
72
|
-
const value = activeStorage().getItem(key);
|
|
73
|
-
if (value instanceof Promise) {
|
|
74
|
-
return value.then((stored) => stored ?? null);
|
|
75
|
-
}
|
|
76
|
-
return value ?? null;
|
|
77
|
-
}
|
|
78
|
-
export function readLocal(key) {
|
|
79
|
-
const value = readStored(key);
|
|
80
|
-
if (value instanceof Promise) {
|
|
81
|
-
return null;
|
|
82
|
-
}
|
|
83
|
-
return value;
|
|
84
|
-
}
|
|
85
|
-
export async function readLocalAsync(key) {
|
|
86
|
-
return await readStored(key);
|
|
87
|
-
}
|
|
88
|
-
export function writeLocal(key, value) {
|
|
89
|
-
void writeLocalAsync(key, value);
|
|
90
|
-
}
|
|
91
|
-
export async function writeLocalAsync(key, value) {
|
|
92
|
-
const storage = activeStorage();
|
|
93
|
-
if (value === null) {
|
|
94
|
-
await storage.removeItem(key);
|
|
95
|
-
} else {
|
|
96
|
-
await storage.setItem(key, value);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
export function readVerifier(key) {
|
|
100
|
-
if (authStorageIsInMemory()) {
|
|
101
|
-
return readBrowserCookie(key);
|
|
102
|
-
}
|
|
103
|
-
return readStored(key);
|
|
104
|
-
}
|
|
105
|
-
export async function readVerifierAsync(key) {
|
|
106
|
-
return await readVerifier(key);
|
|
107
|
-
}
|
|
108
|
-
export async function writeVerifier(key, value) {
|
|
109
|
-
if (authStorageIsInMemory()) {
|
|
110
|
-
writeBrowserCookie(key, value, OAUTH_VERIFIER_MAX_AGE_SECONDS);
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
await writeLocalAsync(key, value);
|
|
114
|
-
}
|
|
115
|
-
function escapeRegExp(value) {
|
|
116
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
117
|
-
}
|
|
118
|
-
export function readBrowserCookie(name) {
|
|
119
|
-
if (typeof document === "undefined") {
|
|
120
|
-
return null;
|
|
121
|
-
}
|
|
122
|
-
const match = document.cookie.match(new RegExp(`(?:^|; )${escapeRegExp(name)}=([^;]*)`));
|
|
123
|
-
const raw = match?.[1];
|
|
124
|
-
if (!raw) {
|
|
125
|
-
return null;
|
|
39
|
+
export function isJwtExpiring(token, skewSeconds = 10, nowMs = Date.now()) {
|
|
40
|
+
const payload = token.split(".")[1];
|
|
41
|
+
if (!payload) {
|
|
42
|
+
return true;
|
|
126
43
|
}
|
|
127
44
|
try {
|
|
128
|
-
|
|
45
|
+
const base64 = payload.replace(/-/g, "+").replace(/_/g, "/");
|
|
46
|
+
const padded = base64 + "=".repeat((4 - base64.length % 4) % 4);
|
|
47
|
+
const json = typeof atob === "function" ? atob(padded) : globalThis.Buffer.from(padded, "base64").toString();
|
|
48
|
+
const exp = JSON.parse(json).exp;
|
|
49
|
+
if (typeof exp !== "number") {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
return exp * 1e3 - skewSeconds * 1e3 <= nowMs;
|
|
129
53
|
} catch {
|
|
130
|
-
return
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
export function writeBrowserCookie(name, value, maxAgeSeconds) {
|
|
134
|
-
if (typeof document === "undefined") {
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
const secure = typeof location !== "undefined" && location.protocol === "https:" ? "; Secure" : "";
|
|
138
|
-
if (value === null) {
|
|
139
|
-
document.cookie = `${name}=; Max-Age=0; Path=/; SameSite=Lax${secure}`;
|
|
140
|
-
return;
|
|
54
|
+
return true;
|
|
141
55
|
}
|
|
142
|
-
document.cookie = `${name}=${encodeURIComponent(value)}; Max-Age=${maxAgeSeconds}; Path=/; SameSite=Lax${secure}`;
|
|
143
56
|
}
|
|
144
|
-
export function
|
|
145
|
-
if (
|
|
146
|
-
return
|
|
147
|
-
}
|
|
148
|
-
const gate = options.shouldHandleCode ?? getConvexAuthClientOptions().shouldHandleCode;
|
|
149
|
-
if (gate === void 0) {
|
|
150
|
-
return true;
|
|
57
|
+
export function sessionKeyFromToken(token) {
|
|
58
|
+
if (!token) {
|
|
59
|
+
return "";
|
|
151
60
|
}
|
|
152
|
-
|
|
153
|
-
|
|
61
|
+
const payload = token.split(".")[1];
|
|
62
|
+
if (payload) {
|
|
63
|
+
try {
|
|
64
|
+
const base64 = payload.replace(/-/g, "+").replace(/_/g, "/");
|
|
65
|
+
const padded = base64 + "=".repeat((4 - base64.length % 4) % 4);
|
|
66
|
+
const json = typeof atob === "function" ? atob(padded) : globalThis.Buffer.from(padded, "base64").toString();
|
|
67
|
+
const claims = JSON.parse(json);
|
|
68
|
+
if (typeof claims.sub === "string" && claims.sub) {
|
|
69
|
+
return `${typeof claims.iss === "string" ? claims.iss : ""}|${claims.sub}`;
|
|
70
|
+
}
|
|
71
|
+
} catch {
|
|
72
|
+
}
|
|
154
73
|
}
|
|
155
|
-
return
|
|
74
|
+
return token;
|
|
156
75
|
}
|