use-convex 1.2.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 +120 -41
- package/dist/module.d.mts +73 -31
- package/dist/module.mjs +73 -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 -398
- 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/useConvexQueries.d.ts +36 -7
- package/dist/runtime/composables/useConvexQueries.js +37 -13
- 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 +208 -23
- 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 +9 -1
- package/dist/runtime/server/fetch.js +7 -10
- package/dist/runtime/utils/authClientOptions.d.ts +54 -0
- package/dist/runtime/utils/authClientOptions.js +10 -0
- package/dist/runtime/utils/authCookie.d.ts +8 -14
- package/dist/runtime/utils/authCookie.js +23 -27
- package/dist/runtime/utils/authStorage.d.ts +80 -42
- package/dist/runtime/utils/authStorage.js +56 -66
- package/dist/runtime/utils/context.d.ts +42 -6
- package/dist/runtime/utils/http.d.ts +7 -0
- package/dist/runtime/utils/http.js +5 -2
- package/dist/types.d.mts +6 -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
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
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.
|
|
11
|
+
*/
|
|
12
|
+
export type ConvexAuthTokenStorage = {
|
|
13
|
+
getItem: (key: string) => string | null | undefined | Promise<string | null | undefined>;
|
|
14
|
+
setItem: (key: string, value: string) => void | Promise<void>;
|
|
15
|
+
removeItem: (key: string) => void | Promise<void>;
|
|
16
|
+
};
|
|
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
|
+
};
|
|
30
|
+
export type ConvexAuthClientOptions = {
|
|
31
|
+
/**
|
|
32
|
+
* Custom token storage. Overrides `convex.auth.storage`.
|
|
33
|
+
*/
|
|
34
|
+
storage?: ConvexAuthTokenStorage;
|
|
35
|
+
/**
|
|
36
|
+
* Replaces the default ambient sign-ins (`[oauth()]`). Pass `[]` to
|
|
37
|
+
* disable OAuth callback handling, or include `convexOAuth()` alongside
|
|
38
|
+
* your own.
|
|
39
|
+
*/
|
|
40
|
+
ambientSignIns?: ConvexAmbientSignIn[];
|
|
41
|
+
/**
|
|
42
|
+
* Replace the page URL after an OAuth callback strips its params.
|
|
43
|
+
* Defaults to `history.replaceState`, then syncs `vue-router`.
|
|
44
|
+
*/
|
|
45
|
+
replaceUrl?: (url: string) => void;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Set runtime Convex Auth knobs. Merge is shallow — later calls override
|
|
49
|
+
* earlier keys.
|
|
50
|
+
*/
|
|
51
|
+
export declare function configureConvexAuth(options: ConvexAuthClientOptions): void;
|
|
52
|
+
export declare function getConvexAuthClientOptions(): ConvexAuthClientOptions;
|
|
53
|
+
/** @internal */
|
|
54
|
+
export declare function resetConvexAuthClientOptionsForTests(): void;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
let runtimeOverrides = {};
|
|
2
|
+
export function configureConvexAuth(options) {
|
|
3
|
+
runtimeOverrides = { ...runtimeOverrides, ...options };
|
|
4
|
+
}
|
|
5
|
+
export function getConvexAuthClientOptions() {
|
|
6
|
+
return { ...runtimeOverrides };
|
|
7
|
+
}
|
|
8
|
+
export function resetConvexAuthClientOptionsForTests() {
|
|
9
|
+
runtimeOverrides = {};
|
|
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,55 +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
|
-
export
|
|
13
|
-
|
|
14
|
-
|
|
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
|
+
};
|
|
15
20
|
export type ConvexAuthConfig = {
|
|
16
|
-
provider?:
|
|
17
|
-
cookie?: string;
|
|
21
|
+
provider?: 'convex-auth';
|
|
18
22
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* Prefer `true` in production. Does not make sessions XSS-proof.
|
|
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.
|
|
23
26
|
*/
|
|
24
|
-
|
|
25
|
-
/**
|
|
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 */
|
|
35
|
+
storageNamespace?: string;
|
|
36
|
+
/** @see ModuleAuthOptions.storage */
|
|
37
|
+
storage?: ConvexAuthStorageMode;
|
|
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;
|
|
27
71
|
};
|
|
28
|
-
export declare function storageNamespace(url: string): string;
|
|
29
|
-
export declare function storageKey(base: string, url: string): string;
|
|
30
|
-
/**
|
|
31
|
-
* Flatten FormData (or pass through a plain record) the same way the React
|
|
32
|
-
* Convex Auth client does before calling `auth:signIn`.
|
|
33
|
-
*/
|
|
34
|
-
export declare function flattenSignInParams(params?: FormData | Record<string, string>): Record<string, string>;
|
|
35
72
|
/**
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
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.
|
|
39
76
|
*/
|
|
40
77
|
export declare function resolveAuthCookieName(auth?: ConvexAuthConfig): string | undefined;
|
|
41
|
-
export declare function resolveAuthPresentCookieName(auth?: ConvexAuthConfig): string | undefined;
|
|
42
|
-
export declare function resolveAuthRefreshCookieName(auth?: ConvexAuthConfig): string | undefined;
|
|
43
|
-
export declare function isHttpOnlyAuth(auth?: ConvexAuthConfig): boolean;
|
|
44
78
|
/** Empty / missing cookies are not a session. */
|
|
45
79
|
export declare function cookieValueToSsrToken(value: string | null | undefined): string | undefined;
|
|
46
|
-
export declare function readLocal(key: string): string | null;
|
|
47
|
-
export declare function writeLocal(key: string, value: string | null): void;
|
|
48
80
|
/**
|
|
49
|
-
* Whether
|
|
50
|
-
*
|
|
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.
|
|
83
|
+
*/
|
|
84
|
+
export declare function isJwtExpiring(token: string, skewSeconds?: number, nowMs?: number): boolean;
|
|
85
|
+
/**
|
|
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.
|
|
51
92
|
*/
|
|
52
|
-
export declare function
|
|
53
|
-
code: string | null;
|
|
54
|
-
verifier: string | null;
|
|
55
|
-
}): boolean;
|
|
93
|
+
export declare function sessionKeyFromToken(token: string | null | undefined): string;
|
|
@@ -1,85 +1,75 @@
|
|
|
1
|
-
export const
|
|
2
|
-
export const
|
|
3
|
-
export const
|
|
4
|
-
export const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export
|
|
10
|
-
|
|
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";
|
|
11
12
|
}
|
|
12
|
-
export function
|
|
13
|
-
return
|
|
13
|
+
export function resolveAuthMode(auth) {
|
|
14
|
+
return auth?.mode ?? "ssr";
|
|
14
15
|
}
|
|
15
|
-
export function
|
|
16
|
-
|
|
17
|
-
return {};
|
|
18
|
-
}
|
|
19
|
-
if (typeof FormData !== "undefined" && params instanceof FormData) {
|
|
20
|
-
const out = {};
|
|
21
|
-
params.forEach((value, key) => {
|
|
22
|
-
if (typeof value === "string") {
|
|
23
|
-
out[key] = value;
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
return out;
|
|
27
|
-
}
|
|
28
|
-
return { ...params };
|
|
16
|
+
export function isSsrConvexAuth(auth) {
|
|
17
|
+
return isConvexAuth(auth) && resolveAuthMode(auth) === "ssr";
|
|
29
18
|
}
|
|
30
|
-
export function
|
|
31
|
-
|
|
32
|
-
return auth.cookie ?? HTTPONLY_JWT_COOKIE;
|
|
33
|
-
}
|
|
34
|
-
if (auth?.cookie) {
|
|
35
|
-
return auth.cookie;
|
|
36
|
-
}
|
|
37
|
-
if (auth?.provider === "convex-auth") {
|
|
38
|
-
return DEFAULT_CONVEX_AUTH_COOKIE;
|
|
39
|
-
}
|
|
40
|
-
return void 0;
|
|
19
|
+
export function resolveAuthApiNames(auth) {
|
|
20
|
+
return { ...DEFAULT_CONVEX_AUTH_API, ...auth?.api };
|
|
41
21
|
}
|
|
42
|
-
export function
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
+
};
|
|
47
29
|
}
|
|
48
|
-
export function
|
|
49
|
-
if (
|
|
50
|
-
return void 0;
|
|
30
|
+
export function resolveAuthCookieName(auth) {
|
|
31
|
+
if (isConvexAuth(auth)) {
|
|
32
|
+
return isSsrConvexAuth(auth) ? CONVEX_AUTH_JWT_COOKIE : void 0;
|
|
51
33
|
}
|
|
52
|
-
return
|
|
53
|
-
}
|
|
54
|
-
export function isHttpOnlyAuth(auth) {
|
|
55
|
-
return auth?.httpOnly === true;
|
|
34
|
+
return auth?.cookie || void 0;
|
|
56
35
|
}
|
|
57
36
|
export function cookieValueToSsrToken(value) {
|
|
58
37
|
return value || void 0;
|
|
59
38
|
}
|
|
60
|
-
export function
|
|
61
|
-
|
|
62
|
-
|
|
39
|
+
export function isJwtExpiring(token, skewSeconds = 10, nowMs = Date.now()) {
|
|
40
|
+
const payload = token.split(".")[1];
|
|
41
|
+
if (!payload) {
|
|
42
|
+
return true;
|
|
63
43
|
}
|
|
64
44
|
try {
|
|
65
|
-
|
|
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;
|
|
66
53
|
} catch {
|
|
67
|
-
return
|
|
54
|
+
return true;
|
|
68
55
|
}
|
|
69
56
|
}
|
|
70
|
-
export function
|
|
71
|
-
if (
|
|
72
|
-
return;
|
|
57
|
+
export function sessionKeyFromToken(token) {
|
|
58
|
+
if (!token) {
|
|
59
|
+
return "";
|
|
73
60
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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 {
|
|
79
72
|
}
|
|
80
|
-
} catch {
|
|
81
73
|
}
|
|
82
|
-
|
|
83
|
-
export function shouldConsumeOAuthCode(options) {
|
|
84
|
-
return options.code !== null && options.verifier !== null;
|
|
74
|
+
return token;
|
|
85
75
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { AuthTokenFetcher, ConvexClient, ConvexHttpClient } from 'convex/browser';
|
|
2
|
-
import type {
|
|
2
|
+
import type { FunctionReference } from 'convex/server';
|
|
3
|
+
import type { ComputedRef, InjectionKey, Ref, ShallowRef } from 'vue';
|
|
4
|
+
import type { CreateHttpClientOptions } from './http.js';
|
|
3
5
|
export interface ConvexAuthContext {
|
|
4
6
|
/**
|
|
5
7
|
* Whether useConvexAuth({ fetchToken }) has been called.
|
|
@@ -18,6 +20,36 @@ export interface ConvexAuthContext {
|
|
|
18
20
|
isAuthenticated: Ref<boolean>;
|
|
19
21
|
isRefreshing: Ref<boolean>;
|
|
20
22
|
}
|
|
23
|
+
/** Snapshot of the Convex Auth client (`AuthState` in `@convex-dev/auth`). */
|
|
24
|
+
export interface ConvexAuthSnapshot {
|
|
25
|
+
isLoading: boolean;
|
|
26
|
+
isAuthenticated: boolean;
|
|
27
|
+
token: string | null;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Runs a method's sign-in function. Direct to the deployment in SPA mode,
|
|
31
|
+
* through the Nitro auth proxy in SSR mode (which moves the refresh token
|
|
32
|
+
* into an httpOnly cookie).
|
|
33
|
+
*/
|
|
34
|
+
export interface ConvexAuthSignInApi {
|
|
35
|
+
mutation: (fn: FunctionReference<'mutation'>, args: Record<string, unknown>) => Promise<any>;
|
|
36
|
+
action: (fn: FunctionReference<'action'>, args: Record<string, unknown>) => Promise<any>;
|
|
37
|
+
}
|
|
38
|
+
/** First-party Convex Auth v2 binding, set by the auth client plugin. */
|
|
39
|
+
export interface ConvexAuthBinding {
|
|
40
|
+
mode: 'ssr' | 'spa';
|
|
41
|
+
state: ShallowRef<ConvexAuthSnapshot>;
|
|
42
|
+
signInApi: ConvexAuthSignInApi;
|
|
43
|
+
/** Adopt a session returned by a method's sign-in function. */
|
|
44
|
+
setSession: (session: {
|
|
45
|
+
accessToken: string;
|
|
46
|
+
userId: string;
|
|
47
|
+
[key: string]: unknown;
|
|
48
|
+
}) => Promise<void>;
|
|
49
|
+
signOut: () => Promise<void>;
|
|
50
|
+
/** Values an ambient sign-in (e.g. OAuth) publishes, read reactively. */
|
|
51
|
+
ambientValue: <T>(id: string, key: string) => Readonly<Ref<T | undefined>>;
|
|
52
|
+
}
|
|
21
53
|
export interface ConvexNuxtContext {
|
|
22
54
|
url: string;
|
|
23
55
|
/**
|
|
@@ -25,21 +57,25 @@ export interface ConvexNuxtContext {
|
|
|
25
57
|
*/
|
|
26
58
|
client: ConvexClient | null;
|
|
27
59
|
/**
|
|
28
|
-
* JWT
|
|
29
|
-
*
|
|
60
|
+
* JWT for HttpClient snapshots: the SSR session token (Convex Auth SSR
|
|
61
|
+
* mode or a BYO cookie), then the live Convex Auth access token on the
|
|
62
|
+
* client. Reactive so sign-in/out re-runs HttpClient fetches.
|
|
30
63
|
*/
|
|
31
64
|
ssrToken: ComputedRef<string | undefined>;
|
|
32
65
|
/**
|
|
33
66
|
* Shared auth state for useConvexAuth.
|
|
34
67
|
*/
|
|
35
68
|
auth: ConvexAuthContext;
|
|
69
|
+
/**
|
|
70
|
+
* Convex Auth v2 client binding (`convex.auth.provider: 'convex-auth'`,
|
|
71
|
+
* browser only). `null` on the server and for BYO providers.
|
|
72
|
+
*/
|
|
73
|
+
convexAuth?: ConvexAuthBinding | null;
|
|
36
74
|
/**
|
|
37
75
|
* Create a fresh HttpClient for one-shot fetches (SSR / Nitro / refresh).
|
|
38
76
|
* Prefer a new client per call — HttpClient is stateful.
|
|
39
77
|
*/
|
|
40
|
-
createHttpClient: (options?:
|
|
41
|
-
token?: string;
|
|
42
|
-
}) => ConvexHttpClient;
|
|
78
|
+
createHttpClient: (options?: CreateHttpClientOptions) => ConvexHttpClient;
|
|
43
79
|
}
|
|
44
80
|
export declare const convexNuxtKey: InjectionKey<ConvexNuxtContext>;
|
|
45
81
|
export declare function createAuthContext(): ConvexAuthContext;
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { ConvexHttpClient } from 'convex/browser';
|
|
2
2
|
export interface CreateHttpClientOptions {
|
|
3
3
|
token?: string;
|
|
4
|
+
/**
|
|
5
|
+
* Deploy / admin key for privileged HttpClient calls (Next.js
|
|
6
|
+
* `fetchQuery(..., { adminToken })` parity). Uses `Authorization: Convex …`
|
|
7
|
+
* and clears any user JWT. Prefer per-request secrets — never put this in
|
|
8
|
+
* public runtime config.
|
|
9
|
+
*/
|
|
10
|
+
adminToken?: string;
|
|
4
11
|
skipConvexDeploymentUrlCheck?: boolean;
|
|
5
12
|
}
|
|
6
13
|
/**
|
|
@@ -2,9 +2,12 @@ import { ConvexHttpClient } from "convex/browser";
|
|
|
2
2
|
export function createHttpClient(url, options = {}) {
|
|
3
3
|
const client = new ConvexHttpClient(url, {
|
|
4
4
|
skipConvexDeploymentUrlCheck: options.skipConvexDeploymentUrlCheck,
|
|
5
|
-
...options.token ? { auth: options.token } : {}
|
|
5
|
+
...options.token && !options.adminToken ? { auth: options.token } : {}
|
|
6
6
|
});
|
|
7
|
-
if (options.
|
|
7
|
+
if (options.adminToken) {
|
|
8
|
+
;
|
|
9
|
+
client.setAdminAuth(options.adminToken);
|
|
10
|
+
} else if (options.token) {
|
|
8
11
|
client.setAuth(options.token);
|
|
9
12
|
}
|
|
10
13
|
;
|
package/dist/types.d.mts
CHANGED
|
@@ -4,7 +4,7 @@ declare module '@nuxt/schema' {
|
|
|
4
4
|
interface PublicRuntimeConfig extends ModulePublicRuntimeConfig {}
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
export { type
|
|
7
|
+
export { type ConvexAuthSession, type ConvexSignInResult, type OAuthCompleteResult, type OAuthFlowError, type OAuthProviderRefs, type OAuthSignInOptions, type OAuthStartResult, type UseAuthReturn } from '../dist/runtime/composables/useAuth.js'
|
|
8
8
|
|
|
9
9
|
export { type ConvexQueryArgs, type UseConvexQueryOptions, type UseConvexQueryReturn } from '../dist/runtime/composables/useConvexQuery.js'
|
|
10
10
|
|
|
@@ -18,7 +18,7 @@ export { type ConvexR2UploadApi, type ConvexR2UploadProgress } from '../dist/run
|
|
|
18
18
|
|
|
19
19
|
export { type PaginatedQueryArgs, type PaginatedQueryItem, type PaginatedQueryReference, type PaginationStatus, type UseConvexPaginatedQueryOptions, type UseConvexPaginatedQueryReturn } from '../dist/runtime/composables/useConvexPaginatedQuery.js'
|
|
20
20
|
|
|
21
|
-
export { type ConvexQueriesRequest, type ConvexQueriesResult, type ConvexQueryRequestEntry } from '../dist/runtime/composables/useConvexQueries.js'
|
|
21
|
+
export { type ConvexQueriesRequest, type ConvexQueriesResult, type ConvexQueryRequestEntry, type UseConvexQueriesOptions } from '../dist/runtime/composables/useConvexQueries.js'
|
|
22
22
|
|
|
23
23
|
export { type ConvexFetchOptions } from '../dist/runtime/server/fetch.js'
|
|
24
24
|
|
|
@@ -30,6 +30,10 @@ export { type ConnectionState } from '../dist/runtime/composables/useConvexConne
|
|
|
30
30
|
|
|
31
31
|
export { type ConvexGate } from '../dist/runtime/composables/useConvexGate.js'
|
|
32
32
|
|
|
33
|
+
export { type ConvexAmbientSignIn, type ConvexAuthClientOptions, type ConvexAuthStorageMode, type ConvexAuthTokenStorage, type configureConvexAuth } from '../dist/runtime/utils/authClientOptions.js'
|
|
34
|
+
|
|
35
|
+
export { type ConvexAuthServerRuntimeConfig } from '../dist/runtime/utils/authStorage.js'
|
|
36
|
+
|
|
33
37
|
export { default } from './module.mjs'
|
|
34
38
|
|
|
35
39
|
export { type ModuleAuthOptions, type ModuleOptions, type ModulePublicRuntimeConfig } from './module.mjs'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "use-convex",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "First-class Convex integration for Nuxt",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -44,13 +44,12 @@
|
|
|
44
44
|
"h3": "^1.15.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@auth
|
|
48
|
-
"@convex-dev/auth": "^0.0.95",
|
|
47
|
+
"@convex-dev/auth": "^2.0.0",
|
|
49
48
|
"@nuxt/module-builder": "^1.0.0",
|
|
50
49
|
"@nuxt/schema": "^4.0.0",
|
|
51
50
|
"@nuxt/test-utils": "^3.23.0",
|
|
52
51
|
"@types/node": "^26.5.0",
|
|
53
|
-
"convex": "^1.
|
|
52
|
+
"convex": "^1.48.0",
|
|
54
53
|
"convex-test": "^0.0.56",
|
|
55
54
|
"happy-dom": "^20.14.0",
|
|
56
55
|
"nitropack": "^2.13.0",
|
|
@@ -63,10 +62,16 @@
|
|
|
63
62
|
"vue-tsc": "^3.0.0"
|
|
64
63
|
},
|
|
65
64
|
"peerDependencies": {
|
|
66
|
-
"convex": "^
|
|
65
|
+
"@convex-dev/auth": "^2.0.0",
|
|
66
|
+
"convex": "^1.48.0",
|
|
67
67
|
"nuxt": "^4.0.0",
|
|
68
68
|
"vue": "^3.5.0"
|
|
69
69
|
},
|
|
70
|
+
"peerDependenciesMeta": {
|
|
71
|
+
"@convex-dev/auth": {
|
|
72
|
+
"optional": true
|
|
73
|
+
}
|
|
74
|
+
},
|
|
70
75
|
"packageManager": "pnpm@10.0.0",
|
|
71
76
|
"pnpm": {
|
|
72
77
|
"overrides": {
|