@atproto/oauth-provider 0.1.0 → 0.1.2-rc.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/account/account-manager.d.ts +2 -2
  3. package/dist/account/account-manager.d.ts.map +1 -1
  4. package/dist/account/account-manager.js.map +1 -1
  5. package/dist/account/account-store.d.ts +19 -6
  6. package/dist/account/account-store.d.ts.map +1 -1
  7. package/dist/account/account-store.js +16 -1
  8. package/dist/account/account-store.js.map +1 -1
  9. package/dist/assets/app/bundle-manifest.json +3 -3
  10. package/dist/assets/app/main.css +1 -1
  11. package/dist/assets/app/main.js +3 -3
  12. package/dist/assets/app/main.js.map +1 -1
  13. package/dist/client/client-auth.d.ts.map +1 -1
  14. package/dist/client/client-auth.js +2 -2
  15. package/dist/client/client-auth.js.map +1 -1
  16. package/dist/client/client-manager.d.ts.map +1 -1
  17. package/dist/client/client-manager.js +3 -1
  18. package/dist/client/client-manager.js.map +1 -1
  19. package/dist/client/client.d.ts.map +1 -1
  20. package/dist/client/client.js +3 -3
  21. package/dist/client/client.js.map +1 -1
  22. package/dist/dpop/dpop-manager.d.ts.map +1 -1
  23. package/dist/dpop/dpop-manager.js +3 -3
  24. package/dist/dpop/dpop-manager.js.map +1 -1
  25. package/dist/errors/invalid-token-error.d.ts.map +1 -1
  26. package/dist/errors/invalid-token-error.js +3 -2
  27. package/dist/errors/invalid-token-error.js.map +1 -1
  28. package/dist/errors/second-authentication-factor-required-error.d.ts +13 -0
  29. package/dist/errors/second-authentication-factor-required-error.d.ts.map +1 -0
  30. package/dist/errors/second-authentication-factor-required-error.js +23 -0
  31. package/dist/errors/second-authentication-factor-required-error.js.map +1 -0
  32. package/dist/lib/util/authorization-header.js +1 -1
  33. package/dist/lib/util/authorization-header.js.map +1 -1
  34. package/dist/metadata/build-metadata.d.ts.map +1 -1
  35. package/dist/metadata/build-metadata.js +2 -0
  36. package/dist/metadata/build-metadata.js.map +1 -1
  37. package/dist/oauth-errors.d.ts +1 -0
  38. package/dist/oauth-errors.d.ts.map +1 -1
  39. package/dist/oauth-errors.js +3 -1
  40. package/dist/oauth-errors.js.map +1 -1
  41. package/dist/oauth-provider.d.ts +101 -4
  42. package/dist/oauth-provider.d.ts.map +1 -1
  43. package/dist/oauth-provider.js +98 -110
  44. package/dist/oauth-provider.js.map +1 -1
  45. package/dist/output/build-authorize-data.d.ts +40 -0
  46. package/dist/output/build-authorize-data.d.ts.map +1 -0
  47. package/dist/output/build-authorize-data.js +22 -0
  48. package/dist/output/build-authorize-data.js.map +1 -0
  49. package/dist/output/build-error-payload.d.ts.map +1 -1
  50. package/dist/output/build-error-payload.js +4 -3
  51. package/dist/output/build-error-payload.js.map +1 -1
  52. package/dist/output/customization.d.ts +2 -12
  53. package/dist/output/customization.d.ts.map +1 -1
  54. package/dist/output/customization.js +59 -32
  55. package/dist/output/customization.js.map +1 -1
  56. package/dist/output/output-manager.d.ts +16 -0
  57. package/dist/output/output-manager.d.ts.map +1 -0
  58. package/dist/output/output-manager.js +69 -0
  59. package/dist/output/output-manager.js.map +1 -0
  60. package/dist/output/send-web-page.d.ts +1 -1
  61. package/dist/output/send-web-page.d.ts.map +1 -1
  62. package/dist/output/send-web-page.js +3 -2
  63. package/dist/output/send-web-page.js.map +1 -1
  64. package/package.json +7 -7
  65. package/src/account/account-manager.ts +2 -2
  66. package/src/account/account-store.ts +12 -6
  67. package/src/assets/app/components/accept-form.tsx +86 -83
  68. package/src/assets/app/components/account-picker.tsx +98 -79
  69. package/src/assets/app/components/button.tsx +34 -0
  70. package/src/assets/app/components/client-identifier.tsx +12 -13
  71. package/src/assets/app/components/fieldset.tsx +26 -0
  72. package/src/assets/app/components/form-card.tsx +47 -0
  73. package/src/assets/app/components/help-card.tsx +1 -1
  74. package/src/assets/app/components/icons/alert-icon.tsx +5 -0
  75. package/src/assets/app/components/icons/at-symbol-icon.tsx +5 -0
  76. package/src/assets/app/components/icons/caret-right-icon.tsx +5 -0
  77. package/src/assets/app/components/icons/lock-icon.tsx +5 -0
  78. package/src/assets/app/components/icons/token-icon.tsx +5 -0
  79. package/src/assets/app/components/icons/util.tsx +17 -0
  80. package/src/assets/app/components/info-card.tsx +45 -0
  81. package/src/assets/app/components/input-checkbox.tsx +47 -0
  82. package/src/assets/app/components/input-container.tsx +37 -0
  83. package/src/assets/app/components/input-layout.tsx +47 -0
  84. package/src/assets/app/components/input-text.tsx +69 -0
  85. package/src/assets/app/components/layout-title-page.tsx +33 -16
  86. package/src/assets/app/components/layout-welcome.tsx +30 -14
  87. package/src/assets/app/components/sign-in-form.tsx +214 -196
  88. package/src/assets/app/components/sign-up-account-form.tsx +101 -117
  89. package/src/assets/app/components/sign-up-disclaimer.tsx +1 -1
  90. package/src/assets/app/hooks/use-api.ts +2 -0
  91. package/src/assets/app/lib/api.ts +49 -14
  92. package/src/assets/app/lib/clsx.ts +6 -1
  93. package/src/assets/app/lib/util.ts +3 -0
  94. package/src/assets/app/main.css +2 -1
  95. package/src/assets/app/views/accept-view.tsx +4 -3
  96. package/src/assets/app/views/authorize-view.tsx +8 -4
  97. package/src/assets/app/views/error-view.tsx +24 -15
  98. package/src/assets/app/views/sign-in-view.tsx +5 -15
  99. package/src/assets/app/views/sign-up-view.tsx +3 -10
  100. package/src/assets/app/views/welcome-view.tsx +11 -18
  101. package/src/client/client-auth.ts +3 -2
  102. package/src/client/client-manager.ts +2 -1
  103. package/src/client/client.ts +3 -1
  104. package/src/dpop/dpop-manager.ts +3 -2
  105. package/src/errors/invalid-token-error.ts +3 -1
  106. package/src/errors/second-authentication-factor-required-error.ts +25 -0
  107. package/src/lib/util/authorization-header.ts +1 -1
  108. package/src/metadata/build-metadata.ts +3 -0
  109. package/src/oauth-errors.ts +1 -0
  110. package/src/oauth-provider.ts +110 -99
  111. package/src/output/{send-authorize-page.ts → build-authorize-data.ts} +3 -43
  112. package/src/output/build-error-payload.ts +3 -1
  113. package/src/output/customization.ts +67 -45
  114. package/src/output/output-manager.ts +87 -0
  115. package/src/output/send-web-page.ts +4 -3
  116. package/tailwind.config.js +14 -1
  117. package/src/assets/app/components/error-card.tsx +0 -41
  118. package/src/output/send-error-page.ts +0 -41
