@atproto/oauth-provider 0.1.0 → 0.1.2-rc.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 (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":"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"}
@@ -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
  }