@robelest/convex-auth 0.0.4-preview.29 → 0.0.4-preview.30

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.
Files changed (49) hide show
  1. package/dist/bin.js +34 -1
  2. package/dist/browser/passkey.js +2 -2
  3. package/dist/client/core/types.d.ts +4 -15
  4. package/dist/client/factors/device.js +3 -3
  5. package/dist/client/factors/totp.js +8 -8
  6. package/dist/client/index.js +7 -7
  7. package/dist/component/convex.config.d.ts +2 -2
  8. package/dist/component/model.d.ts +25 -25
  9. package/dist/component/schema.d.ts +289 -289
  10. package/dist/core/index.d.ts +5 -24
  11. package/dist/core/index.js +3 -16
  12. package/dist/server/auth-context.d.ts +1 -1
  13. package/dist/server/auth-context.js +14 -1
  14. package/dist/server/auth.d.ts +3 -17
  15. package/dist/server/auth.js +2 -7
  16. package/dist/server/config.js +10 -0
  17. package/dist/server/context.js +2 -4
  18. package/dist/server/contract.d.ts +1 -1
  19. package/dist/server/convexIdentity.d.ts +15 -0
  20. package/dist/server/convexIdentity.js +1 -0
  21. package/dist/server/core.js +0 -13
  22. package/dist/server/device.js +13 -12
  23. package/dist/server/env.js +10 -2
  24. package/dist/server/http.d.ts +1 -1
  25. package/dist/server/identity.js +30 -4
  26. package/dist/server/index.d.ts +1 -0
  27. package/dist/server/index.js +1 -0
  28. package/dist/server/mounts.d.ts +79 -79
  29. package/dist/server/mutations/refresh.js +38 -7
  30. package/dist/server/mutations/signin.js +12 -2
  31. package/dist/server/mutations/signout.js +27 -10
  32. package/dist/server/mutations/store.js +1 -1
  33. package/dist/server/oauth/factory.js +2 -1
  34. package/dist/server/passkey.js +12 -13
  35. package/dist/server/prefetch.js +8 -8
  36. package/dist/server/runtime.d.ts +19 -25
  37. package/dist/server/runtime.js +7 -40
  38. package/dist/server/sessions.d.ts +2 -1
  39. package/dist/server/sessions.js +21 -11
  40. package/dist/server/signin.js +17 -16
  41. package/dist/server/sso/domain.d.ts +1 -1
  42. package/dist/server/telemetry.js +58 -0
  43. package/dist/server/tokens.js +24 -4
  44. package/dist/server/totp.js +13 -11
  45. package/dist/server/types.d.ts +58 -2
  46. package/dist/server/utils/span.js +10 -1
  47. package/dist/shared/authResults.d.ts +16 -0
  48. package/package.json +6 -3
  49. package/dist/server/constants.js +0 -6
package/dist/bin.js CHANGED
@@ -6266,7 +6266,7 @@ async function generateKeys() {
6266
6266
  ...publicKey
6267
6267
  }] });
6268
6268
  return {
6269
- JWT_PRIVATE_KEY: `${privateKey.trimEnd().replace(/\n/g, " ")}`,
6269
+ JWT_PRIVATE_KEY: privateKey.trimEnd(),
6270
6270
  JWKS: jwks,
6271
6271
  AUTH_SECRET_ENCRYPTION_KEY: randomBytes(32).toString("base64url")
6272
6272
  };
@@ -6506,6 +6506,7 @@ async function runSetup(options) {
6506
6506
  await configureConvexConfig(config);
6507
6507
  await initializeAuth(config);
6508
6508
  await initializeAuthCore(config);
6509
+ await initializeAuthConfig(config);
6509
6510
  await configureHttp(config);
6510
6511
  if (options.variables !== void 0) await configureOtherVariables(config, options.variables);
6511
6512
  else printFinalSuccessMessage(config);
@@ -6819,6 +6820,38 @@ export const auth = createAuthContext(components.auth);
6819
6820
  O.success(`Created ${newPath}`);
6820
6821
  }
6821
6822
  }