@@ -1,16 +1,5 @@
1
- declare const colorNames: readonly ["primary", "error"];
1
+ declare const colorNames: readonly ["brand", "error", "warning"];
2
2
  type ColorName = (typeof colorNames)[number];
3
- export type FieldDefinition = {
4
- label?: string;
5
- placeholder?: string;
6
- pattern?: string;
7
- title?: string;
8
- };
9
- export type ExtraFieldDefinition = FieldDefinition & {
10
- type: 'text' | 'password' | 'date' | 'captcha';
11
- required?: boolean;
12
- [_: string]: unknown;
13
- };
14
3
  export type Customization = {
15
4
  name?: string;
16
5
  logo?: string;
@@ -33,5 +22,6 @@ export declare function buildCustomizationData({ name, logo, links, }?: Customiz
33
22
  }[] | undefined;
34
23
  };
35
24
  export declare function buildCustomizationCss(customization?: Customization): string;
25
+ export declare function buildCustomizationVars(customization?: Customization): Generator<string, void, unknown>;
36
26
  export {};
37
27
  //# sourceMappingURL=customization.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"customization.d.ts","sourceRoot":"","sources":["../../src/output/customization.ts"],"names":[],"mappings":"AACA,QAAA,MAAM,UAAU,+BAAgC,CAAA;AAChD,KAAK,SAAS,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAA;AAI5C,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG,eAAe,GAAG;IACnD,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,CAAA;IAC9C,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE;SAAG,CAAC,IAAI,SAAS,CAAC,CAAC,EAAE,MAAM;KAAE,CAAA;IACtC,KAAK,CAAC,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAA;QACZ,KAAK,EAAE,MAAM,CAAA;QACb,GAAG,CAAC,EAAE,MAAM,CAAA;KACb,CAAC,CAAA;CACH,CAAA;AAED,wBAAgB,sBAAsB,CAAC,EACrC,IAAI,EACJ,IAAI,EACJ,KAAK,GACN,GAAE,aAAkB;;;;;;;;EAMpB;AAED,wBAAgB,qBAAqB,CAAC,aAAa,CAAC,EAAE,aAAa,UAWlE"}
1
+ {"version":3,"file":"customization.d.ts","sourceRoot":"","sources":["../../src/output/customization.ts"],"names":[],"mappings":"AACA,QAAA,MAAM,UAAU,wCAAyC,CAAA;AACzD,KAAK,SAAS,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAA;AAI5C,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE;SAAG,CAAC,IAAI,SAAS,CAAC,CAAC,EAAE,MAAM;KAAE,CAAA;IACtC,KAAK,CAAC,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAA;QACZ,KAAK,EAAE,MAAM,CAAA;QACb,GAAG,CAAC,EAAE,MAAM,CAAA;KACb,CAAC,CAAA;CACH,CAAA;AAED,wBAAgB,sBAAsB,CAAC,EACrC,IAAI,EACJ,IAAI,EACJ,KAAK,GACN,GAAE,aAAkB;;;;;;;;EAMpB;AAED,wBAAgB,qBAAqB,CAAC,aAAa,CAAC,EAAE,aAAa,UAKlE;AAED,wBAAiB,sBAAsB,CAAC,aAAa,CAAC,EAAE,aAAa,oCAkBpE"}
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildCustomizationCss = exports.buildCustomizationData = void 0;
3
+ exports.buildCustomizationVars = exports.buildCustomizationCss = exports.buildCustomizationData = void 0;
4
4
  // Matches colors defined in tailwind.config.js
5
- const colorNames = ['primary', 'error'];
5
+ const colorNames = ['brand', 'error', 'warning'];
6
6
  const isColorName = (name) => colorNames.includes(name);
