@atproto/oauth-provider 0.5.2 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/dist/account/account-manager.d.ts +7 -5
- package/dist/account/account-manager.d.ts.map +1 -1
- package/dist/account/account-manager.js +34 -25
- package/dist/account/account-manager.js.map +1 -1
- package/dist/account/account-store.d.ts +7 -0
- package/dist/account/account-store.d.ts.map +1 -1
- package/dist/account/account-store.js.map +1 -1
- package/dist/account/account.d.ts +1 -11
- package/dist/account/account.d.ts.map +1 -1
- package/dist/account/{sign-up-data.d.ts → sign-up-input.d.ts} +3 -3
- package/dist/account/sign-up-input.d.ts.map +1 -0
- package/dist/account/{sign-up-data.js → sign-up-input.js} +3 -3
- package/dist/account/sign-up-input.js.map +1 -0
- package/dist/assets/assets-middleware.d.ts +2 -0
- package/dist/assets/assets-middleware.d.ts.map +1 -1
- package/dist/assets/assets-middleware.js +12 -14
- package/dist/assets/assets-middleware.js.map +1 -1
- package/dist/lib/csp/index.d.ts +5 -6
- package/dist/lib/csp/index.d.ts.map +1 -1
- package/dist/lib/csp/index.js +14 -11
- package/dist/lib/csp/index.js.map +1 -1
- package/dist/lib/hcaptcha.d.ts +15 -12
- package/dist/lib/hcaptcha.d.ts.map +1 -1
- package/dist/lib/hcaptcha.js +11 -7
- package/dist/lib/hcaptcha.js.map +1 -1
- package/dist/lib/html/build-document.d.ts +2 -2
- package/dist/lib/html/build-document.d.ts.map +1 -1
- package/dist/lib/html/build-document.js +11 -7
- package/dist/lib/html/build-document.js.map +1 -1
- package/dist/lib/html/html.d.ts.map +1 -1
- package/dist/lib/html/html.js +10 -13
- package/dist/lib/html/html.js.map +1 -1
- package/dist/lib/html/util.d.ts +0 -1
- package/dist/lib/html/util.d.ts.map +1 -1
- package/dist/lib/html/util.js +0 -4
- package/dist/lib/html/util.js.map +1 -1
- package/dist/lib/http/response.d.ts +3 -1
- package/dist/lib/http/response.d.ts.map +1 -1
- package/dist/lib/http/response.js +3 -0
- package/dist/lib/http/response.js.map +1 -1
- package/dist/lib/http/security-headers.d.ts +48 -0
- package/dist/lib/http/security-headers.d.ts.map +1 -0
- package/dist/lib/http/security-headers.js +62 -0
- package/dist/lib/http/security-headers.js.map +1 -0
- package/dist/lib/util/type.d.ts +8 -0
- package/dist/lib/util/type.d.ts.map +1 -1
- package/dist/lib/util/type.js.map +1 -1
- package/dist/oauth-hooks.d.ts +4 -25
- package/dist/oauth-hooks.d.ts.map +1 -1
- package/dist/oauth-provider.js +2 -2
- package/dist/oauth-provider.js.map +1 -1
- package/dist/output/backend-data.d.ts +4 -0
- package/dist/output/backend-data.d.ts.map +1 -0
- package/dist/output/backend-data.js +19 -0
- package/dist/output/backend-data.js.map +1 -0
- package/dist/output/build-authorize-data.d.ts +3 -19
- package/dist/output/build-authorize-data.d.ts.map +1 -1
- package/dist/output/build-authorize-data.js.map +1 -1
- package/dist/output/build-customization-data.d.ts +11 -18
- package/dist/output/build-customization-data.d.ts.map +1 -1
- package/dist/output/build-customization-data.js +1 -1
- package/dist/output/build-customization-data.js.map +1 -1
- package/dist/output/build-error-data.d.ts +3 -0
- package/dist/output/build-error-data.d.ts.map +1 -0
- package/dist/output/build-error-data.js +10 -0
- package/dist/output/build-error-data.js.map +1 -0
- package/dist/output/build-error-payload.d.ts +2 -1
- package/dist/output/build-error-payload.d.ts.map +1 -1
- package/dist/output/build-error-payload.js.map +1 -1
- package/dist/output/output-manager.d.ts +10 -4
- package/dist/output/output-manager.d.ts.map +1 -1
- package/dist/output/output-manager.js +68 -39
- package/dist/output/output-manager.js.map +1 -1
- package/dist/output/send-web-page.d.ts +6 -10
- package/dist/output/send-web-page.d.ts.map +1 -1
- package/dist/output/send-web-page.js +27 -47
- package/dist/output/send-web-page.js.map +1 -1
- package/dist/signer/signed-token-payload.d.ts +3 -3
- package/dist/signer/signer.d.ts +2 -2
- package/package.json +8 -41
- package/src/account/account-manager.ts +55 -34
- package/src/account/account-store.ts +8 -0
- package/src/account/account.ts +1 -14
- package/src/account/{sign-up-data.ts → sign-up-input.ts} +2 -2
- package/src/assets/assets-middleware.ts +11 -17
- package/src/lib/csp/index.ts +16 -13
- package/src/lib/hcaptcha.ts +14 -10
- package/src/lib/html/build-document.ts +15 -8
- package/src/lib/html/html.ts +11 -18
- package/src/lib/html/util.ts +0 -4
- package/src/lib/http/response.ts +9 -1
- package/src/lib/http/security-headers.ts +91 -0
- package/src/lib/util/type.ts +18 -0
- package/src/oauth-hooks.ts +4 -25
- package/src/oauth-provider.ts +2 -2
- package/src/output/backend-data.ts +18 -0
- package/src/output/build-authorize-data.ts +3 -26
- package/src/output/build-customization-data.ts +2 -13
- package/src/output/build-error-data.ts +8 -0
- package/src/output/build-error-payload.ts +4 -2
- package/src/output/output-manager.ts +86 -47
- package/src/output/send-web-page.ts +29 -58
- package/tsconfig.backend.json +1 -2
- package/tsconfig.backend.tsbuildinfo +1 -1
- package/tsconfig.json +1 -5
- package/.linguirc +0 -57
- package/dist/account/sign-up-data.d.ts.map +0 -1
- package/dist/account/sign-up-data.js.map +0 -1
- package/dist/assets/app/bundle-manifest.json +0 -614
- package/dist/assets/app/index-DZHZ9kCP.js +0 -36
- package/dist/assets/app/index-DZHZ9kCP.js.map +0 -1
- package/dist/assets/app/main-B_dNxQo_.js +0 -4
- package/dist/assets/app/main-B_dNxQo_.js.map +0 -1
- package/dist/assets/app/main-Dr6y26KY.css +0 -3
- package/dist/assets/app/main-Dr6y26KY.js +0 -306
- package/dist/assets/app/main-Dr6y26KY.js.map +0 -1
- package/dist/assets/app/messages-6_mYuGzB.js +0 -4
- package/dist/assets/app/messages-6_mYuGzB.js.map +0 -1
- package/dist/assets/app/messages-7wdeBTpD.js +0 -4
- package/dist/assets/app/messages-7wdeBTpD.js.map +0 -1
- package/dist/assets/app/messages-B-YFoWKc.js +0 -4
- package/dist/assets/app/messages-B-YFoWKc.js.map +0 -1
- package/dist/assets/app/messages-B10DUOE-.js +0 -4
- package/dist/assets/app/messages-B10DUOE-.js.map +0 -1
- package/dist/assets/app/messages-B4AwFEeZ.js +0 -4
- package/dist/assets/app/messages-B4AwFEeZ.js.map +0 -1
- package/dist/assets/app/messages-BDP8MyEC.js +0 -4
- package/dist/assets/app/messages-BDP8MyEC.js.map +0 -1
- package/dist/assets/app/messages-BIS87lxQ.js +0 -4
- package/dist/assets/app/messages-BIS87lxQ.js.map +0 -1
- package/dist/assets/app/messages-BI_Wbjdt.js +0 -4
- package/dist/assets/app/messages-BI_Wbjdt.js.map +0 -1
- package/dist/assets/app/messages-BMAouhRx.js +0 -4
- package/dist/assets/app/messages-BMAouhRx.js.map +0 -1
- package/dist/assets/app/messages-BdckMnJj.js +0 -4
- package/dist/assets/app/messages-BdckMnJj.js.map +0 -1
- package/dist/assets/app/messages-BgBLzc46.js +0 -4
- package/dist/assets/app/messages-BgBLzc46.js.map +0 -1
- package/dist/assets/app/messages-BobD78yK.js +0 -4
- package/dist/assets/app/messages-BobD78yK.js.map +0 -1
- package/dist/assets/app/messages-BtThT9UZ.js +0 -4
- package/dist/assets/app/messages-BtThT9UZ.js.map +0 -1
- package/dist/assets/app/messages-BwKHkbeh.js +0 -4
- package/dist/assets/app/messages-BwKHkbeh.js.map +0 -1
- package/dist/assets/app/messages-C417YUvA.js +0 -4
- package/dist/assets/app/messages-C417YUvA.js.map +0 -1
- package/dist/assets/app/messages-C4CxO4bO.js +0 -4
- package/dist/assets/app/messages-C4CxO4bO.js.map +0 -1
- package/dist/assets/app/messages-C5vd04e6.js +0 -4
- package/dist/assets/app/messages-C5vd04e6.js.map +0 -1
- package/dist/assets/app/messages-CAri2Wnz.js +0 -4
- package/dist/assets/app/messages-CAri2Wnz.js.map +0 -1
- package/dist/assets/app/messages-CPtWTZeG.js +0 -4
- package/dist/assets/app/messages-CPtWTZeG.js.map +0 -1
- package/dist/assets/app/messages-CiaM5zm8.js +0 -4
- package/dist/assets/app/messages-CiaM5zm8.js.map +0 -1
- package/dist/assets/app/messages-CkL-L2R6.js +0 -4
- package/dist/assets/app/messages-CkL-L2R6.js.map +0 -1
- package/dist/assets/app/messages-Cy_4XLNe.js +0 -4
- package/dist/assets/app/messages-Cy_4XLNe.js.map +0 -1
- package/dist/assets/app/messages-D5_ad-Eo.js +0 -4
- package/dist/assets/app/messages-D5_ad-Eo.js.map +0 -1
- package/dist/assets/app/messages-DChMl9mT.js +0 -4
- package/dist/assets/app/messages-DChMl9mT.js.map +0 -1
- package/dist/assets/app/messages-DWX-DIfv.js +0 -4
- package/dist/assets/app/messages-DWX-DIfv.js.map +0 -1
- package/dist/assets/app/messages-DgfsOphe.js +0 -4
- package/dist/assets/app/messages-DgfsOphe.js.map +0 -1
- package/dist/assets/app/messages-Dj5B_DR6.js +0 -4
- package/dist/assets/app/messages-Dj5B_DR6.js.map +0 -1
- package/dist/assets/app/messages-Dwzqo4eA.js +0 -4
- package/dist/assets/app/messages-Dwzqo4eA.js.map +0 -1
- package/dist/assets/app/messages-ESCIXJR7.js +0 -4
- package/dist/assets/app/messages-ESCIXJR7.js.map +0 -1
- package/dist/assets/app/messages-dglB2edb.js +0 -4
- package/dist/assets/app/messages-dglB2edb.js.map +0 -1
- package/dist/assets/app/messages-e_ClRrWc.js +0 -4
- package/dist/assets/app/messages-e_ClRrWc.js.map +0 -1
- package/dist/assets/app/messages-evvDxmrP.js +0 -4
- package/dist/assets/app/messages-evvDxmrP.js.map +0 -1
- package/dist/assets/app/messages-pPbdLb5B.js +0 -4
- package/dist/assets/app/messages-pPbdLb5B.js.map +0 -1
- package/dist/assets/app/messages-tJv8gHL2.js +0 -4
- package/dist/assets/app/messages-tJv8gHL2.js.map +0 -1
- package/dist/assets/app/messages-vLRVEw96.js +0 -4
- package/dist/assets/app/messages-vLRVEw96.js.map +0 -1
- package/dist/assets/asset.d.ts +0 -9
- package/dist/assets/asset.d.ts.map +0 -1
- package/dist/assets/asset.js +0 -3
- package/dist/assets/asset.js.map +0 -1
- package/dist/assets/index.d.ts +0 -5
- package/dist/assets/index.d.ts.map +0 -1
- package/dist/assets/index.js +0 -78
- package/dist/assets/index.js.map +0 -1
- package/rollup.config.js +0 -98
- package/src/assets/app/app.tsx +0 -43
- package/src/assets/app/backend-data.ts +0 -27
- package/src/assets/app/backend-types.ts +0 -66
- package/src/assets/app/components/forms/button-toggle-visibility.tsx +0 -43
- package/src/assets/app/components/forms/button.tsx +0 -60
- package/src/assets/app/components/forms/fieldset.tsx +0 -55
- package/src/assets/app/components/forms/form-card-async.tsx +0 -103
- package/src/assets/app/components/forms/form-card.tsx +0 -49
- package/src/assets/app/components/forms/input-checkbox.tsx +0 -78
- package/src/assets/app/components/forms/input-container.tsx +0 -107
- package/src/assets/app/components/forms/input-email-address.tsx +0 -65
- package/src/assets/app/components/forms/input-new-password.tsx +0 -62
- package/src/assets/app/components/forms/input-password.tsx +0 -87
- package/src/assets/app/components/forms/input-text.tsx +0 -82
- package/src/assets/app/components/forms/input-token.tsx +0 -94
- package/src/assets/app/components/forms/wizard-card.tsx +0 -116
- package/src/assets/app/components/layouts/layout-title-page.tsx +0 -77
- package/src/assets/app/components/layouts/layout-welcome.tsx +0 -73
- package/src/assets/app/components/utils/account-identifier.tsx +0 -23
- package/src/assets/app/components/utils/account-image.tsx +0 -33
- package/src/assets/app/components/utils/admonition.tsx +0 -52
- package/src/assets/app/components/utils/client-name.tsx +0 -45
- package/src/assets/app/components/utils/error-card.tsx +0 -93
- package/src/assets/app/components/utils/error-message.tsx +0 -88
- package/src/assets/app/components/utils/help-card.tsx +0 -46
- package/src/assets/app/components/utils/icons.tsx +0 -88
- package/src/assets/app/components/utils/link-anchor.tsx +0 -28
- package/src/assets/app/components/utils/link-title.tsx +0 -26
- package/src/assets/app/components/utils/multi-lang-string.tsx +0 -56
- package/src/assets/app/components/utils/password-strength-label.tsx +0 -37
- package/src/assets/app/components/utils/password-strength-meter.tsx +0 -58
- package/src/assets/app/components/utils/url-viewer.tsx +0 -73
- package/src/assets/app/cookies.ts +0 -11
- package/src/assets/app/hooks/use-api.ts +0 -178
- package/src/assets/app/hooks/use-async-action.ts +0 -120
- package/src/assets/app/hooks/use-bound-dispatch.ts +0 -5
- package/src/assets/app/hooks/use-browser-color-scheme.ts +0 -31
- package/src/assets/app/hooks/use-csrf-token.ts +0 -5
- package/src/assets/app/hooks/use-random-string.ts +0 -37
- package/src/assets/app/hooks/use-stepper.ts +0 -87
- package/src/assets/app/index.html +0 -182
- package/src/assets/app/lib/api.ts +0 -289
- package/src/assets/app/lib/clsx.ts +0 -6
- package/src/assets/app/lib/json-client.ts +0 -94
- package/src/assets/app/lib/password.ts +0 -98
- package/src/assets/app/lib/ref.ts +0 -17
- package/src/assets/app/lib/util.ts +0 -13
- package/src/assets/app/locales/an/messages.po +0 -490
- package/src/assets/app/locales/ast/messages.po +0 -490
- package/src/assets/app/locales/ca/messages.po +0 -490
- package/src/assets/app/locales/da/messages.po +0 -490
- package/src/assets/app/locales/de/messages.po +0 -490
- package/src/assets/app/locales/el/messages.po +0 -490
- package/src/assets/app/locales/en/messages.po +0 -490
- package/src/assets/app/locales/en-GB/messages.po +0 -490
- package/src/assets/app/locales/es/messages.po +0 -490
- package/src/assets/app/locales/eu/messages.po +0 -490
- package/src/assets/app/locales/fi/messages.po +0 -490
- package/src/assets/app/locales/fr/messages.po +0 -490
- package/src/assets/app/locales/ga/messages.po +0 -490
- package/src/assets/app/locales/gl/messages.po +0 -490
- package/src/assets/app/locales/hi/messages.po +0 -490
- package/src/assets/app/locales/hu/messages.po +0 -490
- package/src/assets/app/locales/ia/messages.po +0 -490
- package/src/assets/app/locales/id/messages.po +0 -490
- package/src/assets/app/locales/it/messages.po +0 -490
- package/src/assets/app/locales/ja/messages.po +0 -490
- package/src/assets/app/locales/km/messages.po +0 -490
- package/src/assets/app/locales/ko/messages.po +0 -490
- package/src/assets/app/locales/load.ts +0 -8
- package/src/assets/app/locales/locale-context.ts +0 -19
- package/src/assets/app/locales/locale-provider.tsx +0 -112
- package/src/assets/app/locales/locale-selector.tsx +0 -58
- package/src/assets/app/locales/locales.ts +0 -168
- package/src/assets/app/locales/ne/messages.po +0 -490
- package/src/assets/app/locales/nl/messages.po +0 -490
- package/src/assets/app/locales/pl/messages.po +0 -490
- package/src/assets/app/locales/pt-BR/messages.po +0 -490
- package/src/assets/app/locales/ro/messages.po +0 -490
- package/src/assets/app/locales/ru/messages.po +0 -490
- package/src/assets/app/locales/sv/messages.po +0 -490
- package/src/assets/app/locales/th/messages.po +0 -490
- package/src/assets/app/locales/tr/messages.po +0 -490
- package/src/assets/app/locales/uk/messages.po +0 -490
- package/src/assets/app/locales/vi/messages.po +0 -490
- package/src/assets/app/locales/zh-CN/messages.po +0 -490
- package/src/assets/app/locales/zh-HK/messages.po +0 -490
- package/src/assets/app/locales/zh-TW/messages.po +0 -490
- package/src/assets/app/main.css +0 -33
- package/src/assets/app/main.tsx +0 -44
- package/src/assets/app/views/authorize/accept/accept-form.tsx +0 -150
- package/src/assets/app/views/authorize/accept/accept-view.tsx +0 -70
- package/src/assets/app/views/authorize/authorize-view.tsx +0 -180
- package/src/assets/app/views/authorize/reset-password/reset-password-confirm-form.tsx +0 -88
- package/src/assets/app/views/authorize/reset-password/reset-password-request-form.tsx +0 -80
- package/src/assets/app/views/authorize/reset-password/reset-password-view.tsx +0 -127
- package/src/assets/app/views/authorize/sign-in/sign-in-form.tsx +0 -242
- package/src/assets/app/views/authorize/sign-in/sign-in-picker.tsx +0 -116
- package/src/assets/app/views/authorize/sign-in/sign-in-view.tsx +0 -145
- package/src/assets/app/views/authorize/sign-up/sign-up-account-form.tsx +0 -142
- package/src/assets/app/views/authorize/sign-up/sign-up-disclaimer.tsx +0 -51
- package/src/assets/app/views/authorize/sign-up/sign-up-handle-form.tsx +0 -287
- package/src/assets/app/views/authorize/sign-up/sign-up-hcaptcha-form.tsx +0 -108
- package/src/assets/app/views/authorize/sign-up/sign-up-view.tsx +0 -158
- package/src/assets/app/views/authorize/welcome/welcome-view.tsx +0 -56
- package/src/assets/app/views/error/error-view.tsx +0 -31
- package/src/assets/asset.ts +0 -9
- package/src/assets/index.ts +0 -86
- package/tailwind.config.js +0 -31
- package/tsconfig.frontend.json +0 -11
- package/tsconfig.frontend.tsbuildinfo +0 -1
- package/tsconfig.tools.json +0 -8
- package/tsconfig.tools.tsbuildinfo +0 -1
- package/vite.config.mjs +0 -16
@@ -1,14 +1,29 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.OutputManager = void 0;
|
4
|
-
const
|
5
|
-
const
|
6
|
-
const
|
4
|
+
const oauth_provider_ui_1 = require("@atproto/oauth-provider-ui");
|
5
|
+
const assets_middleware_js_1 = require("../assets/assets-middleware.js");
|
6
|
+
const index_js_1 = require("../lib/csp/index.js");
|
7
|
+
const index_js_2 = require("../lib/html/index.js");
|
8
|
+
const security_headers_js_1 = require("../lib/http/security-headers.js");
|
7
9
|
const locale_js_1 = require("../lib/locale.js");
|
10
|
+
const backend_data_js_1 = require("./backend-data.js");
|
8
11
|
const build_authorize_data_js_1 = require("./build-authorize-data.js");
|
9
12
|
const build_customization_data_js_1 = require("./build-customization-data.js");
|
13
|
+
const build_error_data_js_1 = require("./build-error-data.js");
|
10
14
|
const build_error_payload_js_1 = require("./build-error-payload.js");
|
11
15
|
const send_web_page_js_1 = require("./send-web-page.js");
|
16
|
+
const BASE_CSP = {
|
17
|
+
// API calls are made to the same origin
|
18
|
+
'connect-src': ["'self'"],
|
19
|
+
// Allow loading of PDS logo & User avatars
|
20
|
+
'img-src': ['data:', 'https:'],
|
21
|
+
// Prevent embedding in iframes
|
22
|
+
'frame-ancestors': ["'none'"],
|
23
|
+
};
|
24
|
+
/**
|
25
|
+
* @see {@link https://docs.hcaptcha.com/#content-security-policy-settings}
|
26
|
+
*/
|
12
27
|
const HCAPTCHA_CSP = {
|
13
28
|
'script-src': ['https://hcaptcha.com', 'https://*.hcaptcha.com'],
|
14
29
|
'frame-src': ['https://hcaptcha.com', 'https://*.hcaptcha.com'],
|
@@ -21,68 +36,82 @@ class OutputManager {
|
|
21
36
|
{ name: 'robots', content: 'noindex' },
|
22
37
|
{ name: 'description', content: 'ATProto OAuth authorization page' },
|
23
38
|
];
|
24
|
-
scripts;
|
25
|
-
styles;
|
26
39
|
csp;
|
40
|
+
coep;
|
41
|
+
customizationData;
|
42
|
+
customizationCss;
|
27
43
|
constructor(customization) {
|
28
44
|
this.links = customization.branding?.links;
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
//
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
// "cache" these:
|
46
|
+
this.customizationData = (0, build_customization_data_js_1.buildCustomizationData)(customization);
|
47
|
+
this.customizationCss = (0, index_js_2.cssCode)((0, build_customization_data_js_1.buildCustomizationCss)(customization));
|
48
|
+
this.csp = (0, index_js_1.mergeCsp)(BASE_CSP, customization?.hcaptcha ? HCAPTCHA_CSP : undefined);
|
49
|
+
// Because we are loading avatar images from external sources, that might
|
50
|
+
// not have CORP headers set, we need to use at least "credentialless".
|
51
|
+
this.coep = customization?.hcaptcha
|
52
|
+
? // https://github.com/hCaptcha/react-hcaptcha/issues/259
|
53
|
+
// @TODO Remove the use of `unsafeNone` once the issue above is resolved
|
54
|
+
security_headers_js_1.CrossOriginEmbedderPolicy.unsafeNone
|
55
|
+
: security_headers_js_1.CrossOriginEmbedderPolicy.credentialless;
|
56
|
+
}
|
57
|
+
buildAssets(name, backendData) {
|
58
|
+
return {
|
59
|
+
scripts: [
|
60
|
+
(0, backend_data_js_1.declareBackendData)(backendData),
|
61
|
+
// After backend injected data
|
62
|
+
...Array.from(oauth_provider_ui_1.assets)
|
63
|
+
.filter(([, item]) => item.type === 'chunk' && item.isEntry && item.name === name)
|
64
|
+
.map(([filename]) => ({ url: (0, assets_middleware_js_1.buildAssetUrl)(filename) })),
|
65
|
+
],
|
66
|
+
styles: [
|
67
|
+
...Array.from(oauth_provider_ui_1.assets)
|
68
|
+
.filter(([, item]) => item.mime === 'text/css')
|
69
|
+
.map(([filename]) => ({ url: (0, assets_middleware_js_1.buildAssetUrl)(filename) })),
|
70
|
+
// Last (to be able to override the default styles)
|
71
|
+
this.customizationCss,
|
72
|
+
],
|
49
73
|
};
|
50
|
-
this.csp = (0, index_js_2.mergeCsp)(customizationCsp, assetsCsp);
|
51
74
|
}
|
52
75
|
async sendAuthorizePage(res, data, options) {
|
53
76
|
const locale = negotiateLocale(data.parameters.ui_locales?.split(' ') ?? options?.preferredLocales);
|
77
|
+
const { scripts, styles } = this.buildAssets('authorization-page', {
|
78
|
+
__availableLocales: locale_js_1.AVAILABLE_LOCALES,
|
79
|
+
__customizationData: this.customizationData,
|
80
|
+
__authorizeData: (0, build_authorize_data_js_1.buildAuthorizeData)(data),
|
81
|
+
});
|
54
82
|
return (0, send_web_page_js_1.sendWebPage)(res, {
|
55
|
-
scripts
|
56
|
-
|
57
|
-
...this.scripts,
|
58
|
-
],
|
59
|
-
styles: this.styles,
|
83
|
+
scripts,
|
84
|
+
styles,
|
60
85
|
meta: this.meta,
|
61
86
|
links: this.buildLinks(locale),
|
62
87
|
htmlAttrs: { lang: locale },
|
63
|
-
body: (0,
|
88
|
+
body: (0, index_js_2.html) `<div id="root"></div>`,
|
64
89
|
csp: this.csp,
|
90
|
+
coep: this.coep,
|
65
91
|
});
|
66
92
|
}
|
67
93
|
async sendErrorPage(res, err, options) {
|
68
94
|
const locale = negotiateLocale(options?.preferredLocales);
|
95
|
+
const { scripts, styles } = this.buildAssets('error-page', {
|
96
|
+
__availableLocales: locale_js_1.AVAILABLE_LOCALES,
|
97
|
+
__customizationData: this.customizationData,
|
98
|
+
__errorData: (0, build_error_data_js_1.buildErrorData)(err),
|
99
|
+
});
|
69
100
|
return (0, send_web_page_js_1.sendWebPage)(res, {
|
70
101
|
status: (0, build_error_payload_js_1.buildErrorStatus)(err),
|
71
|
-
scripts
|
72
|
-
|
73
|
-
...this.scripts,
|
74
|
-
],
|
75
|
-
styles: this.styles,
|
102
|
+
scripts,
|
103
|
+
styles,
|
76
104
|
meta: this.meta,
|
77
105
|
links: this.buildLinks(locale),
|
78
106
|
htmlAttrs: { lang: locale },
|
79
|
-
body: (0,
|
107
|
+
body: (0, index_js_2.html) `<div id="root"></div>`,
|
80
108
|
csp: this.csp,
|
109
|
+
coep: this.coep,
|
81
110
|
});
|
82
111
|
}
|
83
112
|
buildLinks(locale) {
|
84
113
|
return this.links
|
85
|
-
?.map(({ rel, href, title }) => (0,
|
114
|
+
?.map(({ rel, href, title }) => (0, index_js_2.isLinkRel)(rel)
|
86
115
|
? typeof title === 'string'
|
87
116
|
? { href, rel, title }
|
88
117
|
: { href, rel, title: title[locale] || title.en }
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"output-manager.js","sourceRoot":"","sources":["../../src/output/output-manager.ts"],"names":[],"mappings":";;;AAEA,
|
1
|
+
{"version":3,"file":"output-manager.js","sourceRoot":"","sources":["../../src/output/output-manager.ts"],"names":[],"mappings":"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"}
|
@@ -1,12 +1,8 @@
|
|
1
1
|
import type { ServerResponse } from 'node:http';
|
2
|
-
import { CspConfig
|
3
|
-
import {
|
4
|
-
import {
|
5
|
-
export declare
|
6
|
-
export type SendWebPageOptions = BuildDocumentOptions &
|
7
|
-
|
8
|
-
};
|
9
|
-
export declare function sendWebPage(res: ServerResponse, options: SendWebPageOptions): Promise<void>;
|
10
|
-
export declare function assetsToCsp(assets?: Iterable<Html | AssetRef>): Generator<CspValue>;
|
11
|
-
export declare function assetToCsp(asset: Html | AssetRef): CspValue;
|
2
|
+
import { CspConfig } from '../lib/csp/index.js';
|
3
|
+
import { BuildDocumentOptions } from '../lib/html/index.js';
|
4
|
+
import { WriteHtmlOptions } from '../lib/http/response.js';
|
5
|
+
export declare const DEFAULT_CSP: CspConfig;
|
6
|
+
export type SendWebPageOptions = BuildDocumentOptions & WriteHtmlOptions;
|
7
|
+
export declare function sendWebPage(res: ServerResponse, { csp: inputCsp, ...options }: SendWebPageOptions): Promise<void>;
|
12
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,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,EAAE,SAAS,
|
1
|
+
{"version":3,"file":"send-web-page.d.ts","sourceRoot":"","sources":["../../src/output/send-web-page.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAsB,MAAM,qBAAqB,CAAA;AACnE,OAAO,EAEL,oBAAoB,EAGrB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,gBAAgB,EAAa,MAAM,yBAAyB,CAAA;AAErE,eAAO,MAAM,WAAW,EAAE,SAGzB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG,oBAAoB,GAAG,gBAAgB,CAAA;AAExE,wBAAsB,WAAW,CAC/B,GAAG,EAAE,cAAc,EACnB,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,EAAE,kBAAkB,GAChD,OAAO,CAAC,IAAI,CAAC,CAcf"}
|
@@ -1,64 +1,44 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.
|
3
|
+
exports.DEFAULT_CSP = void 0;
|
4
4
|
exports.sendWebPage = sendWebPage;
|
5
|
-
exports.assetsToCsp = assetsToCsp;
|
6
|
-
exports.assetToCsp = assetToCsp;
|
7
5
|
const node_crypto_1 = require("node:crypto");
|
8
6
|
const index_js_1 = require("../lib/csp/index.js");
|
9
7
|
const index_js_2 = require("../lib/html/index.js");
|
10
8
|
const response_js_1 = require("../lib/http/response.js");
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
9
|
+
exports.DEFAULT_CSP = {
|
10
|
+
'upgrade-insecure-requests': true,
|
11
|
+
'default-src': ["'none'"],
|
12
|
+
};
|
13
|
+
async function sendWebPage(res, { csp: inputCsp, ...options }) {
|
14
|
+
// @NOTE the csp string might be quite long. In that case it might be tempting
|
15
|
+
// to set it through the http-equiv <meta> in the HTML. However, some
|
16
|
+
// directives cannot be enforced by browsers when set through the meta tag
|
17
|
+
// (e.g. 'frame-ancestors'). Therefore, it's better to set the CSP through the
|
18
|
+
// HTTP header.
|
19
|
+
const csp = (0, index_js_1.mergeCsp)(exports.DEFAULT_CSP, inputCsp, {
|
21
20
|
'base-uri': options.base?.origin,
|
22
|
-
'script-src':
|
23
|
-
'style-src':
|
24
|
-
'img-src': ["'self'", 'data:', 'https:'],
|
25
|
-
'connect-src': ["'self'"],
|
26
|
-
'upgrade-insecure-requests': true,
|
27
|
-
// Prevents the CSP to be embedded in a page <meta>:
|
28
|
-
'frame-ancestors': ["'none'"],
|
21
|
+
'script-src': options.scripts?.map(assetToCsp),
|
22
|
+
'style-src': options.styles?.map(assetToCsp),
|
29
23
|
});
|
30
|
-
|
31
|
-
|
32
|
-
// reason, we won't try to avoid too long headers and let the proxy throw
|
33
|
-
// in case of a too long header.
|
34
|
-
res.setHeader('Content-Security-Policy', (0, index_js_1.buildCsp)(csp));
|
35
|
-
// @TODO: make these headers configurable (?)
|
36
|
-
res.setHeader('Permissions-Policy', 'otp-credentials=*, document-domain=()');
|
37
|
-
res.setHeader('Cross-Origin-Embedder-Policy', 'credentialless');
|
38
|
-
res.setHeader('Cross-Origin-Resource-Policy', 'same-origin');
|
39
|
-
res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
|
40
|
-
res.setHeader('Referrer-Policy', 'same-origin');
|
41
|
-
res.setHeader('X-Frame-Options', 'DENY');
|
42
|
-
res.setHeader('X-Content-Type-Options', 'nosniff');
|
43
|
-
res.setHeader('X-XSS-Protection', '0');
|
44
|
-
res.setHeader('Strict-Transport-Security', 'max-age=63072000');
|
45
|
-
const html = (0, index_js_2.buildDocument)(options);
|
46
|
-
return (0, response_js_1.writeHtml)(res, html.toString(), options);
|
47
|
-
}
|
48
|
-
function* assetsToCsp(assets) {
|
49
|
-
if (assets) {
|
50
|
-
for (const asset of assets) {
|
51
|
-
yield assetToCsp(asset);
|
52
|
-
}
|
53
|
-
}
|
24
|
+
const html = (0, index_js_2.buildDocument)(options).toString();
|
25
|
+
return (0, response_js_1.writeHtml)(res, html, { ...options, csp });
|
54
26
|
}
|
55
27
|
function assetToCsp(asset) {
|
56
28
|
if (asset instanceof index_js_2.Html) {
|
57
|
-
|
58
|
-
|
29
|
+
// Inline assets are "allowed" by their hash
|
30
|
+
const hash = (0, node_crypto_1.createHash)('sha256');
|
31
|
+
for (const fragment of asset)
|
32
|
+
hash.update(fragment);
|
33
|
+
return `'sha256-${hash.digest('base64')}'`;
|
59
34
|
}
|
60
35
|
else {
|
61
|
-
|
36
|
+
// External assets are referenced by their origin
|
37
|
+
if (asset.url.startsWith('https:') || asset.url.startsWith('http:')) {
|
38
|
+
return new URL(asset.url).origin;
|
39
|
+
}
|
40
|
+
// Internal assets are served from the same origin
|
41
|
+
return `'self'`;
|
62
42
|
}
|
63
43
|
}
|
64
44
|
//# sourceMappingURL=send-web-page.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"send-web-page.js","sourceRoot":"","sources":["../../src/output/send-web-page.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"send-web-page.js","sourceRoot":"","sources":["../../src/output/send-web-page.ts"],"names":[],"mappings":";;;AAkBA,kCAiBC;AAnCD,6CAAwC;AAExC,kDAAmE;AACnE,mDAK6B;AAC7B,yDAAqE;AAExD,QAAA,WAAW,GAAc;IACpC,2BAA2B,EAAE,IAAI;IACjC,aAAa,EAAE,CAAC,QAAQ,CAAC;CAC1B,CAAA;AAIM,KAAK,UAAU,WAAW,CAC/B,GAAmB,EACnB,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAsB;IAEjD,8EAA8E;IAC9E,qEAAqE;IACrE,0EAA0E;IAC1E,8EAA8E;IAC9E,eAAe;IACf,MAAM,GAAG,GAAG,IAAA,mBAAQ,EAAC,mBAAW,EAAE,QAAQ,EAAE;QAC1C,UAAU,EAAE,OAAO,CAAC,IAAI,EAAE,MAAyC;QACnE,YAAY,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,UAAU,CAAC;QAC9C,WAAW,EAAE,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,CAAC;KAC7C,CAAC,CAAA;IAEF,MAAM,IAAI,GAAG,IAAA,wBAAa,EAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAA;IAC9C,OAAO,IAAA,uBAAS,EAAC,GAAG,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,CAAC,CAAA;AAClD,CAAC;AAED,SAAS,UAAU,CAAC,KAAsB;IACxC,IAAI,KAAK,YAAY,eAAI,EAAE,CAAC;QAC1B,4CAA4C;QAC5C,MAAM,IAAI,GAAG,IAAA,wBAAU,EAAC,QAAQ,CAAC,CAAA;QACjC,KAAK,MAAM,QAAQ,IAAI,KAAK;YAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QACnD,OAAO,WAAW,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAA;IAC5C,CAAC;SAAM,CAAC;QACN,iDAAiD;QACjD,IAAI,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACpE,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAA8C,CAAA;QAC1E,CAAC;QAED,kDAAkD;QAClD,OAAO,QAAQ,CAAA;IACjB,CAAC;AACH,CAAC"}
|
@@ -2,18 +2,18 @@ import { z } from 'zod';
|
|
2
2
|
import { Simplify } from '../lib/util/type.js';
|
3
3
|
export declare const signedTokenPayloadSchema: z.ZodIntersection<z.ZodObject<{
|
4
4
|
iat: z.ZodNumber;
|
5
|
-
aud: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "atleastone">]>;
|
6
5
|
iss: z.ZodString;
|
6
|
+
aud: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "atleastone">]>;
|
7
7
|
exp: z.ZodNumber;
|
8
8
|
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
9
9
|
iat: z.ZodNumber;
|
10
|
-
aud: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "atleastone">]>;
|
11
10
|
iss: z.ZodString;
|
11
|
+
aud: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "atleastone">]>;
|
12
12
|
exp: z.ZodNumber;
|
13
13
|
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
14
14
|
iat: z.ZodNumber;
|
15
|
-
aud: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "atleastone">]>;
|
16
15
|
iss: z.ZodString;
|
16
|
+
aud: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "atleastone">]>;
|
17
17
|
exp: z.ZodNumber;
|
18
18
|
}, z.ZodTypeAny, "passthrough">>, z.ZodObject<z.objectUtil.extendShape<{
|
19
19
|
nonce: z.ZodOptional<z.ZodOptional<z.ZodString>>;
|
package/dist/signer/signer.d.ts
CHANGED
@@ -200,8 +200,8 @@ export declare class Signer {
|
|
200
200
|
htu?: string | undefined;
|
201
201
|
ath?: string | undefined;
|
202
202
|
sub?: string | undefined;
|
203
|
-
aud?: string | [string, ...string[]] | undefined;
|
204
203
|
iss?: string | undefined;
|
204
|
+
aud?: string | [string, ...string[]] | undefined;
|
205
205
|
exp?: number | undefined;
|
206
206
|
nbf?: number | undefined;
|
207
207
|
azp?: string | undefined;
|
@@ -5817,8 +5817,8 @@ export declare class Signer {
|
|
5817
5817
|
htu?: string | undefined;
|
5818
5818
|
ath?: string | undefined;
|
5819
5819
|
sub?: string | undefined;
|
5820
|
-
aud?: string | [string, ...string[]] | undefined;
|
5821
5820
|
iss?: string | undefined;
|
5821
|
+
aud?: string | [string, ...string[]] | undefined;
|
5822
5822
|
exp?: number | undefined;
|
5823
5823
|
nbf?: number | undefined;
|
5824
5824
|
azp?: string | undefined;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@atproto/oauth-provider",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.6.1",
|
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": [
|
@@ -43,49 +43,24 @@
|
|
43
43
|
"jose": "^5.2.0",
|
44
44
|
"psl": "^1.9.0",
|
45
45
|
"zod": "^3.23.8",
|
46
|
+
"@atproto-labs/fetch": "0.2.2",
|
46
47
|
"@atproto-labs/fetch-node": "0.1.8",
|
47
48
|
"@atproto-labs/pipe": "0.1.0",
|
48
49
|
"@atproto-labs/simple-store": "0.1.2",
|
49
50
|
"@atproto-labs/simple-store-memory": "0.1.2",
|
50
|
-
"@atproto/common": "^0.4.8",
|
51
51
|
"@atproto/jwk": "0.1.4",
|
52
52
|
"@atproto/jwk-jose": "0.1.5",
|
53
53
|
"@atproto/oauth-types": "0.2.4",
|
54
|
-
"@atproto/
|
55
|
-
"@atproto
|
54
|
+
"@atproto/oauth-provider-api": "0.0.1",
|
55
|
+
"@atproto/common": "^0.4.8",
|
56
|
+
"@atproto/oauth-provider-ui": "0.0.2",
|
57
|
+
"@atproto/syntax": "0.4.0"
|
56
58
|
},
|
57
59
|
"devDependencies": {
|
58
|
-
"@hcaptcha/react-hcaptcha": "^1.11.2",
|
59
|
-
"@lingui/cli": "^5.2.0",
|
60
|
-
"@lingui/core": "^5.2.0",
|
61
|
-
"@lingui/react": "^5.2.0",
|
62
|
-
"@lingui/swc-plugin": "^5.4.0",
|
63
|
-
"@lingui/vite-plugin": "^5.2.0",
|
64
|
-
"@rollup/plugin-commonjs": "^28.0.2",
|
65
|
-
"@rollup/plugin-dynamic-import-vars": "^2.1.5",
|
66
|
-
"@rollup/plugin-node-resolve": "^16.0.0",
|
67
|
-
"@rollup/plugin-swc": "^0.4.0",
|
68
|
-
"@swc/core": "^1.10.18",
|
69
|
-
"@swc/helpers": "^0.5.15",
|
70
60
|
"@types/cookie": "^0.6.0",
|
71
61
|
"@types/forwarded": "0.1.3",
|
72
62
|
"@types/psl": "1.1.3",
|
73
|
-
"@types/
|
74
|
-
"@types/react-dom": "^19.0.4",
|
75
|
-
"@types/send": "^0.17.4",
|
76
|
-
"@vitejs/plugin-react-swc": "^3.8.0",
|
77
|
-
"@web/rollup-plugin-import-meta-assets": "^2.2.1",
|
78
|
-
"autoprefixer": "^10.4.17",
|
79
|
-
"postcss": "^8.4.38",
|
80
|
-
"react": "^19.0.0",
|
81
|
-
"react-dom": "^19.0.0",
|
82
|
-
"react-error-boundary": "^5.0.0",
|
83
|
-
"rollup": "^4.13.0",
|
84
|
-
"rollup-plugin-postcss": "^4.0.2",
|
85
|
-
"tailwindcss": "^3.4.3",
|
86
|
-
"typescript": "^5.6.3",
|
87
|
-
"vite": "^6.2.0",
|
88
|
-
"@atproto-labs/rollup-plugin-bundle-manifest": "0.1.2"
|
63
|
+
"@types/send": "^0.17.4"
|
89
64
|
},
|
90
65
|
"postcss": {
|
91
66
|
"plugins": {
|
@@ -94,14 +69,6 @@
|
|
94
69
|
}
|
95
70
|
},
|
96
71
|
"scripts": {
|
97
|
-
"
|
98
|
-
"po:compile": "lingui compile --typescript",
|
99
|
-
"prebuild:frontend": "pnpm po:compile",
|
100
|
-
"build:frontend": "rollup --config rollup.config.js",
|
101
|
-
"build:backend": "tsc --build --force tsconfig.backend.json",
|
102
|
-
"start:ui": "vite",
|
103
|
-
"dev:frontend": "pnpm run build:frontend --watch",
|
104
|
-
"dev:catalogs": "pnpm run po:extract --debounce 250 --watch > /dev/null",
|
105
|
-
"dev:messages": "pnpm run po:compile --debounce 500 --watch"
|
72
|
+
"build": "tsc --build tsconfig.backend.json"
|
106
73
|
}
|
107
74
|
}
|
@@ -18,9 +18,10 @@ import {
|
|
18
18
|
AccountStore,
|
19
19
|
ResetPasswordConfirmData,
|
20
20
|
ResetPasswordRequestData,
|
21
|
+
SignUpData,
|
21
22
|
} from './account-store.js'
|
22
23
|
import { SignInData } from './sign-in-data.js'
|
23
|
-
import {
|
24
|
+
import { SignUpInput } from './sign-up-input.js'
|
24
25
|
|
25
26
|
const TIMING_ATTACK_MITIGATION_DELAY = 400
|
26
27
|
const BRUTE_FORCE_MITIGATION_DELAY = 300
|
@@ -41,59 +42,79 @@ export class AccountManager {
|
|
41
42
|
: undefined
|
42
43
|
}
|
43
44
|
|
44
|
-
protected async
|
45
|
-
|
45
|
+
protected async processHcaptchaToken(
|
46
|
+
input: SignUpInput,
|
46
47
|
deviceId: DeviceId,
|
47
48
|
deviceMetadata: RequestMetadata,
|
48
|
-
): Promise<
|
49
|
-
|
50
|
-
|
51
|
-
if (this.inviteCodeRequired && !data.inviteCode) {
|
52
|
-
throw new InvalidRequestError('Invite code is required')
|
49
|
+
): Promise<HcaptchaVerifyResult | undefined> {
|
50
|
+
if (!this.hcaptchaClient) {
|
51
|
+
return undefined
|
53
52
|
}
|
54
53
|
|
55
|
-
if (
|
56
|
-
|
57
|
-
|
58
|
-
}
|
54
|
+
if (!input.hcaptchaToken) {
|
55
|
+
throw new InvalidRequestError('hCaptcha token is required')
|
56
|
+
}
|
59
57
|
|
60
|
-
|
58
|
+
const { allowed, result } = await this.hcaptchaClient
|
59
|
+
.verify(
|
61
60
|
'signup',
|
62
|
-
|
61
|
+
input.hcaptchaToken,
|
63
62
|
deviceMetadata.ipAddress,
|
64
|
-
|
63
|
+
input.handle,
|
65
64
|
deviceMetadata.userAgent,
|
66
65
|
)
|
67
|
-
|
68
|
-
|
69
|
-
data,
|
70
|
-
allowed,
|
71
|
-
result,
|
72
|
-
deviceId,
|
73
|
-
deviceMetadata,
|
66
|
+
.catch((err) => {
|
67
|
+
throw InvalidRequestError.from(err, 'hCaptcha verification failed')
|
74
68
|
})
|
75
69
|
|
76
|
-
|
77
|
-
|
78
|
-
|
70
|
+
if (!allowed) {
|
71
|
+
throw new InvalidRequestError('hCaptcha verification failed')
|
72
|
+
}
|
73
|
+
|
74
|
+
return result
|
75
|
+
}
|
79
76
|
|
80
|
-
|
77
|
+
protected async enforceInviteCode(
|
78
|
+
input: SignUpInput,
|
79
|
+
_deviceId: DeviceId,
|
80
|
+
_deviceMetadata: RequestMetadata,
|
81
|
+
): Promise<string | undefined> {
|
82
|
+
if (!this.inviteCodeRequired) {
|
83
|
+
return undefined
|
81
84
|
}
|
82
85
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
86
|
+
if (!input.inviteCode) {
|
87
|
+
throw new InvalidRequestError('Invite code is required')
|
88
|
+
}
|
89
|
+
|
90
|
+
return input.inviteCode
|
91
|
+
}
|
92
|
+
|
93
|
+
protected async buildSignupData(
|
94
|
+
input: SignUpInput,
|
95
|
+
deviceId: DeviceId,
|
96
|
+
deviceMetadata: RequestMetadata,
|
97
|
+
): Promise<SignUpData> {
|
98
|
+
const [hcaptchaResult, inviteCode] = await Promise.all([
|
99
|
+
this.processHcaptchaToken(input, deviceId, deviceMetadata),
|
100
|
+
this.enforceInviteCode(input, deviceId, deviceMetadata),
|
101
|
+
])
|
102
|
+
|
103
|
+
return { ...input, hcaptchaResult, inviteCode }
|
89
104
|
}
|
90
105
|
|
91
106
|
public async signUp(
|
92
|
-
|
107
|
+
input: SignUpInput,
|
93
108
|
deviceId: DeviceId,
|
94
109
|
deviceMetadata: RequestMetadata,
|
95
110
|
): Promise<AccountInfo> {
|
96
|
-
await this.
|
111
|
+
await callAsync(this.hooks.onSignupAttempt, {
|
112
|
+
input,
|
113
|
+
deviceId,
|
114
|
+
deviceMetadata,
|
115
|
+
})
|
116
|
+
|
117
|
+
const data = await this.buildSignupData(input, deviceId, deviceMetadata)
|
97
118
|
|
98
119
|
// Mitigation against brute forcing email of users.
|
99
120
|
// @TODO Add rate limit to all the OAuth routes.
|
@@ -4,6 +4,7 @@ import { z } from 'zod'
|
|
4
4
|
import { ensureValidHandle, normalizeHandle } from '@atproto/syntax'
|
5
5
|
import { ClientId } from '../client/client-id.js'
|
6
6
|
import { DeviceId } from '../device/device-id.js'
|
7
|
+
import { HcaptchaVerifyResult } from '../lib/hcaptcha.js'
|
7
8
|
import { localeSchema } from '../lib/locale.js'
|
8
9
|
import { Awaitable, buildInterfaceChecker } from '../lib/util/type.js'
|
9
10
|
import {
|
@@ -13,6 +14,7 @@ import {
|
|
13
14
|
} from '../oauth-errors.js'
|
14
15
|
import { Sub } from '../oidc/sub.js'
|
15
16
|
import { Account } from './account.js'
|
17
|
+
import { SignUpInput } from './sign-up-input.js'
|
16
18
|
|
17
19
|
// @NOTE Change the length here to force stronger passwords (through a reset)
|
18
20
|
export const oldPasswordSchema = z.string().min(1)
|
@@ -49,6 +51,7 @@ export const emailSchema = z
|
|
49
51
|
})
|
50
52
|
.transform((value) => value.toLowerCase())
|
51
53
|
export const inviteCodeSchema = z.string().min(1)
|
54
|
+
export type InviteCode = z.infer<typeof inviteCodeSchema>
|
52
55
|
|
53
56
|
export const authenticateAccountDataSchema = z
|
54
57
|
.object({
|
@@ -118,6 +121,11 @@ export type AccountInfo = {
|
|
118
121
|
info: DeviceAccountInfo
|
119
122
|
}
|
120
123
|
|
124
|
+
export type SignUpData = SignUpInput & {
|
125
|
+
hcaptchaResult?: HcaptchaVerifyResult
|
126
|
+
inviteCode?: InviteCode
|
127
|
+
}
|
128
|
+
|
121
129
|
export interface AccountStore {
|
122
130
|
/**
|
123
131
|
* @throws {HandleUnavailableError} - To indicate that the handle is already taken
|
package/src/account/account.ts
CHANGED
@@ -1,14 +1 @@
|
|
1
|
-
|
2
|
-
import { Sub } from '../oidc/sub.js'
|
3
|
-
|
4
|
-
export type Account = Simplify<{
|
5
|
-
sub: Sub // Account id
|
6
|
-
aud: string | [string, ...string[]] // Resource server URL
|
7
|
-
|
8
|
-
// OIDC inspired
|
9
|
-
preferred_username?: string
|
10
|
-
email?: string
|
11
|
-
email_verified?: boolean
|
12
|
-
picture?: string
|
13
|
-
name?: string
|
14
|
-
}>
|
1
|
+
export type { Account } from '@atproto/oauth-provider-api'
|
@@ -2,10 +2,10 @@ import { z } from 'zod'
|
|
2
2
|
import { hcaptchaTokenSchema } from '../lib/hcaptcha.js'
|
3
3
|
import { createAccountDataSchema } from './account-store.js'
|
4
4
|
|
5
|
-
export const
|
5
|
+
export const signUpInputSchema = createAccountDataSchema
|
6
6
|
.extend({
|
7
7
|
hcaptchaToken: hcaptchaTokenSchema.optional(),
|
8
8
|
})
|
9
9
|
.strict()
|
10
10
|
|
11
|
-
export type
|
11
|
+
export type SignUpInput = z.TypeOf<typeof signUpInputSchema>
|