@samebase/identity-broker 0.1.0 → 0.3.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.
Files changed (36) hide show
  1. package/README.md +17 -3
  2. package/dist/cli/index.js +18 -5
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/client/connectors/google.d.ts +5 -1
  5. package/dist/client/connectors/google.js +6 -1
  6. package/dist/client/connectors/google.js.map +1 -1
  7. package/dist/client/connectors/types.d.ts +5 -0
  8. package/dist/client/html.d.ts +5 -1
  9. package/dist/client/html.js +17 -7
  10. package/dist/client/html.js.map +1 -1
  11. package/dist/client/index.d.ts +16 -1
  12. package/dist/client/index.js +201 -43
  13. package/dist/client/index.js.map +1 -1
  14. package/dist/client/keys.d.ts +5 -0
  15. package/dist/client/keys.js +8 -0
  16. package/dist/client/keys.js.map +1 -1
  17. package/dist/client/protocol.d.ts +7 -2
  18. package/dist/client/protocol.js +39 -11
  19. package/dist/client/protocol.js.map +1 -1
  20. package/dist/client/responses.d.ts +7 -1
  21. package/dist/client/responses.js +8 -3
  22. package/dist/client/responses.js.map +1 -1
  23. package/dist/component/_generated/component.d.ts +28 -1
  24. package/dist/component/authRequests.d.ts +30 -4
  25. package/dist/component/authRequests.js +92 -11
  26. package/dist/component/authRequests.js.map +1 -1
  27. package/dist/component/lifecycle.d.ts +14 -3
  28. package/dist/component/lifecycle.js +106 -49
  29. package/dist/component/lifecycle.js.map +1 -1
  30. package/dist/component/registration.d.ts +12 -0
  31. package/dist/component/registration.js +33 -0
  32. package/dist/component/registration.js.map +1 -1
  33. package/dist/component/schema.d.ts +119 -10
  34. package/dist/component/schema.js +21 -2
  35. package/dist/component/schema.js.map +1 -1
  36. package/package.json +1 -1
package/README.md CHANGED
@@ -18,6 +18,9 @@ registers each deployment as a client at deploy time and never touches GitHub or
18
18
  your own action. `github()`, `google()` and `email()` are included.
19
19
  - A hub is a small Convex app that mounts the component. Fork