7
7
  function buildCustomizationData({ name, logo, links, } = {}) {
8
8
  return {
@@ -13,50 +13,77 @@ function buildCustomizationData({ name, logo, links, } = {}) {
13
13
  }
14
14
  exports.buildCustomizationData = buildCustomizationData;
15
15
  function buildCustomizationCss(customization) {
16
- if (!customization?.colors)
17
- return '';
18
- const vars = Object.entries(customization.colors)
19
- .filter((e) => isColorName(e[0]) && e[1] != null)
20
- .map(([name, value]) => [name, parseColor(value)])
21
- .filter((e) => e[1] != null)
22
- // alpha not supported by tailwind (it does not work that way)
23
- .map(([name, { r, g, b }]) => `--color-${name}: ${r} ${g} ${b};`);
24
- return `:root { ${vars.join(' ')} }`;
16
+ const vars = Array.from(buildCustomizationVars(customization));
17
+ if (vars.length)
18
+ return `:root { ${vars.join(' ')} }`;
19
+ return '';
25
20
  }
26
21
  exports.buildCustomizationCss = buildCustomizationCss;
22
+ function* buildCustomizationVars(customization) {
23
+ if (customization?.colors) {
24
+ for (const [name, value] of Object.entries(customization.colors)) {
25
+ if (!isColorName(name)) {
26
+ throw new TypeError(`Invalid color name: ${name}`);
27
+ }
28
+ // Skip undefined values
29
+ if (value === undefined)
30
+ continue;
31
+ const { r, g, b, a } = parseColor(value);
32
+ // Tailwind does not apply alpha values to base colors
33
+ if (a !== undefined)
34
+ throw new TypeError('Alpha not supported');
35
+ yield `--color-${name}: ${r} ${g} ${b};`;
36
+ }
37
+ }
38
+ }
39
+ exports.buildCustomizationVars = buildCustomizationVars;
27
40
  function parseColor(color) {
41
+ if (typeof color !== 'string') {
42
+ throw new TypeError(`Invalid color value: ${typeof color}`);
43
+ }
28
44
  if (color.startsWith('#')) {
29
45
  if (color.length === 4 || color.length === 5) {
30
- const [r, g, b, a] = color
31
- .slice(1)
32
- .split('')
33
- .map((c) => parseInt(c + c, 16));
46
+ const r = parseUi8Hex(color.slice(1, 2));
47
+ const g = parseUi8Hex(color.slice(2, 3));
48
+ const b = parseUi8Hex(color.slice(3, 4));
49
+ const a = color.length > 4 ? parseUi8Hex(color.slice(4, 5)) : undefined;
34
50
  return { r, g, b, a };
35
51
  }
36
52
  if (color.length === 7 || color.length === 9) {
37
- const r = parseInt(color.slice(1, 3), 16);
38
- const g = parseInt(color.slice(3, 5), 16);
39
- const b = parseInt(color.slice(5, 7), 16);
40
- const a = color.length > 8 ? parseInt(color.slice(7, 9), 16) : undefined;
53
+ const r = parseUi8Hex(color.slice(1, 3));
54
+ const g = parseUi8Hex(color.slice(3, 5));
55
+ const b = parseUi8Hex(color.slice(5, 7));
56
+ const a = color.length > 8 ? parseUi8Hex(color.slice(7, 9)) : undefined;
41
57
  return { r, g, b, a };
42
58
  }
43
- return undefined;
59
+ throw new TypeError(`Invalid hex color: ${color}`);
44
60
  }
45
- const rgbMatch = color.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
61
+ const rgbMatch = color.match(/^\s*rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)\s*$/);
46
62
  if (rgbMatch) {
47
- const [, r, g, b] = rgbMatch;
48
- return { r: parseInt(r, 10), g: parseInt(g, 10), b: parseInt(b, 10) };
63
+ const r = parseUi8Dec(rgbMatch[1]);
64
+ const g = parseUi8Dec(rgbMatch[2]);
65
+ const b = parseUi8Dec(rgbMatch[3]);
66
+ return { r, g, b };
49
67
  }
50
- const rgbaMatch = color.match(/rgba\((\d+),\s*(\d+),\s*(\d+),\s*(\d+)\)/);
68
+ const rgbaMatch = color.match(/^\s*rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)\s*$/);
51
69
  if (rgbaMatch) {
52
- const [, r, g, b, a] = rgbaMatch;
53
- return {
54
- r: parseInt(r, 10),
55
- g: parseInt(g, 10),
56
- b: parseInt(b, 10),
57
- a: parseInt(a, 10),
58
- };
70
+ const r = parseUi8Dec(rgbaMatch[1]);
71
+ const g = parseUi8Dec(rgbaMatch[2]);
72
+ const b = parseUi8Dec(rgbaMatch[3]);
73
+ const a = parseUi8Dec(rgbaMatch[4]);
74
+ return { r, g, b, a };
59
75
  }
60
- return undefined;
76
+ throw new TypeError(`Unsupported color format: ${color}`);
77
+ }
78
+ function parseUi8Hex(v) {
79
+ return asUi8(parseInt(v, 16));
80
+ }
81
+ function parseUi8Dec(v) {
82
+ return asUi8(parseInt(v, 10));
83
+ }
84
+ function asUi8(v) {
85
+ if (v >= 0 && v <= 255 && v === (v | 0))
86
+ return v;
87
+ throw new TypeError(`Invalid color component: ${v}`);
61
88
  }
