@atproto/oauth-provider-ui 0.1.0 → 0.1.2
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/dist/authorization-page-Dhx8lvtZ.js +3 -0
- package/dist/authorization-page-Dhx8lvtZ.js.map +1 -0
- package/dist/bundle-manifest.json +630 -0
- package/dist/error-page-DC6Vc-cv.js +2 -0
- package/dist/error-page-DC6Vc-cv.js.map +1 -0
- package/dist/error-view-CRGNTAn2.css +1 -0
- package/dist/error-view-MVy7C9l0.js +59 -0
- package/dist/error-view-MVy7C9l0.js.map +1 -0
- package/dist/index-CHPoD7Rp.js +20 -0
- package/dist/index-CHPoD7Rp.js.map +1 -0
- package/dist/messages-B0mgsxS-.js +2 -0
- package/dist/messages-B0mgsxS-.js.map +1 -0
- package/dist/messages-B5g8Fkio.js +2 -0
- package/dist/messages-B5g8Fkio.js.map +1 -0
- package/dist/messages-BCMss-Kt.js +2 -0
- package/dist/messages-BCMss-Kt.js.map +1 -0
- package/dist/messages-BGUrKgyK.js +2 -0
- package/dist/messages-BGUrKgyK.js.map +1 -0
- package/dist/messages-BjxAnLDp.js +2 -0
- package/dist/messages-BjxAnLDp.js.map +1 -0
- package/dist/messages-Bjysz3rI.js +2 -0
- package/dist/messages-Bjysz3rI.js.map +1 -0
- package/dist/messages-BvvEr3UX.js +2 -0
- package/dist/messages-BvvEr3UX.js.map +1 -0
- package/dist/messages-Bz6JOhJf.js +2 -0
- package/dist/messages-Bz6JOhJf.js.map +1 -0
- package/dist/messages-BzL3D1EU.js +2 -0
- package/dist/messages-BzL3D1EU.js.map +1 -0
- package/dist/messages-CAvN5UoW.js +2 -0
- package/dist/messages-CAvN5UoW.js.map +1 -0
- package/dist/messages-CEmswT1Q.js +2 -0
- package/dist/messages-CEmswT1Q.js.map +1 -0
- package/dist/messages-CHYqz0q6.js +2 -0
- package/dist/messages-CHYqz0q6.js.map +1 -0
- package/dist/messages-CRmpdijj.js +2 -0
- package/dist/messages-CRmpdijj.js.map +1 -0
- package/dist/messages-Cdb79R6S.js +2 -0
- package/dist/messages-Cdb79R6S.js.map +1 -0
- package/dist/messages-ChkJ_0WT.js +2 -0
- package/dist/messages-ChkJ_0WT.js.map +1 -0
- package/dist/messages-CqiEX6JJ.js +2 -0
- package/dist/messages-CqiEX6JJ.js.map +1 -0
- package/dist/messages-CxkHjJSR.js +2 -0
- package/dist/messages-CxkHjJSR.js.map +1 -0
- package/dist/messages-D0-cWoJ9.js +2 -0
- package/dist/messages-D0-cWoJ9.js.map +1 -0
- package/dist/messages-D2MnAxYY.js +2 -0
- package/dist/messages-D2MnAxYY.js.map +1 -0
- package/dist/messages-D5TZVsui.js +2 -0
- package/dist/messages-D5TZVsui.js.map +1 -0
- package/dist/messages-DBdV4-iw.js +2 -0
- package/dist/messages-DBdV4-iw.js.map +1 -0
- package/dist/messages-DEK3zybC.js +2 -0
- package/dist/messages-DEK3zybC.js.map +1 -0
- package/dist/messages-DGSM5jkd.js +2 -0
- package/dist/messages-DGSM5jkd.js.map +1 -0
- package/dist/messages-DJgAnSTQ.js +2 -0
- package/dist/messages-DJgAnSTQ.js.map +1 -0
- package/dist/messages-DK7O7sb_.js +2 -0
- package/dist/messages-DK7O7sb_.js.map +1 -0
- package/dist/messages-DRp7qc3j.js +2 -0
- package/dist/messages-DRp7qc3j.js.map +1 -0
- package/dist/messages-DT6xRw0m.js +2 -0
- package/dist/messages-DT6xRw0m.js.map +1 -0
- package/dist/messages-LnzLtU0L.js +2 -0
- package/dist/messages-LnzLtU0L.js.map +1 -0
- package/dist/messages-_Nk2qNGw.js +2 -0
- package/dist/messages-_Nk2qNGw.js.map +1 -0
- package/dist/messages-eHH6nZyF.js +2 -0
- package/dist/messages-eHH6nZyF.js.map +1 -0
- package/dist/messages-iNw8zY2C.js +2 -0
- package/dist/messages-iNw8zY2C.js.map +1 -0
- package/dist/messages-ipc0L8yF.js +2 -0
- package/dist/messages-ipc0L8yF.js.map +1 -0
- package/dist/messages-j7LsWm2F.js +2 -0
- package/dist/messages-j7LsWm2F.js.map +1 -0
- package/dist/messages-mgE_5UEw.js +2 -0
- package/dist/messages-mgE_5UEw.js.map +1 -0
- package/dist/messages-oRd-J5--.js +2 -0
- package/dist/messages-oRd-J5--.js.map +1 -0
- package/package.json +10 -8
- package/.linguirc +0 -57
- package/CHANGELOG.md +0 -17
- package/CONTRIBUTING.md +0 -6
- package/authorization-page.html +0 -186
- package/error-page.html +0 -118
- package/index.html +0 -13
- package/src/authorization-page.tsx +0 -49
- package/src/components/forms/button-toggle-visibility.tsx +0 -43
- package/src/components/forms/button.tsx +0 -60
- package/src/components/forms/fieldset.tsx +0 -55
- package/src/components/forms/form-card-async.tsx +0 -103
- package/src/components/forms/form-card.tsx +0 -49
- package/src/components/forms/input-checkbox.tsx +0 -78
- package/src/components/forms/input-container.tsx +0 -107
- package/src/components/forms/input-email-address.tsx +0 -65
- package/src/components/forms/input-new-password.tsx +0 -62
- package/src/components/forms/input-password.tsx +0 -87
- package/src/components/forms/input-text.tsx +0 -82
- package/src/components/forms/input-token.tsx +0 -94
- package/src/components/forms/wizard-card.tsx +0 -116
- package/src/components/layouts/layout-title-page.tsx +0 -78
- package/src/components/layouts/layout-welcome.tsx +0 -78
- package/src/components/utils/account-identifier.tsx +0 -23
- package/src/components/utils/account-image.tsx +0 -33
- package/src/components/utils/admonition.tsx +0 -52
- package/src/components/utils/client-name.tsx +0 -71
- package/src/components/utils/error-card.tsx +0 -93
- package/src/components/utils/error-message.tsx +0 -88
- package/src/components/utils/help-card.tsx +0 -46
- package/src/components/utils/icons.tsx +0 -88
- package/src/components/utils/link-anchor.tsx +0 -28
- package/src/components/utils/link-title.tsx +0 -26
- package/src/components/utils/multi-lang-string.tsx +0 -62
- package/src/components/utils/password-strength-label.tsx +0 -37
- package/src/components/utils/password-strength-meter.tsx +0 -58
- package/src/components/utils/url-viewer.tsx +0 -73
- package/src/error-page.tsx +0 -23
- package/src/hooks/use-api.ts +0 -202
- package/src/hooks/use-async-action.ts +0 -120
- package/src/hooks/use-bound-dispatch.ts +0 -5
- package/src/hooks/use-browser-color-scheme.ts +0 -31
- package/src/hooks/use-random-string.ts +0 -37
- package/src/hooks/use-stepper.ts +0 -87
- package/src/lib/api.ts +0 -225
- package/src/lib/cookies.ts +0 -17
- package/src/lib/json-client.ts +0 -141
- package/src/lib/password.ts +0 -98
- package/src/lib/ref.ts +0 -17
- package/src/lib/util.ts +0 -14
- package/src/locales/an/messages.po +0 -494
- package/src/locales/ast/messages.po +0 -494
- package/src/locales/ca/messages.po +0 -494
- package/src/locales/da/messages.po +0 -494
- package/src/locales/de/messages.po +0 -494
- package/src/locales/el/messages.po +0 -494
- package/src/locales/en/messages.po +0 -494
- package/src/locales/en-GB/messages.po +0 -494
- package/src/locales/es/messages.po +0 -494
- package/src/locales/eu/messages.po +0 -494
- package/src/locales/fi/messages.po +0 -494
- package/src/locales/fr/messages.po +0 -494
- package/src/locales/ga/messages.po +0 -494
- package/src/locales/gl/messages.po +0 -494
- package/src/locales/hi/messages.po +0 -494
- package/src/locales/hu/messages.po +0 -494
- package/src/locales/ia/messages.po +0 -494
- package/src/locales/id/messages.po +0 -494
- package/src/locales/it/messages.po +0 -494
- package/src/locales/ja/messages.po +0 -494
- package/src/locales/km/messages.po +0 -494
- package/src/locales/ko/messages.po +0 -494
- package/src/locales/load.ts +0 -8
- package/src/locales/locale-provider.tsx +0 -108
- package/src/locales/locale-selector.tsx +0 -57
- package/src/locales/locales.ts +0 -183
- package/src/locales/ne/messages.po +0 -494
- package/src/locales/nl/messages.po +0 -494
- package/src/locales/pl/messages.po +0 -494
- package/src/locales/pt-BR/messages.po +0 -494
- package/src/locales/ro/messages.po +0 -494
- package/src/locales/ru/messages.po +0 -494
- package/src/locales/sv/messages.po +0 -494
- package/src/locales/th/messages.po +0 -494
- package/src/locales/tr/messages.po +0 -494
- package/src/locales/uk/messages.po +0 -494
- package/src/locales/vi/messages.po +0 -494
- package/src/locales/zh-CN/messages.po +0 -494
- package/src/locales/zh-HK/messages.po +0 -494
- package/src/locales/zh-TW/messages.po +0 -494
- package/src/style.css +0 -219
- package/src/views/authorize/accept/accept-form.tsx +0 -155
- package/src/views/authorize/accept/accept-view.tsx +0 -70
- package/src/views/authorize/authorize-view.tsx +0 -186
- package/src/views/authorize/reset-password/reset-password-confirm-form.tsx +0 -88
- package/src/views/authorize/reset-password/reset-password-request-form.tsx +0 -80
- package/src/views/authorize/reset-password/reset-password-view.tsx +0 -127
- package/src/views/authorize/sign-in/sign-in-form.tsx +0 -240
- package/src/views/authorize/sign-in/sign-in-picker.tsx +0 -116
- package/src/views/authorize/sign-in/sign-in-view.tsx +0 -145
- package/src/views/authorize/sign-up/sign-up-account-form.tsx +0 -142
- package/src/views/authorize/sign-up/sign-up-disclaimer.tsx +0 -51
- package/src/views/authorize/sign-up/sign-up-handle-form.tsx +0 -287
- package/src/views/authorize/sign-up/sign-up-hcaptcha-form.tsx +0 -108
- package/src/views/authorize/sign-up/sign-up-view.tsx +0 -158
- package/src/views/authorize/welcome/welcome-view.tsx +0 -56
- package/src/views/error/error-view.tsx +0 -31
- package/tsconfig.json +0 -7
- package/tsconfig.src.json +0 -13
- package/tsconfig.src.tsbuildinfo +0 -1
- package/tsconfig.tools.json +0 -8
- package/tsconfig.tools.tsbuildinfo +0 -1
- package/vite.config.mjs +0 -47
- /package/{src/hydration-data.d.ts → hydration-data.d.ts} +0 -0
package/authorization-page.html
DELETED
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>Mock - OAuth Provider</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<div id="root"></div>
|
|
10
|
-
<script>
|
|
11
|
-
/*
|
|
12
|
-
* This file's purpose is to provide a way to develop the UI without
|
|
13
|
-
* running a full featured OAuth server. It mocks the server responses and
|
|
14
|
-
* provides configuration data to the UI.
|
|
15
|
-
*
|
|
16
|
-
* This file is not part of the production build.
|
|
17
|
-
*
|
|
18
|
-
* Start the development server with the following command from the
|
|
19
|
-
* oauth-provider root:
|
|
20
|
-
*
|
|
21
|
-
* ```sh
|
|
22
|
-
* pnpm run start:ui
|
|
23
|
-
* ```
|
|
24
|
-
*
|
|
25
|
-
* Then open the browser at http://localhost:5173/
|
|
26
|
-
*/
|
|
27
|
-
</script>
|
|
28
|
-
<style>
|
|
29
|
-
:root {
|
|
30
|
-
--branding-color-primary: 10 122 255;
|
|
31
|
-
--branding-color-primary-contrast: 255 255 255;
|
|
32
|
-
--branding-color-primary-hue: 212.57142857142856;
|
|
33
|
-
|
|
34
|
-
--branding-color-error: 244 11 66;
|
|
35
|
-
--branding-color-error-contrast: 255 255 255;
|
|
36
|
-
--branding-color-error-hue: 345.83690987124464;
|
|
37
|
-
|
|
38
|
-
--branding-color-warning: 251 86 7;
|
|
39
|
-
--branding-color-warning-contrast: 255 255 255;
|
|
40
|
-
--branding-color-warning-hue: 19.426229508196723;
|
|
41
|
-
|
|
42
|
-
--branding-color-success: 2 195 154;
|
|
43
|
-
--branding-color-success-contrast: 0 0 0;
|
|
44
|
-
--branding-color-success-hue: 167.2538860103627;
|
|
45
|
-
}
|
|
46
|
-
</style>
|
|
47
|
-
<script type="module">
|
|
48
|
-
import { API_ENDPOINT_PREFIX } from '@atproto/oauth-provider-api'
|
|
49
|
-
|
|
50
|
-
/*
|
|
51
|
-
* PDS branding configuration
|
|
52
|
-
*/
|
|
53
|
-
|
|
54
|
-
const name = 'Bluesky'
|
|
55
|
-
const links = [
|
|
56
|
-
{
|
|
57
|
-
title: { en: 'Home' },
|
|
58
|
-
href: 'https://bsky.social/',
|
|
59
|
-
rel: 'canonical', // prevents the login page from being indexed by search engines
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
title: { en: 'Terms of Service' },
|
|
63
|
-
href: 'https://bsky.social/about/support/tos',
|
|
64
|
-
rel: 'terms-of-service',
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
title: { en: 'Privacy Policy' },
|
|
68
|
-
href: 'https://bsky.social/about/support/privacy-policy',
|
|
69
|
-
rel: 'privacy-policy',
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
title: { en: 'Support' },
|
|
73
|
-
href: 'https://blueskyweb.zendesk.com/hc/en-us',
|
|
74
|
-
rel: 'help',
|
|
75
|
-
},
|
|
76
|
-
]
|
|
77
|
-
const logo = `data:image/svg+xml,${encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 320 286"><path fill="rgb(10,122,255)" d="M69.364 19.146c36.687 27.806 76.147 84.186 90.636 114.439 14.489-30.253 53.948-86.633 90.636-114.439C277.107-.917 320-16.44 320 32.957c0 9.865-5.603 82.875-8.889 94.729-11.423 41.208-53.045 51.719-90.071 45.357 64.719 11.12 81.182 47.953 45.627 84.785-80 82.874-106.667-44.333-106.667-44.333s-26.667 127.207-106.667 44.333c-35.555-36.832-19.092-73.665 45.627-84.785-37.026 6.362-78.648-4.149-90.071-45.357C5.603 115.832 0 42.822 0 32.957 0-16.44 42.893-.917 69.364 19.147Z" /></svg>')}`
|
|
78
|
-
|
|
79
|
-
// Provide a value here to test the "sing-in only" flow
|
|
80
|
-
const loginHint = undefined // 'alice.test'
|
|
81
|
-
|
|
82
|
-
// Use empty array to disable the "sing-up" flow, use a single value to
|
|
83
|
-
// disable the domain selector.
|
|
84
|
-
const availableUserDomains = ['.bsky.social', '.bsky.team']
|
|
85
|
-
|
|
86
|
-
// Use non empty string to enable hCaptcha during "sing-up" flow
|
|
87
|
-
const hcaptchaSiteKey = undefined
|
|
88
|
-
|
|
89
|
-
/*
|
|
90
|
-
* Client branding configuration
|
|
91
|
-
*/
|
|
92
|
-
|
|
93
|
-
// Use an "http://" URL to test the "an app on your device" flow
|
|
94
|
-
const clientId = 'https://example.com/client.json'
|
|
95
|
-
const clientName = 'My App'
|
|
96
|
-
const clientPolicyUri = 'https://bsky.app'
|
|
97
|
-
const clientTosUri = 'https://bsky.app'
|
|
98
|
-
const clientLogoUri = 'https://bsky.app'
|
|
99
|
-
|
|
100
|
-
// Mock data
|
|
101
|
-
|
|
102
|
-
const requestUri = 'foo-bar'
|
|
103
|
-
|
|
104
|
-
document.cookie = `csrf-${requestUri}=xyz; path=/`
|
|
105
|
-
|
|
106
|
-
window.__customizationData = {
|
|
107
|
-
availableUserDomains,
|
|
108
|
-
inviteCodeRequired: false,
|
|
109
|
-
hcaptchaSiteKey,
|
|
110
|
-
name,
|
|
111
|
-
links,
|
|
112
|
-
logo,
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
window.__authorizeData = {
|
|
116
|
-
clientId: clientId,
|
|
117
|
-
clientMetadata: {
|
|
118
|
-
client_id: clientId,
|
|
119
|
-
client_name: clientName,
|
|
120
|
-
policy_uri: clientPolicyUri,
|
|
121
|
-
tos_uri: clientTosUri,
|
|
122
|
-
logo_uri: clientLogoUri,
|
|
123
|
-
},
|
|
124
|
-
clientTrusted: false,
|
|
125
|
-
requestUri,
|
|
126
|
-
loginHint,
|
|
127
|
-
sessions: [],
|
|
128
|
-
scopeDetails: [
|
|
129
|
-
{ scope: 'atproto' },
|
|
130
|
-
{ scope: 'transition:generic' },
|
|
131
|
-
{ scope: 'transition:chat.bsky' },
|
|
132
|
-
],
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const origFetch = window.fetch
|
|
136
|
-
|
|
137
|
-
async function mockFetch(...args) {
|
|
138
|
-
const [input, init] = args
|
|
139
|
-
|
|
140
|
-
const method = init?.method ?? 'GET'
|
|
141
|
-
const url =
|
|
142
|
-
typeof input === 'string'
|
|
143
|
-
? new URL(input, window.location)
|
|
144
|
-
: input instanceof URL
|
|
145
|
-
? input
|
|
146
|
-
: undefined
|
|
147
|
-
if (url) {
|
|
148
|
-
switch (`${method} ${url.pathname}`) {
|
|
149
|
-
case `POST ${API_ENDPOINT_PREFIX}/sign-up`:
|
|
150
|
-
case `POST ${API_ENDPOINT_PREFIX}/sign-in`:
|
|
151
|
-
return new Response(
|
|
152
|
-
JSON.stringify({
|
|
153
|
-
consentRequired: false,
|
|
154
|
-
account: {
|
|
155
|
-
sub: 'did:plc:123',
|
|
156
|
-
name: 'Alice',
|
|
157
|
-
email: 'alice@test.com',
|
|
158
|
-
email_verified: false,
|
|
159
|
-
preferred_username: 'alice.test',
|
|
160
|
-
picture: 'https://cat.com/cat.jpg',
|
|
161
|
-
},
|
|
162
|
-
}),
|
|
163
|
-
{
|
|
164
|
-
status: 200,
|
|
165
|
-
headers: { 'Content-Type': 'application/json' },
|
|
166
|
-
},
|
|
167
|
-
)
|
|
168
|
-
case `POST ${API_ENDPOINT_PREFIX}/verify-handle-availability`:
|
|
169
|
-
case `POST ${API_ENDPOINT_PREFIX}/reset-password-request`:
|
|
170
|
-
case `POST ${API_ENDPOINT_PREFIX}/reset-password-confirm`:
|
|
171
|
-
return new Response(null, { status: 204 })
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
return origFetch.call(this, ...args)
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
Object.defineProperty(window, 'fetch', {
|
|
179
|
-
value: mockFetch,
|
|
180
|
-
writable: true,
|
|
181
|
-
configurable: true,
|
|
182
|
-
})
|
|
183
|
-
</script>
|
|
184
|
-
<script src="./src/authorization-page.tsx" type="module"></script>
|
|
185
|
-
</body>
|
|
186
|
-
</html>
|
package/error-page.html
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>Mock - OAuth Provider</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<div id="root"></div>
|
|
10
|
-
<script>
|
|
11
|
-
/*
|
|
12
|
-
* This file's purpose is to provide a way to develop the UI without
|
|
13
|
-
* running a full featured OAuth server. It mocks the server responses and
|
|
14
|
-
* provides configuration data to the UI.
|
|
15
|
-
*
|
|
16
|
-
* This file is not part of the production build.
|
|
17
|
-
*
|
|
18
|
-
* Start the development server with the following command from the
|
|
19
|
-
* oauth-provider root:
|
|
20
|
-
*
|
|
21
|
-
* ```sh
|
|
22
|
-
* pnpm run start:ui
|
|
23
|
-
* ```
|
|
24
|
-
*
|
|
25
|
-
* Then open the browser at http://localhost:5173/
|
|
26
|
-
*/
|
|
27
|
-
</script>
|
|
28
|
-
<style>
|
|
29
|
-
:root {
|
|
30
|
-
--branding-color-primary: 10 122 255;
|
|
31
|
-
--branding-color-primary-contrast: 255 255 255;
|
|
32
|
-
--branding-color-primary-hue: 212.57142857142856;
|
|
33
|
-
|
|
34
|
-
--branding-color-error: 244 11 66;
|
|
35
|
-
--branding-color-error-contrast: 255 255 255;
|
|
36
|
-
--branding-color-error-hue: 345.83690987124464;
|
|
37
|
-
|
|
38
|
-
--branding-color-warning: 251 86 7;
|
|
39
|
-
--branding-color-warning-contrast: 255 255 255;
|
|
40
|
-
--branding-color-warning-hue: 19.426229508196723;
|
|
41
|
-
|
|
42
|
-
--branding-color-success: 2 195 154;
|
|
43
|
-
--branding-color-success-contrast: 0 0 0;
|
|
44
|
-
--branding-color-success-hue: 167.2538860103627;
|
|
45
|
-
}
|
|
46
|
-
</style>
|
|
47
|
-
<script type="module">
|
|
48
|
-
/*
|
|
49
|
-
* PDS branding configuration
|
|
50
|
-
*/
|
|
51
|
-
|
|
52
|
-
const name = 'Bluesky'
|
|
53
|
-
const links = [
|
|
54
|
-
{
|
|
55
|
-
title: { en: 'Home', fr: 'Accueil' },
|
|
56
|
-
href: 'https://bsky.social/',
|
|
57
|
-
rel: 'canonical', // prevents the login page from being indexed by search engines
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
title: { en: 'Terms of Service' },
|
|
61
|
-
href: 'https://bsky.social/about/support/tos',
|
|
62
|
-
rel: 'terms-of-service',
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
title: { en: 'Privacy Policy' },
|
|
66
|
-
href: 'https://bsky.social/about/support/privacy-policy',
|
|
67
|
-
rel: 'privacy-policy',
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
title: { en: 'Support' },
|
|
71
|
-
href: 'https://blueskyweb.zendesk.com/hc/en-us',
|
|
72
|
-
rel: 'help',
|
|
73
|
-
},
|
|
74
|
-
]
|
|
75
|
-
const logo = `data:image/svg+xml,${encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 320 286"><path fill="rgb(10,122,255)" d="M69.364 19.146c36.687 27.806 76.147 84.186 90.636 114.439 14.489-30.253 53.948-86.633 90.636-114.439C277.107-.917 320-16.44 320 32.957c0 9.865-5.603 82.875-8.889 94.729-11.423 41.208-53.045 51.719-90.071 45.357 64.719 11.12 81.182 47.953 45.627 84.785-80 82.874-106.667-44.333-106.667-44.333s-26.667 127.207-106.667 44.333c-35.555-36.832-19.092-73.665 45.627-84.785-37.026 6.362-78.648-4.149-90.071-45.357C5.603 115.832 0 42.822 0 32.957 0-16.44 42.893-.917 69.364 19.147Z" /></svg>')}`
|
|
76
|
-
|
|
77
|
-
// Provide a value here to test the "sing-in only" flow
|
|
78
|
-
const loginHint = undefined // 'alice.test'
|
|
79
|
-
|
|
80
|
-
// Use empty array to disable the "sing-up" flow, use a single value to
|
|
81
|
-
// disable the domain selector.
|
|
82
|
-
const availableUserDomains = ['.bsky.social', '.bsky.team']
|
|
83
|
-
|
|
84
|
-
// Use non empty string to enable hCaptcha during "sing-up" flow
|
|
85
|
-
const hcaptchaSiteKey = undefined
|
|
86
|
-
|
|
87
|
-
/*
|
|
88
|
-
* Client branding configuration
|
|
89
|
-
*/
|
|
90
|
-
|
|
91
|
-
// Use an "http://" URL to test the "an app on your device" flow
|
|
92
|
-
const clientId = 'https://example.com/client.json'
|
|
93
|
-
const clientName = 'My App'
|
|
94
|
-
const clientPolicyUri = 'https://bsky.app'
|
|
95
|
-
const clientTosUri = 'https://bsky.app'
|
|
96
|
-
const clientLogoUri = 'https://bsky.app'
|
|
97
|
-
|
|
98
|
-
// Mock data
|
|
99
|
-
|
|
100
|
-
const requestUri = 'foo-bar'
|
|
101
|
-
|
|
102
|
-
window.__customizationData = {
|
|
103
|
-
availableUserDomains,
|
|
104
|
-
inviteCodeRequired: false,
|
|
105
|
-
hcaptchaSiteKey,
|
|
106
|
-
name,
|
|
107
|
-
links,
|
|
108
|
-
logo,
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
window.__errorData = {
|
|
112
|
-
error: 'foo',
|
|
113
|
-
error_description: 'bar',
|
|
114
|
-
}
|
|
115
|
-
</script>
|
|
116
|
-
<script src="./src/error-page.tsx" type="module"></script>
|
|
117
|
-
</body>
|
|
118
|
-
</html>
|
package/index.html
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>OAuth mock pages</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<a href="authorization-page.html">authorization-page</a>
|
|
10
|
-
<br />
|
|
11
|
-
<a href="error-page.html">error-page</a>
|
|
12
|
-
</body>
|
|
13
|
-
</html>
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import './style.css'
|
|
2
|
-
|
|
3
|
-
import { StrictMode } from 'react'
|
|
4
|
-
import { createRoot } from 'react-dom/client'
|
|
5
|
-
import { ErrorBoundary } from 'react-error-boundary'
|
|
6
|
-
import type { HydrationData } from './hydration-data.d.ts'
|
|
7
|
-
import { LocaleProvider } from './locales/locale-provider.tsx'
|
|
8
|
-
import { AuthorizeView } from './views/authorize/authorize-view.tsx'
|
|
9
|
-
import { ErrorView } from './views/error/error-view.tsx'
|
|
10
|
-
|
|
11
|
-
const {
|
|
12
|
-
__authorizeData: authorizeData,
|
|
13
|
-
__sessions: sessions,
|
|
14
|
-
__customizationData: customizationData,
|
|
15
|
-
} = window as typeof window & HydrationData['authorization-page']
|
|
16
|
-
|
|
17
|
-
// When the user is logging in, make sure the page URL contains the
|
|
18
|
-
// "request_uri" in case the user refreshes the page.
|
|
19
|
-
// @TODO Actually do this on the backend through a redirect.
|
|
20
|
-
const url = new URL(window.location.href)
|
|
21
|
-
if (
|
|
22
|
-
url.pathname === '/oauth/authorize' &&
|
|
23
|
-
!url.searchParams.has('request_uri')
|
|
24
|
-
) {
|
|
25
|
-
url.search = ''
|
|
26
|
-
url.searchParams.set('client_id', authorizeData.clientId)
|
|
27
|
-
url.searchParams.set('request_uri', authorizeData.requestUri)
|
|
28
|
-
window.history.replaceState(history.state, '', url.pathname + url.search)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const container = document.getElementById('root')!
|
|
32
|
-
|
|
33
|
-
createRoot(container).render(
|
|
34
|
-
<StrictMode>
|
|
35
|
-
<LocaleProvider userLocales={authorizeData.uiLocales?.split(' ')}>
|
|
36
|
-
<ErrorBoundary
|
|
37
|
-
fallbackRender={({ error }) => (
|
|
38
|
-
<ErrorView error={error} customizationData={customizationData} />
|
|
39
|
-
)}
|
|
40
|
-
>
|
|
41
|
-
<AuthorizeView
|
|
42
|
-
customizationData={customizationData}
|
|
43
|
-
authorizeData={authorizeData}
|
|
44
|
-
sessions={sessions}
|
|
45
|
-
/>
|
|
46
|
-
</ErrorBoundary>
|
|
47
|
-
</LocaleProvider>
|
|
48
|
-
</StrictMode>,
|
|
49
|
-
)
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { useLingui } from '@lingui/react/macro'
|
|
2
|
-
import { Override } from '../../lib/util.ts'
|
|
3
|
-
import { EyeIcon, EyeSlashIcon } from '../utils/icons.tsx'
|
|
4
|
-
import { Button, ButtonProps } from './button.tsx'
|
|
5
|
-
|
|
6
|
-
export type ButtonToggleVisibilityProps = Override<
|
|
7
|
-
Omit<ButtonProps, 'aria-label' | 'square'>,
|
|
8
|
-
{
|
|
9
|
-
visible: boolean
|
|
10
|
-
toggleVisible: () => void
|
|
11
|
-
}
|
|
12
|
-
>
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Generic button to toggle visibility of an item (e.g. password).
|
|
16
|
-
*/
|
|
17
|
-
export function ButtonToggleVisibility({
|
|
18
|
-
visible,
|
|
19
|
-
toggleVisible,
|
|
20
|
-
|
|
21
|
-
// button
|
|
22
|
-
onClick,
|
|
23
|
-
...props
|
|
24
|
-
}: ButtonToggleVisibilityProps) {
|
|
25
|
-
const { t } = useLingui()
|
|
26
|
-
return (
|
|
27
|
-
<Button
|
|
28
|
-
{...props}
|
|
29
|
-
square
|
|
30
|
-
onClick={(event) => {
|
|
31
|
-
onClick?.(event)
|
|
32
|
-
if (!event.defaultPrevented) toggleVisible()
|
|
33
|
-
}}
|
|
34
|
-
aria-label={visible ? t`Hide` : t`Make visible`}
|
|
35
|
-
>
|
|
36
|
-
{visible ? (
|
|
37
|
-
<EyeIcon className="w-5" aria-hidden />
|
|
38
|
-
) : (
|
|
39
|
-
<EyeSlashIcon className="w-5" aria-hidden />
|
|
40
|
-
)}
|
|
41
|
-
</Button>
|
|
42
|
-
)
|
|
43
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { clsx } from 'clsx'
|
|
2
|
-
import { JSX } from 'react'
|
|
3
|
-
import { Override } from '../../lib/util.ts'
|
|
4
|
-
|
|
5
|
-
export type ButtonProps = Override<
|
|
6
|
-
JSX.IntrinsicElements['button'],
|
|
7
|
-
{
|
|
8
|
-
color?: 'primary' | 'grey'
|
|
9
|
-
loading?: boolean
|
|
10
|
-
transparent?: boolean
|
|
11
|
-
square?: boolean
|
|
12
|
-
}
|
|
13
|
-
>
|
|
14
|
-
|
|
15
|
-
export function Button({
|
|
16
|
-
color = 'grey',
|
|
17
|
-
transparent = false,
|
|
18
|
-
loading = undefined,
|
|
19
|
-
square = false,
|
|
20
|
-
|
|
21
|
-
// button
|
|
22
|
-
children,
|
|
23
|
-
className,
|
|
24
|
-
type = 'button',
|
|
25
|
-
role = 'Button',
|
|
26
|
-
disabled = false,
|
|
27
|
-
...props
|
|
28
|
-
}: ButtonProps) {
|
|
29
|
-
return (
|
|
30
|
-
<button
|
|
31
|
-
role={role}
|
|
32
|
-
type={type}
|
|
33
|
-
disabled={disabled || loading === true}
|
|
34
|
-
{...props}
|
|
35
|
-
className={clsx(
|
|
36
|
-
'cursor-pointer touch-manipulation overflow-hidden truncate rounded-md tracking-wide',
|
|
37
|
-
square ? 'p-2' : 'px-6 py-2',
|
|
38
|
-
color === 'primary'
|
|
39
|
-
? clsx(
|
|
40
|
-
'accent-slate-100',
|
|
41
|
-
transparent
|
|
42
|
-
? 'text-primary bg-transparent'
|
|
43
|
-
: 'bg-primary text-primary-contrast',
|
|
44
|
-
)
|
|
45
|
-
: color === 'grey'
|
|
46
|
-
? clsx(
|
|
47
|
-
'accent-primary',
|
|
48
|
-
'text-slate-600 dark:text-slate-300',
|
|
49
|
-
'hover:bg-gray-200 dark:hover:bg-gray-700',
|
|
50
|
-
transparent ? 'bg-transparent' : 'bg-gray-100 dark:bg-gray-800',
|
|
51
|
-
)
|
|
52
|
-
: undefined,
|
|
53
|
-
'disabled:opacity-50',
|
|
54
|
-
className,
|
|
55
|
-
)}
|
|
56
|
-
>
|
|
57
|
-
{children}
|
|
58
|
-
</button>
|
|
59
|
-
)
|
|
60
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { JSX, ReactNode, createContext, useMemo } from 'react'
|
|
2
|
-
import { useRandomString } from '../../hooks/use-random-string.ts'
|
|
3
|
-
import { Override } from '../../lib/util.ts'
|
|
4
|
-
|
|
5
|
-
export type FieldsetContextValue = {
|
|
6
|
-
disabled: boolean
|
|
7
|
-
labelId?: string
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export const FieldsetContext = createContext<FieldsetContextValue>({
|
|
11
|
-
disabled: false,
|
|
12
|
-
})
|
|
13
|
-
FieldsetContext.displayName = 'FieldsetContext'
|
|
14
|
-
|
|
15
|
-
export type FieldsetCardProps = Override<
|
|
16
|
-
Omit<JSX.IntrinsicElements['fieldset'], 'aria-labelledby'>,
|
|
17
|
-
{
|
|
18
|
-
label?: ReactNode
|
|
19
|
-
}
|
|
20
|
-
>
|
|
21
|
-
|
|
22
|
-
export function Fieldset({
|
|
23
|
-
label,
|
|
24
|
-
children,
|
|
25
|
-
disabled,
|
|
26
|
-
...props
|
|
27
|
-
}: FieldsetCardProps) {
|
|
28
|
-
const labelId = useRandomString({ prefix: 'fieldset-' })
|
|
29
|
-
|
|
30
|
-
const contextValue = useMemo(
|
|
31
|
-
() => ({
|
|
32
|
-
disabled: disabled ?? false,
|
|
33
|
-
labelId: label ? labelId : undefined,
|
|
34
|
-
}),
|
|
35
|
-
[disabled, label, labelId],
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
return (
|
|
39
|
-
<fieldset {...props} aria-labelledby={labelId} disabled={disabled}>
|
|
40
|
-
{label && (
|
|
41
|
-
<legend
|
|
42
|
-
id={labelId}
|
|
43
|
-
key="title"
|
|
44
|
-
className="mb-1 text-sm font-medium text-slate-600 dark:text-slate-400"
|
|
45
|
-
>
|
|
46
|
-
{label}
|
|
47
|
-
</legend>
|
|
48
|
-
)}
|
|
49
|
-
|
|
50
|
-
<div className="flex flex-col space-y-4">
|
|
51
|
-
<FieldsetContext value={contextValue}>{children}</FieldsetContext>
|
|
52
|
-
</div>
|
|
53
|
-
</fieldset>
|
|
54
|
-
)
|
|
55
|
-
}
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { Trans } from '@lingui/react/macro'
|
|
2
|
-
import { FormEvent, ReactNode, useCallback } from 'react'
|
|
3
|
-
import {
|
|
4
|
-
UseAsyncActionOptions,
|
|
5
|
-
useAsyncAction,
|
|
6
|
-
} from '../../hooks/use-async-action.ts'
|
|
7
|
-
import { Override } from '../../lib/util.ts'
|
|
8
|
-
import { ErrorCard } from '../utils/error-card.tsx'
|
|
9
|
-
import { Button } from './button.tsx'
|
|
10
|
-
import { FormCard, FormCardProps } from './form-card.tsx'
|
|
11
|
-
|
|
12
|
-
export type { AsyncActionController } from '../../hooks/use-async-action.ts'
|
|
13
|
-
|
|
14
|
-
export type ErrorRender = (data: { error: Error }) => ReactNode
|
|
15
|
-
export const errorRenderDefault: ErrorRender = ({ error }) => (
|
|
16
|
-
<ErrorCard error={error} />
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
export type FormCardAsyncProps = Override<
|
|
20
|
-
Override<
|
|
21
|
-
Omit<FormCardProps, 'cancel' | 'actions' | 'prepend'>,
|
|
22
|
-
Pick<UseAsyncActionOptions, 'ref' | 'onLoading' | 'onError'>
|
|
23
|
-
>,
|
|
24
|
-
{
|
|
25
|
-
invalid?: boolean
|
|
26
|
-
disabled?: boolean
|
|
27
|
-
|
|
28
|
-
onSubmit: (signal: AbortSignal) => void | PromiseLike<void>
|
|
29
|
-
submitLabel?: ReactNode
|
|
30
|
-
|
|
31
|
-
onCancel?: () => void
|
|
32
|
-
cancelLabel?: ReactNode
|
|
33
|
-
|
|
34
|
-
errorRender?: ErrorRender
|
|
35
|
-
}
|
|
36
|
-
>
|
|
37
|
-
|
|
38
|
-
export function FormCardAsync({
|
|
39
|
-
invalid,
|
|
40
|
-
disabled,
|
|
41
|
-
|
|
42
|
-
onSubmit,
|
|
43
|
-
submitLabel,
|
|
44
|
-
|
|
45
|
-
onCancel = undefined,
|
|
46
|
-
cancelLabel,
|
|
47
|
-
|
|
48
|
-
errorRender = errorRenderDefault,
|
|
49
|
-
|
|
50
|
-
// UseAsyncActionOptions
|
|
51
|
-
ref,
|
|
52
|
-
onLoading,
|
|
53
|
-
onError,
|
|
54
|
-
|
|
55
|
-
// FormCardProps
|
|
56
|
-
children,
|
|
57
|
-
...props
|
|
58
|
-
}: FormCardAsyncProps) {
|
|
59
|
-
const { run, loading, error } = useAsyncAction(onSubmit, {
|
|
60
|
-
ref,
|
|
61
|
-
onError,
|
|
62
|
-
onLoading,
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
const doSubmit = useCallback(
|
|
66
|
-
(event: FormEvent<HTMLFormElement>) => {
|
|
67
|
-
event.preventDefault()
|
|
68
|
-
|
|
69
|
-
if (!event.currentTarget.reportValidity()) return
|
|
70
|
-
|
|
71
|
-
if (!disabled && !invalid) void run()
|
|
72
|
-
},
|
|
73
|
-
[disabled, invalid, run],
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
return (
|
|
77
|
-
<FormCard
|
|
78
|
-
{...props}
|
|
79
|
-
onSubmit={doSubmit}
|
|
80
|
-
disabled={disabled || loading}
|
|
81
|
-
prepend={error != null ? errorRender({ error }) : undefined}
|
|
82
|
-
cancel={
|
|
83
|
-
onCancel && (
|
|
84
|
-
<Button onClick={onCancel}>
|
|
85
|
-
{cancelLabel || <Trans>Cancel</Trans>}
|
|
86
|
-
</Button>
|
|
87
|
-
)
|
|
88
|
-
}
|
|
89
|
-
actions={
|
|
90
|
-
<Button
|
|
91
|
-
color="primary"
|
|
92
|
-
type="submit"
|
|
93
|
-
loading={loading}
|
|
94
|
-
disabled={disabled}
|
|
95
|
-
>
|
|
96
|
-
{submitLabel || <Trans>Submit</Trans>}
|
|
97
|
-
</Button>
|
|
98
|
-
}
|
|
99
|
-
>
|
|
100
|
-
{children}
|
|
101
|
-
</FormCard>
|
|
102
|
-
)
|
|
103
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { JSX, ReactNode } from 'react'
|
|
2
|
-
import { Override } from '../../lib/util.ts'
|
|
3
|
-
|
|
4
|
-
export type FormCardProps = Override<
|
|
5
|
-
JSX.IntrinsicElements['form'],
|
|
6
|
-
{
|
|
7
|
-
disabled?: boolean
|
|
8
|
-
append?: ReactNode
|
|
9
|
-
prepend?: ReactNode
|
|
10
|
-
cancel?: ReactNode
|
|
11
|
-
actions?: ReactNode
|
|
12
|
-
}
|
|
13
|
-
>
|
|
14
|
-
|
|
15
|
-
export function FormCard({
|
|
16
|
-
actions,
|
|
17
|
-
cancel,
|
|
18
|
-
append,
|
|
19
|
-
children,
|
|
20
|
-
prepend,
|
|
21
|
-
disabled,
|
|
22
|
-
|
|
23
|
-
// form
|
|
24
|
-
inert = disabled,
|
|
25
|
-
...props
|
|
26
|
-
}: FormCardProps) {
|
|
27
|
-
return (
|
|
28
|
-
<form {...props} inert={inert} className="flex flex-col space-y-4">
|
|
29
|
-
{prepend && <div key="prepend">{prepend}</div>}
|
|
30
|
-
|
|
31
|
-
<div key="children" className="space-y-4">
|
|
32
|
-
{children}
|
|
33
|
-
</div>
|
|
34
|
-
|
|
35
|
-
{append && <div key="append">{append}</div>}
|
|
36
|
-
|
|
37
|
-
{(actions || cancel) && (
|
|
38
|
-
<div
|
|
39
|
-
key="buttons"
|
|
40
|
-
className="flex flex-row-reverse flex-wrap items-center justify-end space-x-2 space-x-reverse"
|
|
41
|
-
>
|
|
42
|
-
{actions}
|
|
43
|
-
<div className="flex-auto" />
|
|
44
|
-
{cancel}
|
|
45
|
-
</div>
|
|
46
|
-
)}
|
|
47
|
-
</form>
|
|
48
|
-
)
|
|
49
|
-
}
|