20
20
  [samebase/identity-hub](https://github.com/samebase/identity-hub) for one.
21
+ - `@samebase/alchemy-identity-hub`: an Alchemy v2 resource, `IdentityHub.Client`, that registers a
22
+ deployment as a client at deploy time. See
23
+ [packages/alchemy-identity-hub](https://github.com/samebase/identity-broker/tree/main/packages/alchemy-identity-hub).
21
24
 
22
25
  ## Mount it
23
26
 
@@ -62,12 +65,23 @@ export default http;
62
65
  ```ts
63
66
  // convex/identityBroker.ts: administration for `npx convex run`
64
67
  import { broker } from "./http";
65
- export const { createApp, mintRegistrationToken, deleteApp, listApps, listClients, cleanup } =
66
- broker.admin();
68
+ export const {
69
+ createApp,
70
+ mintRegistrationToken,
71
+ listRegistrationTokens,
72
+ revokeRegistrationToken,
73
+ setAllowedCallbackHosts,
74
+ deleteClient,
75
+ deleteApp,
76
+ listApps,
77
+ listClients,
78
+ cleanup,
79
+ } = broker.admin();
67
80
  ```
68
81
 
69
82
  Keys: `npx identity-broker keys` prints the value for `IDENTITY_BROKER_KEYS`; `keys --rotate`
70
- advances it.
83
+ advances it, and `keys --rotate --no-overlap` replaces a compromised key at once. Back up the key
84
+ set: its salt makes every `sub`. `parseKeySet` checks a value before a deploy.
71
85
 
72
86
  ## Register an app's deployments
73
87
 
package/dist/cli/index.js CHANGED
@@ -1,7 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { createKeySet, parseKeySet, rotateKeySet } from "../client/keys.js";
3
- const USAGE = `identity-broker keys print a new key set for IDENTITY_BROKER_KEYS
4
- identity-broker keys --rotate read the current key set on stdin, print the rotated one`;
2
+ import { createKeySet, parseKeySet, rotateKeySet, rotateKeySetWithoutOverlap, } from "../client/keys.js";
3
+ const USAGE = `identity-broker keys print a new key set for IDENTITY_BROKER_KEYS
4
+ identity-broker keys --rotate read the current key set on stdin, print the rotated
5
+ one; the retired public key stays for 14 days
6
+ identity-broker keys --rotate --no-overlap the same after a key compromise: retired keys are
7
+ dropped at once; the salt is kept`;
5
8
  async function readStdin() {
6
9
  const chunks = [];
7
10
  for await (const chunk of process.stdin) {
@@ -14,8 +17,18 @@ async function main(argv) {
14
17
  console.error(USAGE);
15
18
  return 2;
16
19
  }
17
- if (argv.includes("--rotate")) {
18
- const rotated = await rotateKeySet(parseKeySet(await readStdin()));
20
+ const rotate = argv.includes("--rotate");
21
+ const noOverlap = argv.includes("--no-overlap");
22
+ // Without --rotate, --no-overlap would print a new key set with a new salt: every sub changes.
23
+ if (noOverlap && !rotate) {
24
+ console.error(USAGE);
25
+ return 2;
26
+ }
27
+ if (rotate) {
28
+ const current = parseKeySet(await readStdin());
29
+ const rotated = noOverlap
30
+ ? await rotateKeySetWithoutOverlap(current)
31
+ : await rotateKeySet(current);
19
32
  process.stdout.write(`${JSON.stringify(rotated)}\n`);
20
33
  return 0;
21
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE5E,MAAM,KAAK,GAAG;yFAC2E,CAAC;AAE1F,KAAK,UAAU,SAAS;IACtB,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAChD,CAAC;AAED,KAAK,UAAU,IAAI,CAAC,IAAc;IAChC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;QACvB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACrB,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,WAAW,CAAC,MAAM,SAAS,EAAE,CAAC,CAAC,CAAC;QACnE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACrD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,YAAY,EAAE,CAAC,IAAI,CAAC,CAAC;IAClE,OAAO,CAAC,CAAC;AACX,CAAC;AAED,OAAO,CAAC,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EACL,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC;AAE3B,MAAM,KAAK,GAAG;;;;+EAIiE,CAAC;AAEhF,KAAK,UAAU,SAAS;IACtB,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAChD,CAAC;AAED,KAAK,UAAU,IAAI,CAAC,IAAc;IAChC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;QACvB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACrB,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IACzC,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;IAChD,+FAA+F;IAC/F,IAAI,SAAS,IAAI,CAAC,MAAM,EAAE,CAAC;QACzB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACrB,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,SAAS,EAAE,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAG,SAAS;YACvB,CAAC,CAAC,MAAM,0BAA0B,CAAC,OAAO,CAAC;YAC3C,CAAC,CAAC,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;QAChC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACrD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,YAAY,EAAE,CAAC,IAAI,CAAC,CAAC;IAClE,OAAO,CAAC,CAAC;AACX,CAAC;AAED,OAAO,CAAC,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC"}
@@ -1,5 +1,9 @@
1
1
  import type { OidcConnector } from "./types.js";
2
- /** Google as an OIDC connector: discovery, id_token claims, `prompt=login` for fresh logins. */
2
+ /**
3
+ * Google as an OIDC connector: discovery and id_token claims. Google documents no `login` value
4
+ * for `prompt`, only `none`, `consent`, and `select_account`, so a fresh login through it answers
5
+ * `login_required`.
6
+ */
3
7
  export declare function google(credentials: {
4
8
  clientId: () => string;
5
9
  clientSecret: () => string;
@@ -1,4 +1,8 @@
1
- /** Google as an OIDC connector: discovery, id_token claims, `prompt=login` for fresh logins. */
1
+ /**
2
+ * Google as an OIDC connector: discovery and id_token claims. Google documents no `login` value
3
+ * for `prompt`, only `none`, `consent`, and `select_account`, so a fresh login through it answers
4
+ * `login_required`.
5
+ */
2
6
  export function google(credentials) {
3
7
  return {
4
8
  kind: "oidc",
@@ -6,6 +10,7 @@ export function google(credentials) {
6
10
  label: "Google",
7
11
  issuer: "https://accounts.google.com",
8
12
  scopes: ["openid", "email", "profile"],
13
+ promptLogin: false,
9
14
  clientId: credentials.clientId,
10
15
  clientSecret: credentials.clientSecret,
11
16
  };
@@ -1 +1 @@
1
- {"version":3,"file":"google.js","sourceRoot":"","sources":["../../../src/client/connectors/google.ts"],"names":[],"mappings":"AAEA,gGAAgG;AAChG,MAAM,UAAU,MAAM,CAAC,WAItB;IACC,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,WAAW,CAAC,IAAI,IAAI,QAAQ;QAClC,KAAK,EAAE,QAAQ;QACf,MAAM,EAAE,6BAA6B;QACrC,MAAM,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC;QACtC,QAAQ,EAAE,WAAW,CAAC,QAAQ;QAC9B,YAAY,EAAE,WAAW,CAAC,YAAY;KACvC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"google.js","sourceRoot":"","sources":["../../../src/client/connectors/google.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,UAAU,MAAM,CAAC,WAItB;IACC,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,WAAW,CAAC,IAAI,IAAI,QAAQ;QAClC,KAAK,EAAE,QAAQ;QACf,MAAM,EAAE,6BAA6B;QACrC,MAAM,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC;QACtC,WAAW,EAAE,KAAK;QAClB,QAAQ,EAAE,WAAW,CAAC,QAAQ;QAC9B,YAAY,EAAE,WAAW,CAAC,YAAY;KACvC,CAAC;AACJ,CAAC"}
@@ -30,6 +30,11 @@ export type OidcConnector = Credentials & {
30
30
  label: string;
31
31
  issuer: string;
32
32
  scopes: string[];
33
+ /**
34
+ * The provider documents `prompt=login`, so a fresh login (`prompt=login` or `max_age`) is sent
35
+ * upstream as that. Without it, a fresh login answers `login_required`.
36
+ */
37
+ promptLogin: boolean;
33
38
  };
34
39
  /** The host action that delivers a code. The broker never sees how. */
35
40
  export type SendEmailCode = FunctionReference<"action", "internal", {
@@ -1,5 +1,5 @@
1
1
  /** The few pages the broker renders itself. Plain HTML, one stylesheet, no script. */
2
- export declare function page(title: string, body: string): Response;
2
+ export declare function page(title: string, body: string, status?: number): Response;
3
3
  /**
4
4
  * The connector choice. A third-party app gets the consent wording and a deny link; a first-party
5
5
  * app only sees the buttons.
@@ -7,6 +7,8 @@ export declare function page(title: string, body: string): Response;
7
7
  export declare function chooserPage(args: {
8
8
  appName: string;
9
9
  firstParty: boolean;
10
+ /** The granted scopes: the consent names only what they release. */
11
+ scopes: string[];
10
12
  connectors: Array<{
11
13
  name: string;
12
14
  label: string;
@@ -19,6 +21,7 @@ export declare function emailAddressPage(args: {
19
21
  action: string;
20
22
  requestId: string;
21
23
  error?: string;
24
+ status?: number;
22
25
  }): Response;
23
26
  export declare function emailCodePage(args: {
24
27
  appName: string;
@@ -26,5 +29,6 @@ export declare function emailCodePage(args: {
26
29
  requestId: string;
27
30
  email: string;
28
31
  error?: string;
32
+ status?: number;
29
33
  }): Response;
30
34
  export declare function errorPage(title: string, message: string, status?: number): Response;
@@ -20,7 +20,7 @@ const STYLE = `
20
20
  .error { color: #b00020; }
21
21
  .muted { color: #555; }
22
22
  `;
23
- export function page(title, body) {
23
+ export function page(title, body, status = 200) {
24
24
  const html = `<!doctype html>
25
25
  <html lang="en">
26
26
  <head>
@@ -33,11 +33,14 @@ export function page(title, body) {
33
33
  <body><main>${body}</main></body>
34
34
  </html>`;
35
35
  return new Response(html, {
36
- status: 200,
36
+ status,
37
37
  headers: {
38
38
  "Content-Type": "text/html; charset=utf-8",
39
39
  "Cache-Control": "no-store",
40
40
  "Referrer-Policy": "no-referrer",
41
+ // No page of the broker may be framed: the chooser doubles as consent.
42
+ "Content-Security-Policy": "frame-ancestors 'none'",
43
+ "X-Frame-Options": "DENY",
41
44
  },
42
45
  });
43
46
  }
@@ -49,9 +52,17 @@ export function chooserPage(args) {
49
52
  const buttons = args.connectors
50
53
  .map((connector) => `<a class="button" href="${escape(connector.href)}">Continue with ${escape(connector.label)}</a>`)
51
54
  .join("\n");
55
+ const released = [
56
+ "a stable id",
57
+ ...(args.scopes.includes("profile") ? ["your name and picture"] : []),
58
+ ...(args.scopes.includes("email") ? ["your verified email address"] : []),
59
+ ];
60
+ const list = released.length <= 2
61
+ ? released.join(" and ")
62
+ : `${released.slice(0, -1).join(", ")}, and ${released.slice(-1).join("")}`;
52
63
  const consent = args.firstParty
53
64
  ? ""
54
- : `<p class="muted">${escape(args.appName)} will receive your identity from the provider you choose: a stable id, your name, and your verified email address.</p>`;
65
+ : `<p class="muted">${escape(args.appName)} will receive your identity from the provider you choose: ${list}.</p>`;
55
66
  const deny = args.firstParty
56
67
  ? ""
57
68
  : `<p><a href="${escape(args.denyHref)}">Cancel and return to ${escape(args.appName)}</a></p>`;
@@ -65,7 +76,7 @@ export function emailAddressPage(args) {
65
76
  <input type="hidden" name="step" value="send">
66
77
  <input type="email" name="email" required autocomplete="email" autofocus placeholder="you@example.com">
67
78
  <button type="submit">Send code</button>
68
- </form>`);
79
+ </form>`, args.status);
69
80
  }
70
81
  export function emailCodePage(args) {
71
82
  const error = args.error === undefined ? "" : `<p class="error">${escape(args.error)}</p>`;
@@ -75,10 +86,9 @@ export function emailCodePage(args) {
75
86
  <input type="hidden" name="step" value="verify">
76
87
  <input type="text" name="code" inputmode="numeric" pattern="[0-9]{6}" required autocomplete="one-time-code" autofocus placeholder="000000">
77
88
  <button type="submit">Continue</button>
78
- </form>`);
89
+ </form>`, args.status);
79
90
  }
80
91
  export function errorPage(title, message, status = 400) {
81
- const response = page(title, `<h1>${escape(title)}</h1><p>${escape(message)}</p>`);
82
- return new Response(response.body, { status, headers: response.headers });
92
+ return page(title, `<h1>${escape(title)}</h1><p>${escape(message)}</p>`, status);
83
93
  }
84
94
  //# sourceMappingURL=html.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/client/html.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/client/html.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@ export type { Connector, EmailConnector, OauthConnector, OidcConnector, SendEmai
5
5
  export { github } from "./connectors/github.js";
6
6
  export { google } from "./connectors/google.js";
7
7
  export { email } from "./connectors/email.js";
8
- export { createKeySet, rotateKeySet, type KeySet } from "./keys.js";
8
+ export { createKeySet, parseKeySet, rotateKeySet, type KeySet } from "./keys.js";
9
9
  export type IdentityBrokerConfig = {
10
10
  /** `components.identityBroker` of the host app. */
11
11
  component: ComponentApi;
@@ -44,6 +44,19 @@ export declare function defineIdentityBroker(config: IdentityBrokerConfig): {
44
44
  allowedCallbackHosts: string[];
45
45
  appId: string;
46
46
  }, Promise<null>>;
47
+ listRegistrationTokens: import("convex/server").RegisteredQuery<"internal", {
48
+ appId: string;
49
+ }, Promise<{
50
+ createdAt: number;
51
+ expiresAt: number;
52
+ tokenHash: string;
53
+ }[]>>;
54
+ revokeRegistrationToken: import("convex/server").RegisteredMutation<"internal", {
55
+ tokenHash: string;
56
+ }, Promise<null>>;
57
+ deleteClient: import("convex/server").RegisteredMutation<"internal", {
58
+ clientId: string;
59
+ }, Promise<null>>;
47
60
  deleteApp: import("convex/server").RegisteredMutation<"internal", {
48
61
  appId: string;
49
62
  }, Promise<null>>;
@@ -71,7 +84,9 @@ export declare function defineIdentityBroker(config: IdentityBrokerConfig): {
71
84
  cleanup: import("convex/server").RegisteredMutation<"internal", {}, Promise<{
72
85
  authRequests: number;
73
86
  authorizationCodes: number;
87
+ emailSends: number;
74
88
  previewClients: number;
89
+ registrationTokens: number;
75
90
  signIns: number;
76
91
  }>>;
77
92
  };