62
89
  //# sourceMappingURL=customization.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"customization.js","sourceRoot":"","sources":["../../src/output/customization.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"customization.js","sourceRoot":"","sources":["../../src/output/customization.ts"],"names":[],"mappings":";;;AAAA,+CAA+C;AAC/C,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAU,CAAA;AAEzD,MAAM,WAAW,GAAG,CAAC,IAAY,EAAqB,EAAE,CACrD,UAAgC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;AAalD,SAAgB,sBAAsB,CAAC,EACrC,IAAI,EACJ,IAAI,EACJ,KAAK,MACY,EAAE;IACnB,OAAO;QACL,IAAI;QACJ,IAAI;QACJ,KAAK;KACN,CAAA;AACH,CAAC;AAVD,wDAUC;AAED,SAAgB,qBAAqB,CAAC,aAA6B;IACjE,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,aAAa,CAAC,CAAC,CAAA;IAC9D,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,WAAW,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAA;IAErD,OAAO,EAAE,CAAA;AACX,CAAC;AALD,sDAKC;AAED,QAAe,CAAC,CAAC,sBAAsB,CAAC,aAA6B;IACnE,IAAI,aAAa,EAAE,MAAM,EAAE,CAAC;QAC1B,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;YACjE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvB,MAAM,IAAI,SAAS,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAA;YACpD,CAAC;YAED,wBAAwB;YACxB,IAAI,KAAK,KAAK,SAAS;gBAAE,SAAQ;YAEjC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;YAExC,sDAAsD;YACtD,IAAI,CAAC,KAAK,SAAS;gBAAE,MAAM,IAAI,SAAS,CAAC,qBAAqB,CAAC,CAAA;YAE/D,MAAM,WAAW,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAA;QAC1C,CAAC;IACH,CAAC;AACH,CAAC;AAlBD,wDAkBC;AAGD,SAAS,UAAU,CAAC,KAAc;IAChC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,IAAI,SAAS,CAAC,wBAAwB,OAAO,KAAK,EAAE,CAAC,CAAA;IAC7D,CAAC;IAED,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7C,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YACxC,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YACxC,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YACxC,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;YACvE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAA;QACvB,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7C,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YACxC,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YACxC,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YACxC,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;YACvE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAA;QACvB,CAAC;QAED,MAAM,IAAI,SAAS,CAAC,sBAAsB,KAAK,EAAE,CAAC,CAAA;IACpD,CAAC;IAED,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAC1B,oDAAoD,CACrD,CAAA;IACD,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;QAClC,MAAM,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;QAClC,MAAM,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;QAClC,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAA;IACpB,CAAC;IAED,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAC3B,iEAAiE,CAClE,CAAA;IACD,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,CAAC,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAA;QACnC,MAAM,CAAC,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAA;QACnC,MAAM,CAAC,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAA;QACnC,MAAM,CAAC,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAA;QACnC,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAA;IACvB,CAAC;IAED,MAAM,IAAI,SAAS,CAAC,6BAA6B,KAAK,EAAE,CAAC,CAAA;AAC3D,CAAC;AAED,SAAS,WAAW,CAAC,CAAS;IAC5B,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;AAC/B,CAAC;AAED,SAAS,WAAW,CAAC,CAAS;IAC5B,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;AAC/B,CAAC;AAED,SAAS,KAAK,CAAC,CAAS;IACtB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;QAAE,OAAO,CAAC,CAAA;IACjD,MAAM,IAAI,SAAS,CAAC,4BAA4B,CAAC,EAAE,CAAC,CAAA;AACtD,CAAC"}