6823
+ async function initializeAuthConfig(config) {
6824
+ logStep(config, "Initialize auth.config file");
6825
+ const sourceTemplate = `\
6826
+ export default {$$
6827
+ providers: [$$
6828
+ {$$
6829
+ domain: process.env.CONVEX_SITE_URL,$$
6830
+ applicationID: "convex",$$
6831
+ },$$
6832
+ ],$$
6833
+ };
6834
+ `;
6835
+ const source = templateToSource(sourceTemplate);
6836
+ const authConfigPath = path.join(config.convexFolderPath, "auth.config");
6837
+ const existingPath = existingNonEmptySourcePath(authConfigPath);
6838
+ if (existingPath !== null) if (doesAlreadyMatchTemplate(readFileSync(existingPath, "utf8"), sourceTemplate)) O.success(`${existingPath} is already set up.`);
6839
+ else {
6840
+ O.info(`You already have ${existingPath}. Make sure it trusts CONVEX_SITE_URL as the Convex auth issuer:`);
6841
+ O.message(indent(`\n${source}\n`));
6842
+ const ready = await ot({ message: "Ready to continue?" });
6843
+ handleCancel(ready);
6844
+ if (!ready) {
6845
+ pt("Setup cancelled.");
6846
+ process$1.exit(1);
6847
+ }
6848
+ }
6849
+ else {
6850
+ const newPath = config.usesTypeScript ? `${authConfigPath}.ts` : `${authConfigPath}.js`;
6851
+ writeFileSync(newPath, source);
6852
+ O.success(`Created ${newPath}`);
6853
+ }
6854
+ }
6822
6855
  async function configureHttp(config) {
6823
6856
  logStep(config, "Configure http file");
6824
6857
  const sourceTemplate = `\
@@ -8,7 +8,7 @@ function createPasskeyClient(deps) {
8
8
  if (result.kind !== "signedIn") return { kind: "started" };
9
9
  return await setTokenAndMaybeWait(proxy ? {
10
10
  shouldStore: false,
11
- tokens: result.tokens === null ? null : { token: result.tokens.token },
11
+ tokens: result.session === null ? null : { token: result.session.token },
12
12
  waitForHandshake: true,
13
13
  context: {
14
14
  provider: "passkey",
@@ -16,7 +16,7 @@ function createPasskeyClient(deps) {
16
16
  }
17
17
  } : {
18
18
  shouldStore: true,
19
- tokens: result.tokens,
19
+ tokens: result.session,
20
20
  waitForHandshake: true,
21
21
  context: {
22
22
  provider: "passkey",
@@ -1,3 +1,4 @@
1
+ import { AuthTokens, DeviceCodePayload } from "../../shared/authResults.js";
1
2
  import { ConvexError, Value } from "convex/values";
2
3
  import { FunctionReference } from "convex/server";
3
4
 
@@ -76,7 +77,7 @@ interface ClientAdapterDeps {
76
77
  proxyFetch: (body: Record<string, unknown>) => Promise<unknown>;
77
78
  setTokenAndMaybeWait: (args: {
78
79
  shouldStore: true;
79
- tokens: AuthSession | null;
80
+ tokens: AuthTokens | null;
80
81
  waitForHandshake: boolean;
81
82
  context: {
82
83
  provider?: string;
@@ -97,28 +98,17 @@ interface ClientAdapterDeps {
97
98
  interface ClientAdapterFactories {
98
99
  passkey?: (deps: ClientAdapterDeps) => PasskeyClient;
99
100
  }
100
- type AuthSession = {
101
- token: string;
102
- refreshToken: string;
103
- };
101
+ type DeviceCodeResult = DeviceCodePayload;
104
102
  /**
105
103
  * Device code response returned when signing in with the `"device"` provider.
106
104
  *
107
105
  * The device displays the `userCode` (or `verificationUriComplete`) and
108
106
  * polls via `auth.device.poll()` until the user authorizes.
109
107
  */
110
- type DeviceCodeResult = {
111
- /** High-entropy device code used for polling (keep secret). */deviceCode: string; /** Short human-readable code the user enters (e.g. "WDJB-MJHT"). */
112
- userCode: string; /** Base verification URL (e.g. "https://myapp.com/device"). */
113
- verificationUri: string; /** Verification URL with user code pre-filled as `?code=XXXX-XXXX`. */
114
- verificationUriComplete: string; /** Lifetime of the codes in seconds. */
115
- expiresIn: number; /** Minimum polling interval in seconds. */
116
- interval: number;
117
- };
118
108
  /**
119
109
  * Result of a `signIn` call.
120
110
  *
121
- * - `kind: "signedIn"` — credentials were accepted and the user is authenticated.
111
+ * - `kind: "signedIn"` — credentials were accepted and a client session is now available.
122
112
  * - `kind: "redirect"` — OAuth flow initiated; redirect the user to `redirect.toString()`.
123
113
  * - `kind: "totpRequired"` — credentials valid but 2FA is needed; call `auth.totp.verify()`.
124
114
  * - `kind: "deviceCode"` — device flow initiated; display the code and poll via `auth.device.poll()`.
@@ -163,7 +153,6 @@ type AuthState = {
163
153
  type AuthApiRefs<HasPasskey extends boolean = boolean, HasTotp extends boolean = boolean, HasDevice extends boolean = boolean> = {
164
154
  signIn: FunctionReference<"action", "public", Record<string, Value>, unknown>;
165
155
  signOut: FunctionReference<"action", "public", Record<string, Value>, unknown>;
166
- store: FunctionReference<"mutation", "public", Record<string, Value>, unknown>;
167
156
  };
168
157
  /**
169
158
  * Passkey (WebAuthn) client-side helpers.
@@ -45,10 +45,10 @@ function createDeviceClient(deps) {
45
45
  throw error;
46
46
  }
47
47
  if (pollResult === null) continue;
48
- if (isSignedInResult(pollResult) && pollResult.tokens) {
48
+ if (isSignedInResult(pollResult) && pollResult.session) {
49
49
  if (proxy) await setTokenAndMaybeWait({
50
50
  shouldStore: false,
51
- tokens: pollResult.tokens === null ? null : { token: pollResult.tokens.token },
51
+ tokens: pollResult.session === null ? null : { token: pollResult.session.token },
52
52
  waitForHandshake: true,
53
53
  context: {
54
54
  provider: "device",
@@ -57,7 +57,7 @@ function createDeviceClient(deps) {
57
57
  });
58
58
  else await setTokenAndMaybeWait({
59
59
  shouldStore: true,
60
- tokens: pollResult.tokens ?? null,
60
+ tokens: pollResult.session ?? null,
61
61
  waitForHandshake: true,
62
62
  context: {
63
63
  provider: "device",
@@ -56,9 +56,9 @@ function createTotpClient(deps) {
56
56
  verifier: opts.verifier
57
57
  }
58
58
  });
59
- if (isSignedInResult(result$1) && result$1.tokens) await setTokenAndMaybeWait({
59
+ if (isSignedInResult(result$1) && result$1.session) await setTokenAndMaybeWait({
60
60
  shouldStore: false,
61
- tokens: result$1.tokens === null ? null : { token: result$1.tokens.token },
61
+ tokens: result$1.session === null ? null : { token: result$1.session.token },
62
62
  waitForHandshake: true,
63
63
  context: {
64
64
  provider: "totp",
@@ -72,9 +72,9 @@ function createTotpClient(deps) {
72
72
  params,
73
73
  verifier: opts.verifier
74
74
  });
75
- if (isSignedInResult(result) && result.tokens) await setTokenAndMaybeWait({
75
+ if (isSignedInResult(result) && result.session) await setTokenAndMaybeWait({
76
76
  shouldStore: true,
77
- tokens: result.tokens ?? null,
77
+ tokens: result.session ?? null,
78
78
  waitForHandshake: true,
79
79
  context: {
80
80
  provider: "totp",
@@ -96,9 +96,9 @@ function createTotpClient(deps) {
96
96
  verifier: opts.verifier
97
97
  }
98
98
  });
99
- if (isSignedInResult(result$1) && result$1.tokens) await setTokenAndMaybeWait({
99
+ if (isSignedInResult(result$1) && result$1.session) await setTokenAndMaybeWait({
100
100
  shouldStore: false,
101
- tokens: result$1.tokens === null ? null : { token: result$1.tokens.token },
101
+ tokens: result$1.session === null ? null : { token: result$1.session.token },
102
102
  waitForHandshake: true,
103
103
  context: {
104
104
  provider: "totp",
@@ -112,9 +112,9 @@ function createTotpClient(deps) {
112
112
  params,
113
113
  verifier: opts.verifier
114
114
  });
115
- if (isSignedInResult(result) && result.tokens) await setTokenAndMaybeWait({
115
+ if (isSignedInResult(result) && result.session) await setTokenAndMaybeWait({
116
116
  shouldStore: true,
117
- tokens: result.tokens ?? null,
117
+ tokens: result.session ?? null,
118
118
  waitForHandshake: true,
119
119
  context: {
120
120
  provider: "totp",
@@ -361,13 +361,13 @@ function client(options) {
361
361
  const verifyCodeAndSetToken = async (args, opts) => {
362
362
  const result = await verifyCode(args);
363
363
  if (result.kind !== "signedIn") throw new Error("Code exchange did not return tokens.");
364
- const { tokens } = result;
364
+ const { session } = result;
365
365
  await setToken({
366
366
  shouldStore: true,
367
- tokens: tokens ?? null,
367
+ tokens: session ?? null,
368
368
  resyncConvexAuth: opts?.resyncConvexAuth
369
369
  });
370
- return tokens !== null;
370
+ return session !== null;
371
371
  };
372
372
  const normalizeDeviceCodeResult = (device_code) => {
373
373
  const input = device_code;
@@ -441,7 +441,7 @@ function client(options) {
441
441
  };
442
442
  if (result.kind === "signedIn") return await setTokenAndMaybeWait(resultOptions.shouldStore ? {
443
443
  shouldStore: true,
444
- tokens: result.tokens,
444
+ tokens: result.session,
445
445
  waitForHandshake: true,
446
446
  context: {
447
447
  provider,
@@ -449,7 +449,7 @@ function client(options) {
449
449
  }
450
450
  } : {
451
451
  shouldStore: false,
452
- tokens: result.tokens === null ? null : { token: result.tokens.token },
452
+ tokens: result.session === null ? null : { token: result.session.token },
453
453
  waitForHandshake: true,
454
454
  context: {
455
455
  provider,
@@ -538,9 +538,9 @@ function client(options) {
538
538
  action: "auth:signIn",
539
539
  args: { refreshToken: true }
540
540
  }), isRetriableProxyRefreshError);
541
- if (isSignedInResult(result) && result.tokens) await setToken({
541
+ if (isSignedInResult(result) && result.session) await setToken({
542
542
  shouldStore: false,
543
- tokens: { token: result.tokens.token },
543
+ tokens: { token: result.session.token },
544
544
  resyncConvexAuth: false
545
545
  });
546
546
  else await setToken({
@@ -1,7 +1,7 @@
1
- import * as convex_server7 from "convex/server";
1
+ import * as convex_server0 from "convex/server";
2
2
 
3
3
  //#region src/component/convex.config.d.ts
4
- declare const component: convex_server7.ComponentDefinition<any>;
4
+ declare const component: convex_server0.ComponentDefinition<any>;
5
5
  //#endregion
6
6
  export { component as default };
7
7
  //# sourceMappingURL=convex.config.d.ts.map
@@ -1,7 +1,7 @@
1
- import * as convex_values478 from "convex/values";
1
+ import * as convex_values480 from "convex/values";
2
2
 
3
3
  //#region src/component/model.d.ts
4
- declare const vApiKeyDoc: convex_values478.VObject<{
4
+ declare const vApiKeyDoc: convex_values480.VObject<{
5
5
  lastUsedAt?: number | undefined;
6
6
  expiresAt?: number | undefined;
7
7
  rateLimit?: {
@@ -16,7 +16,7 @@ declare const vApiKeyDoc: convex_values478.VObject<{
16
16
  _creationTime: number;
17
17
  name: string;
18
18
  revoked: boolean;
19
- userId: convex_values478.GenericId<"User">;
19
+ userId: convex_values480.GenericId<"User">;
20
20
  prefix: string;
21
21
  hashedKey: string;
22
22
  scopes: {
@@ -24,43 +24,43 @@ declare const vApiKeyDoc: convex_values478.VObject<{
24
24
  actions: string[];
25
25
  }[];
26
26
  createdAt: number;
27
- _id: convex_values478.GenericId<"ApiKey">;
27
+ _id: convex_values480.GenericId<"ApiKey">;
28
28
  }, {
29
- userId: convex_values478.VId<convex_values478.GenericId<"User">, "required">;
30
- prefix: convex_values478.VString<string, "required">;
31
- hashedKey: convex_values478.VString<string, "required">;
32
- name: convex_values478.VString<string, "required">;
33
- scopes: convex_values478.VArray<{
29
+ userId: convex_values480.VId<convex_values480.GenericId<"User">, "required">;
30
+ prefix: convex_values480.VString<string, "required">;
31
+ hashedKey: convex_values480.VString<string, "required">;
32
+ name: convex_values480.VString<string, "required">;
33
+ scopes: convex_values480.VArray<{
34
34
  resource: string;
35
35
  actions: string[];
36
- }[], convex_values478.VObject<{
36
+ }[], convex_values480.VObject<{
37
37
  resource: string;
38
38
  actions: string[];
39
39
  }, {
40
- resource: convex_values478.VString<string, "required">;
41
- actions: convex_values478.VArray<string[], convex_values478.VString<string, "required">, "required">;
40
+ resource: convex_values480.VString<string, "required">;
41
+ actions: convex_values480.VArray<string[], convex_values480.VString<string, "required">, "required">;
42
42
  }, "required", "resource" | "actions">, "required">;
43
- rateLimit: convex_values478.VObject<{
43
+ rateLimit: convex_values480.VObject<{
44
44
  maxRequests: number;
45
45
  windowMs: number;
46
46
  } | undefined, {
47
- maxRequests: convex_values478.VFloat64<number, "required">;
48
- windowMs: convex_values478.VFloat64<number, "required">;
47
+ maxRequests: convex_values480.VFloat64<number, "required">;
48
+ windowMs: convex_values480.VFloat64<number, "required">;
49
49
  }, "optional", "maxRequests" | "windowMs">;
50
- rateLimitState: convex_values478.VObject<{
50
+ rateLimitState: convex_values480.VObject<{
51
51
  attemptsLeft: number;
52
52
  lastAttemptTime: number;
53
53
  } | undefined, {
54
- attemptsLeft: convex_values478.VFloat64<number, "required">;
55
- lastAttemptTime: convex_values478.VFloat64<number, "required">;
54
+ attemptsLeft: convex_values480.VFloat64<number, "required">;
55
+ lastAttemptTime: convex_values480.VFloat64<number, "required">;
56
56
  }, "optional", "attemptsLeft" | "lastAttemptTime">;
57
- expiresAt: convex_values478.VFloat64<number | undefined, "optional">;
58
- lastUsedAt: convex_values478.VFloat64<number | undefined, "optional">;
59
- createdAt: convex_values478.VFloat64<number, "required">;
60
- revoked: convex_values478.VBoolean<boolean, "required">;
61
- metadata: convex_values478.VAny<any, "optional", string>;
62
- _id: convex_values478.VId<convex_values478.GenericId<"ApiKey">, "required">;
63
- _creationTime: convex_values478.VFloat64<number, "required">;
57
+ expiresAt: convex_values480.VFloat64<number | undefined, "optional">;
58
+ lastUsedAt: convex_values480.VFloat64<number | undefined, "optional">;
59
+ createdAt: convex_values480.VFloat64<number, "required">;
60
+ revoked: convex_values480.VBoolean<boolean, "required">;
61
+ metadata: convex_values480.VAny<any, "optional", string>;
62
+ _id: convex_values480.VId<convex_values480.GenericId<"ApiKey">, "required">;
63
+ _creationTime: convex_values480.VFloat64<number, "required">;
64
64
  }, "required", "_creationTime" | "name" | "revoked" | "lastUsedAt" | "expiresAt" | "userId" | "prefix" | "hashedKey" | "scopes" | "rateLimit" | "rateLimitState" | "createdAt" | "metadata" | "_id" | "rateLimit.maxRequests" | "rateLimit.windowMs" | "rateLimitState.attemptsLeft" | "rateLimitState.lastAttemptTime" | `metadata.${string}`>;
65
65
  //#endregion
66
66
  export { vApiKeyDoc };