@@ -0,0 +1,16 @@
1
+ /// <reference types="node" />
2
+ import { ServerResponse } from 'node:http';
3
+ import { Asset } from '../assets/asset.js';
4
+ import { Html } from '../lib/html/index.js';
5
+ import { AuthorizationResultAuthorize } from './build-authorize-data.js';
6
+ import { Customization } from './customization.js';
7
+ export declare class OutputManager {
8
+ readonly customizationScript: Html;
9
+ readonly customizationStyle: Html;
10
+ readonly customizationLinks?: Customization['links'];
11
+ readonly assetsPromise: Promise<[js: Asset, css: Asset]>;
12
+ constructor(customization?: Customization);
13
+ sendAuthorizePage(res: ServerResponse, data: AuthorizationResultAuthorize): Promise<void>;
14
+ sendErrorPage(res: ServerResponse, err: unknown): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=output-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-manager.d.ts","sourceRoot":"","sources":["../../src/output/output-manager.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAE1C,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAE1C,OAAO,EAAW,IAAI,EAAQ,MAAM,sBAAsB,CAAA;AAC1D,OAAO,EACL,4BAA4B,EAE7B,MAAM,2BAA2B,CAAA;AAElC,OAAO,EAGL,aAAa,EACd,MAAM,oBAAoB,CAAA;AAG3B,qBAAa,aAAa;IACxB,QAAQ,CAAC,mBAAmB,EAAE,IAAI,CAAA;IAClC,QAAQ,CAAC,kBAAkB,EAAE,IAAI,CAAA;IACjC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAA;IAMpD,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAG7C;gBAEC,aAAa,CAAC,EAAE,aAAa;IAYnC,iBAAiB,CACrB,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE,4BAA4B,GACjC,OAAO,CAAC,IAAI,CAAC;IAoBV,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAoBtE"}
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OutputManager = void 0;
4
+ const index_js_1 = require("../assets/index.js");
5
+ const index_js_2 = require("../lib/html/index.js");
6
+ const build_authorize_data_js_1 = require("./build-authorize-data.js");
7
+ const build_error_payload_js_1 = require("./build-error-payload.js");
8
+ const customization_js_1 = require("./customization.js");
9
+ const send_web_page_js_1 = require("./send-web-page.js");
10
+ class OutputManager {
11
+ customizationScript;
12
+ customizationStyle;
13
+ customizationLinks;
14
+ // Could technically cause an "UnhandledPromiseRejection", which might cause
15
+ // the process to exit. This is intentional, as it's a critical error. It
16
+ // should never happen in practice, as the built assets are bundled with the
17
+ // package.
18
+ assetsPromise = Promise.all([
19
+ (0, index_js_1.getAsset)('main.js'),
20
+ (0, index_js_1.getAsset)('main.css'),
21
+ ]);
22
+ constructor(customization) {
23
+ // Note: building this here for two reasons:
24
+ // 1. To avoid re-building it on every request
25
+ // 2. To throw during init if the customization is invalid
26
+ this.customizationScript = (0, send_web_page_js_1.declareBackendData)('__customizationData', (0, customization_js_1.buildCustomizationData)(customization));
27
+ this.customizationStyle = (0, index_js_2.cssCode)((0, customization_js_1.buildCustomizationCss)(customization));
28
+ this.customizationLinks = customization?.links;
29
+ }
30
+ async sendAuthorizePage(res, data) {
31
+ const [jsAsset, cssAsset] = await this.assetsPromise;
32
+ return (0, send_web_page_js_1.sendWebPage)(res, {
33
+ scripts: [
34
+ (0, send_web_page_js_1.declareBackendData)('__authorizeData', (0, build_authorize_data_js_1.buildAuthorizeData)(data)),
35
+ this.customizationScript,
36
+ jsAsset, // Last (to be able to read the "backend data" variables)
37
+ ],
38
+ styles: [
39
+ cssAsset, // First (to be overridden by customization)
40
+ this.customizationStyle,
41
+ ],
42
+ links: this.customizationLinks,
43
+ htmlAttrs: { lang: 'en' },
44
+ title: 'Authorize',
45
+ body: (0, index_js_2.html) `<div id="root"></div>`,
46
+ });
47
+ }
48
+ async sendErrorPage(res, err) {
49
+ const [jsAsset, cssAsset] = await this.assetsPromise;
50
+ return (0, send_web_page_js_1.sendWebPage)(res, {
51
+ status: (0, build_error_payload_js_1.buildErrorStatus)(err),
52
+ scripts: [
53
+ (0, send_web_page_js_1.declareBackendData)('__errorData', (0, build_error_payload_js_1.buildErrorPayload)(err)),
54
+ this.customizationScript,
55
+ jsAsset, // Last (to be able to read the "backend data" variables)
56
+ ],
57
+ styles: [
58
+ cssAsset, // First (to be overridden by customization)
59
+ this.customizationStyle,
60
+ ],
61
+ links: this.customizationLinks,
62
+ htmlAttrs: { lang: 'en' },
63
+ title: 'Error',
64
+ body: (0, index_js_2.html) `<div id="root"></div>`,
65
+ });
66
+ }
67
+ }
68
+ exports.OutputManager = OutputManager;
69
+ //# sourceMappingURL=output-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-manager.js","sourceRoot":"","sources":["../../src/output/output-manager.ts"],"names":[],"mappings":";;;AAGA,iDAA6C;AAC7C,mDAA0D;AAC1D,uEAGkC;AAClC,qEAA8E;AAC9E,yDAI2B;AAC3B,yDAAoE;AAEpE,MAAa,aAAa;IACf,mBAAmB,CAAM;IACzB,kBAAkB,CAAM;IACxB,kBAAkB,CAAyB;IAEpD,4EAA4E;IAC5E,yEAAyE;IACzE,4EAA4E;IAC5E,WAAW;IACF,aAAa,GAAqC,OAAO,CAAC,GAAG,CAAC;QACrE,IAAA,mBAAQ,EAAC,SAAS,CAAC;QACnB,IAAA,mBAAQ,EAAC,UAAU,CAAC;KACZ,CAAC,CAAA;IAEX,YAAY,aAA6B;QACvC,4CAA4C;QAC5C,8CAA8C;QAC9C,0DAA0D;QAC1D,IAAI,CAAC,mBAAmB,GAAG,IAAA,qCAAkB,EAC3C,qBAAqB,EACrB,IAAA,yCAAsB,EAAC,aAAa,CAAC,CACtC,CAAA;QACD,IAAI,CAAC,kBAAkB,GAAG,IAAA,kBAAO,EAAC,IAAA,wCAAqB,EAAC,aAAa,CAAC,CAAC,CAAA;QACvE,IAAI,CAAC,kBAAkB,GAAG,aAAa,EAAE,KAAK,CAAA;IAChD,CAAC;IAED,KAAK,CAAC,iBAAiB,CACrB,GAAmB,EACnB,IAAkC;QAElC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,MAAM,IAAI,CAAC,aAAa,CAAA;QAEpD,OAAO,IAAA,8BAAW,EAAC,GAAG,EAAE;YACtB,OAAO,EAAE;gBACP,IAAA,qCAAkB,EAAC,iBAAiB,EAAE,IAAA,4CAAkB,EAAC,IAAI,CAAC,CAAC;gBAC/D,IAAI,CAAC,mBAAmB;gBACxB,OAAO,EAAE,yDAAyD;aACnE;YACD,MAAM,EAAE;gBACN,QAAQ,EAAE,4CAA4C;gBACtD,IAAI,CAAC,kBAAkB;aACxB;YACD,KAAK,EAAE,IAAI,CAAC,kBAAkB;YAC9B,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;YACzB,KAAK,EAAE,WAAW;YAClB,IAAI,EAAE,IAAA,eAAI,EAAA,uBAAuB;SAClC,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,GAAmB,EAAE,GAAY;QACnD,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,MAAM,IAAI,CAAC,aAAa,CAAA;QAEpD,OAAO,IAAA,8BAAW,EAAC,GAAG,EAAE;YACtB,MAAM,EAAE,IAAA,yCAAgB,EAAC,GAAG,CAAC;YAC7B,OAAO,EAAE;gBACP,IAAA,qCAAkB,EAAC,aAAa,EAAE,IAAA,0CAAiB,EAAC,GAAG,CAAC,CAAC;gBACzD,IAAI,CAAC,mBAAmB;gBACxB,OAAO,EAAE,yDAAyD;aACnE;YACD,MAAM,EAAE;gBACN,QAAQ,EAAE,4CAA4C;gBACtD,IAAI,CAAC,kBAAkB;aACxB;YACD,KAAK,EAAE,IAAI,CAAC,kBAAkB;YAC9B,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;YACzB,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,IAAA,eAAI,EAAA,uBAAuB;SAClC,CAAC,CAAA;IACJ,CAAC;CACF;AArED,sCAqEC"}
@@ -4,5 +4,5 @@ import { BuildDocumentOptions, Html } from '../lib/html/index.js';
4
4
  export declare function declareBackendData(name: string, data: unknown): Html;
5
5
  export declare function sendWebPage(res: ServerResponse, { status, ...options }: BuildDocumentOptions & {
6
6
  status?: number;
7
- }): void;
7
+ }): Promise<void>;
8
8
  //# sourceMappingURL=send-web-page.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"send-web-page.d.ts","sourceRoot":"","sources":["../../src/output/send-web-page.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAE1C,OAAO,EAGL,oBAAoB,EACpB,IAAI,EAEL,MAAM,sBAAsB,CAAA;AAG7B,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,QAM7D;AAED,wBAAgB,WAAW,CACzB,GAAG,EAAE,cAAc,EACnB,EAAE,MAAY,EAAE,GAAG,OAAO,EAAE,EAAE,oBAAoB,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACvE,IAAI,CAgCN"}
1
+ {"version":3,"file":"send-web-page.d.ts","sourceRoot":"","sources":["../../src/output/send-web-page.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAE1C,OAAO,EAGL,oBAAoB,EACpB,IAAI,EAEL,MAAM,sBAAsB,CAAA;AAG7B,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,QAM7D;AAED,wBAAsB,WAAW,CAC/B,GAAG,EAAE,cAAc,EACnB,EAAE,MAAY,EAAE,GAAG,OAAO,EAAE,EAAE,oBAAoB,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACvE,OAAO,CAAC,IAAI,CAAC,CAiCf"}
@@ -12,8 +12,9 @@ function declareBackendData(name, data) {
12
12
  return (0, index_js_1.js) `window[${name}]=${data};document.currentScript.remove();`;
13
13
  }
14
14
  exports.declareBackendData = declareBackendData;
15
- function sendWebPage(res, { status = 200, ...options }) {
15
+ async function sendWebPage(res, { status = 200, ...options }) {
16
16
  // @TODO: make these headers configurable (?)
17
+ res.setHeader('Permissions-Policy', 'otp-credentials=*, document-domain=()');
17
18
  res.setHeader('Cross-Origin-Embedder-Policy', 'credentialless');
18
19
  res.setHeader('Cross-Origin-Resource-Policy', 'same-origin');
19
20
  res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
@@ -34,7 +35,7 @@ function sendWebPage(res, { status = 200, ...options }) {
34
35
  `upgrade-insecure-requests`,
35
36
  ].join('; '));
36
37
  const html = (0, index_js_1.buildDocument)(options);
37
- (0, response_js_1.writeHtml)(res, html.toString(), status);
38
+ return (0, response_js_1.writeHtml)(res, html.toString(), status);
38
39
  }
39
40
  exports.sendWebPage = sendWebPage;
40
41
  function assetToHash(asset) {
@@ -1 +1 @@
1
- {"version":3,"file":"send-web-page.js","sourceRoot":"","sources":["../../src/output/send-web-page.ts"],"names":[],"mappings":";;;AAAA,6CAAwC;AAGxC,mDAM6B;AAC7B,yDAAmD;AAEnD,SAAgB,kBAAkB,CAAC,IAAY,EAAE,IAAa;IAC5D,8EAA8E;IAC9E,8EAA8E;IAC9E,8DAA8D;IAC9D,yDAAyD;IACzD,OAAO,IAAA,aAAE,EAAA,UAAU,IAAI,KAAK,IAAI,mCAAmC,CAAA;AACrE,CAAC;AAND,gDAMC;AAED,SAAgB,WAAW,CACzB,GAAmB,EACnB,EAAE,MAAM,GAAG,GAAG,EAAE,GAAG,OAAO,EAA8C;IAExE,6CAA6C;IAC7C,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,gBAAgB,CAAC,CAAA;IAC/D,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,aAAa,CAAC,CAAA;IAC5D,GAAG,CAAC,SAAS,CAAC,4BAA4B,EAAE,aAAa,CAAC,CAAA;IAC1D,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAA;IAC/C,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAA;IACxC,GAAG,CAAC,SAAS,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAA;IAClD,GAAG,CAAC,SAAS,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAA;IACtC,GAAG,CAAC,SAAS,CAAC,2BAA2B,EAAE,kBAAkB,CAAC,CAAA;IAC9D,GAAG,CAAC,SAAS,CACX,yBAAyB,EACzB;QACE,oBAAoB;QACpB,wBAAwB;QACxB,oBAAoB;QACpB,YAAY,OAAO,CAAC,IAAI,EAAE,MAAM,IAAI,QAAQ,EAAE;QAC9C,qBACE,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EACpE,EAAE;QACF,oBACE,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EACnE,EAAE;QACF,6BAA6B;QAC7B,oBAAoB;QACpB,2BAA2B;KAC5B,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAA;IAED,MAAM,IAAI,GAAG,IAAA,wBAAa,EAAC,OAAO,CAAC,CAAA;IAEnC,IAAA,uBAAS,EAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,MAAM,CAAC,CAAA;AACzC,CAAC;AAnCD,kCAmCC;AAED,SAAS,WAAW,CAAC,KAAsB;IACzC,OAAO,KAAK,YAAY,eAAI;QAC1B,CAAC,CAAC,IAAA,wBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;QAChE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAA;AAClB,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,WAAW,IAAI,GAAG,CAAA;AAC3B,CAAC"}
1
+ {"version":3,"file":"send-web-page.js","sourceRoot":"","sources":["../../src/output/send-web-page.ts"],"names":[],"mappings":";;;AAAA,6CAAwC;AAGxC,mDAM6B;AAC7B,yDAAmD;AAEnD,SAAgB,kBAAkB,CAAC,IAAY,EAAE,IAAa;IAC5D,8EAA8E;IAC9E,8EAA8E;IAC9E,8DAA8D;IAC9D,yDAAyD;IACzD,OAAO,IAAA,aAAE,EAAA,UAAU,IAAI,KAAK,IAAI,mCAAmC,CAAA;AACrE,CAAC;AAND,gDAMC;AAEM,KAAK,UAAU,WAAW,CAC/B,GAAmB,EACnB,EAAE,MAAM,GAAG,GAAG,EAAE,GAAG,OAAO,EAA8C;IAExE,6CAA6C;IAC7C,GAAG,CAAC,SAAS,CAAC,oBAAoB,EAAE,uCAAuC,CAAC,CAAA;IAC5E,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,gBAAgB,CAAC,CAAA;IAC/D,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,aAAa,CAAC,CAAA;IAC5D,GAAG,CAAC,SAAS,CAAC,4BAA4B,EAAE,aAAa,CAAC,CAAA;IAC1D,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAA;IAC/C,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAA;IACxC,GAAG,CAAC,SAAS,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAA;IAClD,GAAG,CAAC,SAAS,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAA;IACtC,GAAG,CAAC,SAAS,CAAC,2BAA2B,EAAE,kBAAkB,CAAC,CAAA;IAC9D,GAAG,CAAC,SAAS,CACX,yBAAyB,EACzB;QACE,oBAAoB;QACpB,wBAAwB;QACxB,oBAAoB;QACpB,YAAY,OAAO,CAAC,IAAI,EAAE,MAAM,IAAI,QAAQ,EAAE;QAC9C,qBACE,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EACpE,EAAE;QACF,oBACE,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EACnE,EAAE;QACF,6BAA6B;QAC7B,oBAAoB;QACpB,2BAA2B;KAC5B,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAA;IAED,MAAM,IAAI,GAAG,IAAA,wBAAa,EAAC,OAAO,CAAC,CAAA;IAEnC,OAAO,IAAA,uBAAS,EAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,MAAM,CAAC,CAAA;AAChD,CAAC;AApCD,kCAoCC;AAED,SAAS,WAAW,CAAC,KAAsB;IACzC,OAAO,KAAK,YAAY,eAAI;QAC1B,CAAC,CAAC,IAAA,wBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;QAChE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAA;AAClB,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,WAAW,IAAI,GAAG,CAAA;AAC3B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/oauth-provider",
3
- "version": "0.1.0",
3
+ "version": "0.1.2-rc.0",
4
4
  "license": "MIT",
5
5
  "description": "Generic OAuth2 and OpenID Connect provider for Node.js. Currently only supports features needed for Atproto.",
6
6
  "keywords": [
@@ -39,13 +39,13 @@
39
39
  "psl": "^1.9.0",
40
40
  "zod": "^3.23.8",
41
41
  "@atproto-labs/fetch": "0.1.0",
42
- "@atproto-labs/fetch-node": "0.1.0",
42
+ "@atproto-labs/simple-store": "0.1.1",
43
+ "@atproto-labs/simple-store-memory": "0.1.1",
44
+ "@atproto/jwk": "0.1.1",
45
+ "@atproto/jwk-jose": "0.1.2-rc.0",
46
+ "@atproto/oauth-types": "0.1.1",
43
47
  "@atproto-labs/pipe": "0.1.0",
44
- "@atproto-labs/simple-store": "0.1.0",
45
- "@atproto-labs/simple-store-memory": "0.1.0",
46
- "@atproto/jwk": "0.1.0",
47
- "@atproto/jwk-jose": "0.1.0",
48
- "@atproto/oauth-types": "0.1.0"
48
+ "@atproto-labs/fetch-node": "0.1.0"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@rollup/plugin-commonjs": "^25.0.7",
@@ -9,7 +9,7 @@ import {
9
9
  Account,
10
10
  AccountInfo,
11
11
  AccountStore,
12
- LoginCredentials,
12
+ SignInCredentials,
13
13
  } from './account-store.js'
14
14
 
15
15
  const TIMING_ATTACK_MITIGATION_DELAY = 400
@@ -18,7 +18,7 @@ export class AccountManager {
18
18
  constructor(protected readonly store: AccountStore) {}
19
19
 
20
20
  public async signIn(
21
- credentials: LoginCredentials,
21
+ credentials: SignInCredentials,
22
22
  deviceId: DeviceId,
23
23
  ): Promise<AccountInfo> {
24
24
  return constantTime(TIMING_ATTACK_MITIGATION_DELAY, async () => {
@@ -1,20 +1,26 @@
1
+ import z from 'zod'
2
+
1
3
  import { ClientId } from '../client/client-id.js'
2
4
  import { DeviceId } from '../device/device-id.js'
3
5
  import { Awaitable } from '../lib/util/type.js'
4
6
  import { Sub } from '../oidc/sub.js'
5
7
  import { Account } from './account.js'
6
8
 
7
- export type LoginCredentials = {
8
- username: string
9
- password: string
9
+ export const signInCredentialsSchema = z.object({
10
+ username: z.string(),
11
+ password: z.string(),
10
12
 
11
13
  /**
12
14
  * If false, the account must not be returned from
13
15
  * {@link AccountStore.listDeviceAccounts}. Note that this only makes sense when
14
16
  * used with a device ID.
15
17
  */
16
- remember?: boolean
17
- }
18
+ remember: z.boolean().optional().default(false),
19
+
20
+ emailOtp: z.string().optional(),
21
+ })
22
+
23
+ export type SignInCredentials = z.TypeOf<typeof signInCredentialsSchema>
18
24
 
19
25
  export type DeviceAccountInfo = {
20
26
  remembered: boolean
@@ -32,7 +38,7 @@ export type AccountInfo = {
32
38
 
33
39
  export interface AccountStore {
34
40
  authenticateAccount(
35
- credentials: LoginCredentials,
41
+ credentials: SignInCredentials,
36
42
  deviceId: DeviceId,
37
43
  ): Awaitable<AccountInfo | null>
38
44
 
@@ -1,26 +1,32 @@
1
1
  import { OAuthClientMetadata } from '@atproto/oauth-types'
2
- import { type HTMLAttributes } from 'react'
2
+ import { FormEvent } from 'react'
3
3
 
4
4
  import { Account } from '../backend-data'
5
- import { clsx } from '../lib/clsx'
5
+ import { Override } from '../lib/util'
6
6
  import { AccountIdentifier } from './account-identifier'
7
+ import { Button } from './button'
7
8
  import { ClientIdentifier } from './client-identifier'
8
9
  import { ClientName } from './client-name'
10
+ import { FormCard, FormCardProps } from './form-card'
11
+ import { Fieldset } from './fieldset'
9
12
 
10
- export type AcceptFormProps = {
11
- account: Account
12
- clientId: string
13
- clientMetadata: OAuthClientMetadata
14
- clientTrusted: boolean
15
- onAccept: () => void
16
- acceptLabel?: string
13
+ export type AcceptFormProps = Override<
14
+ FormCardProps,
15
+ {
16
+ account: Account
17
+ clientId: string
18
+ clientMetadata: OAuthClientMetadata
19
+ clientTrusted: boolean
20
+ onAccept: () => void
21
+ acceptLabel?: string
17
22
 
18
- onReject: () => void
19
- rejectLabel?: string
23
+ onReject: () => void
24
+ rejectLabel?: string
20
25
 
21
- onBack?: () => void
22
- backLabel?: string
23
- }
26
+ onBack?: () => void
27
+ backLabel?: string
28
+ }
29
+ >
24
30
 
25
31
  export function AcceptForm({
26
32
  account,
@@ -34,79 +40,76 @@ export function AcceptForm({
34
40
  onBack,
35
41
  backLabel = 'Back',
36
42
 
37
- ...attrs
38
- }: AcceptFormProps & HTMLAttributes<HTMLDivElement>) {
39
- return (
40
- <div {...attrs} className={clsx('flex flex-col', attrs.className)}>
41
- {clientTrusted && clientMetadata.logo_uri && (
42
- <div className="flex items-center justify-center mb-4">
43
- <img
44
- crossOrigin="anonymous"
45
- src={clientMetadata.logo_uri}
46
- alt={clientMetadata.client_name}
47
- className="w-16 h-16 rounded-full"
48
- />
49
- </div>
50
- )}
51
-
52
- <ClientName
53
- clientId={clientId}
54
- clientMetadata={clientMetadata}
55
- as="h1"
56
- className="text-2xl font-semibold text-center text-primary"
57
- />
58
-
59
- <p className="mt-4">
60
- <ClientIdentifier clientId={clientId} clientMetadata={clientMetadata} />{' '}
61
- is asking for permission to access your{' '}
62
- <AccountIdentifier account={account} /> account.
63
- </p>
64
-
65
- <p className="mt-4">
66
- By clicking <b>{acceptLabel}</b>, you allow this application to access
67
- your information in accordance to its{' '}
68
- <a
69
- href={clientMetadata.tos_uri}
70
- rel="nofollow noopener"
71
- target="_blank"
72
- className="text-primary underline"
73
- >
74
- terms of service
75
- </a>
76
- .
77
- </p>
43
+ ...props
44
+ }: AcceptFormProps) {
45
+ const doSubmit = (e: FormEvent) => {
46
+ e.preventDefault()
47
+ onAccept()
48
+ }
78
49
 
79
- <div className="flex-auto" />
80
-
81
- <div className="p-4 flex flex-wrap items-center justify-between">
82
- <button
83
- type="button"
84
- onClick={onAccept}
85
- className="py-2 bg-transparent text-primary rounded-md font-semibold order-last"
86
- >
87
- {acceptLabel}
88
- </button>
50
+ return (
51
+ <FormCard
52
+ onSubmit={doSubmit}
53
+ cancel={onBack && <Button onClick={onBack}>{backLabel}</Button>}
54
+ actions={
55
+ <>
56
+ <Button type="submit" color="brand">
57
+ {acceptLabel}
58
+ </Button>
89
59
 
90
- {onBack && (
91
- <button
92
- type="button"
93
- onClick={() => onBack()}
94
- className="mr-2 py-2 bg-transparent text-primary rounded-md font-light"
95
- >
96
- {backLabel}
97
- </button>
60
+ <Button onClick={onReject}>{rejectLabel}</Button>
61
+ </>
62
+ }
63
+ {...props}
64
+ >
65
+ <Fieldset
66
+ title={
67
+ <ClientName clientId={clientId} clientMetadata={clientMetadata} />
68
+ }
69
+ >
70
+ {clientTrusted && clientMetadata.logo_uri && (
71
+ <div key="logo" className="flex items-center justify-center">
72
+ <img
73
+ crossOrigin="anonymous"
74
+ src={clientMetadata.logo_uri}
75
+ alt={clientMetadata.client_name}
76
+ className="w-16 h-16 rounded-full"
77
+ />
78
+ </div>
98
79
  )}
99
80
 
100
- <div className="flex-auto"></div>
81
+ <p>
82
+ <ClientIdentifier
83
+ clientId={clientId}
84
+ clientMetadata={clientMetadata}
85
+ />{' '}
86
+ is asking for permission to access your{' '}
87
+ <AccountIdentifier account={account} /> account.
88
+ </p>
101
89
 
102
- <button
103
- type="button"
104
- onClick={onReject}
105
- className="mr-2 py-2 bg-transparent text-primary rounded-md font-light"
106
- >
107
- {rejectLabel}
108
- </button>
109
- </div>
110
- </div>
90
+ <p>
91
+ By clicking <b>{acceptLabel}</b>, you allow this application to access
92
+ your information in accordance to their{' '}
93
+ <a
94
+ href={clientMetadata.tos_uri}
95
+ rel="nofollow noopener"
96
+ target="_blank"
97
+ className="text-brand underline"
98
+ >
99
+ terms of service
100
+ </a>
101
+ {' and '}
102
+ <a
103
+ href={clientMetadata.policy_uri}
104
+ rel="nofollow noopener"
105
+ target="_blank"
106
+ className="text-brand underline"
107
+ >
108
+ privacy policy
109
+ </a>
110
+ .
111
+ </p>
112
+ </Fieldset>
113
+ </FormCard>
111
114
  )
112
115
  }