@atproto/oauth-provider 0.19.6 → 0.19.8

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 (165) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/errors/error-parser.js +5 -5
  3. package/dist/errors/error-parser.js.map +1 -1
  4. package/package.json +22 -18
  5. package/src/access-token/access-token-mode.ts +0 -4
  6. package/src/account/account-manager.ts +0 -591
  7. package/src/account/account-store.ts +0 -305
  8. package/src/account/sign-in-data.ts +0 -15
  9. package/src/account/sign-up-input.ts +0 -20
  10. package/src/client/client-auth.ts +0 -64
  11. package/src/client/client-data.ts +0 -9
  12. package/src/client/client-id.ts +0 -4
  13. package/src/client/client-info.ts +0 -13
  14. package/src/client/client-manager.ts +0 -772
  15. package/src/client/client-store.ts +0 -35
  16. package/src/client/client-utils.ts +0 -37
  17. package/src/client/client.ts +0 -394
  18. package/src/constants.ts +0 -80
  19. package/src/customization/branding.ts +0 -12
  20. package/src/customization/build-customization-css.ts +0 -55
  21. package/src/customization/build-customization-data.ts +0 -24
  22. package/src/customization/colors.ts +0 -48
  23. package/src/customization/customization.ts +0 -29
  24. package/src/customization/links.ts +0 -10
  25. package/src/device/device-data.ts +0 -11
  26. package/src/device/device-id.ts +0 -27
  27. package/src/device/device-manager.ts +0 -292
  28. package/src/device/device-store.ts +0 -31
  29. package/src/device/session-id.ts +0 -21
  30. package/src/dpop/dpop-manager.ts +0 -214
  31. package/src/dpop/dpop-nonce.ts +0 -121
  32. package/src/dpop/dpop-proof.ts +0 -6
  33. package/src/errors/access-denied-error.ts +0 -12
  34. package/src/errors/account-selection-required-error.ts +0 -12
  35. package/src/errors/authorization-error.ts +0 -45
  36. package/src/errors/consent-required-error.ts +0 -12
  37. package/src/errors/error-parser.ts +0 -147
  38. package/src/errors/handle-unavailable-error.ts +0 -23
  39. package/src/errors/invalid-authorization-details-error.ts +0 -27
  40. package/src/errors/invalid-client-error.ts +0 -20
  41. package/src/errors/invalid-client-id-error.ts +0 -31
  42. package/src/errors/invalid-client-metadata-error.ts +0 -68
  43. package/src/errors/invalid-credentials-error.ts +0 -29
  44. package/src/errors/invalid-dpop-key-binding-error.ts +0 -21
  45. package/src/errors/invalid-dpop-proof-error.ts +0 -13
  46. package/src/errors/invalid-grant-error.ts +0 -21
  47. package/src/errors/invalid-invite-code-error.ts +0 -10
  48. package/src/errors/invalid-redirect-uri-error.ts +0 -17
  49. package/src/errors/invalid-request-error.ts +0 -32
  50. package/src/errors/invalid-scope-error.ts +0 -15
  51. package/src/errors/invalid-token-error.ts +0 -60
  52. package/src/errors/login-required-error.ts +0 -12
  53. package/src/errors/oauth-error.ts +0 -28
  54. package/src/errors/second-authentication-factor-required-error.ts +0 -25
  55. package/src/errors/unauthorized-client-error.ts +0 -20
  56. package/src/errors/use-dpop-nonce-error.ts +0 -32
  57. package/src/errors/www-authenticate-error.ts +0 -64
  58. package/src/index.ts +0 -16
  59. package/src/lexicon/lexicon-data.ts +0 -11
  60. package/src/lexicon/lexicon-getter.ts +0 -55
  61. package/src/lexicon/lexicon-manager.ts +0 -116
  62. package/src/lexicon/lexicon-store.ts +0 -35
  63. package/src/lib/csp/index.ts +0 -101
  64. package/src/lib/hcaptcha.ts +0 -228
  65. package/src/lib/html/README.md +0 -9
  66. package/src/lib/html/build-document.ts +0 -151
  67. package/src/lib/html/escapers.ts +0 -66
  68. package/src/lib/html/html.ts +0 -56
  69. package/src/lib/html/hydration-data.ts +0 -19
  70. package/src/lib/html/index.ts +0 -5
  71. package/src/lib/html/tags.ts +0 -67
  72. package/src/lib/html/util.ts +0 -17
  73. package/src/lib/http/README.md +0 -11
  74. package/src/lib/http/accept.ts +0 -90
  75. package/src/lib/http/context.ts +0 -42
  76. package/src/lib/http/headers.ts +0 -15
  77. package/src/lib/http/index.ts +0 -10
  78. package/src/lib/http/method.ts +0 -18
  79. package/src/lib/http/middleware.ts +0 -169
  80. package/src/lib/http/parser.ts +0 -101
  81. package/src/lib/http/path.ts +0 -82
  82. package/src/lib/http/request.ts +0 -256
  83. package/src/lib/http/response.ts +0 -122
  84. package/src/lib/http/route.ts +0 -60
  85. package/src/lib/http/router.ts +0 -117
  86. package/src/lib/http/security-headers.ts +0 -100
  87. package/src/lib/http/stream.ts +0 -57
  88. package/src/lib/http/types.ts +0 -16
  89. package/src/lib/http/url.ts +0 -23
  90. package/src/lib/nsid.ts +0 -10
  91. package/src/lib/redis.ts +0 -25
  92. package/src/lib/util/authorization-header.ts +0 -28
  93. package/src/lib/util/cast.ts +0 -18
  94. package/src/lib/util/color.ts +0 -168
  95. package/src/lib/util/crypto.ts +0 -32
  96. package/src/lib/util/date.ts +0 -7
  97. package/src/lib/util/error.ts +0 -7
  98. package/src/lib/util/function.ts +0 -39
  99. package/src/lib/util/locale.ts +0 -12
  100. package/src/lib/util/object.ts +0 -23
  101. package/src/lib/util/redirect-uri.ts +0 -46
  102. package/src/lib/util/time.ts +0 -49
  103. package/src/lib/util/type.ts +0 -182
  104. package/src/lib/util/ui8.ts +0 -14
  105. package/src/lib/util/well-known.ts +0 -8
  106. package/src/lib/util/zod-error.ts +0 -26
  107. package/src/lib/write-form-redirect.ts +0 -58
  108. package/src/lib/write-html.ts +0 -70
  109. package/src/metadata/build-metadata.ts +0 -141
  110. package/src/oauth-client.ts +0 -3
  111. package/src/oauth-dpop.ts +0 -2
  112. package/src/oauth-errors.ts +0 -26
  113. package/src/oauth-hooks.ts +0 -519
  114. package/src/oauth-middleware.ts +0 -53
  115. package/src/oauth-provider.ts +0 -1110
  116. package/src/oauth-store.ts +0 -12
  117. package/src/oauth-verifier.ts +0 -260
  118. package/src/replay/replay-manager.ts +0 -51
  119. package/src/replay/replay-store-memory.ts +0 -36
  120. package/src/replay/replay-store-redis.ts +0 -30
  121. package/src/replay/replay-store.ts +0 -44
  122. package/src/request/code.ts +0 -23
  123. package/src/request/request-data.ts +0 -36
  124. package/src/request/request-id.ts +0 -22
  125. package/src/request/request-manager.ts +0 -521
  126. package/src/request/request-store.ts +0 -60
  127. package/src/request/request-uri.ts +0 -42
  128. package/src/result/authorization-redirect-parameters.ts +0 -24
  129. package/src/result/authorization-result-authorize-page.ts +0 -16
  130. package/src/result/authorization-result-redirect.ts +0 -8
  131. package/src/router/assets/assets-manifest.ts +0 -117
  132. package/src/router/assets/assets.ts +0 -124
  133. package/src/router/assets/csrf.ts +0 -79
  134. package/src/router/assets/send-account-page.ts +0 -23
  135. package/src/router/assets/send-authorization-page.ts +0 -42
  136. package/src/router/assets/send-cookie-error-page.ts +0 -21
  137. package/src/router/assets/send-error-page.ts +0 -25
  138. package/src/router/assets/send-redirect.ts +0 -140
  139. package/src/router/create-account-page-middleware.ts +0 -88
  140. package/src/router/create-api-middleware.ts +0 -1051
  141. package/src/router/create-authorization-page-middleware.ts +0 -281
  142. package/src/router/create-oauth-middleware.ts +0 -257
  143. package/src/router/error-handler.ts +0 -6
  144. package/src/router/middleware-options.ts +0 -9
  145. package/src/signer/access-token-payload.ts +0 -25
  146. package/src/signer/api-token-payload.ts +0 -18
  147. package/src/signer/signer.ts +0 -121
  148. package/src/token/refresh-token.ts +0 -30
  149. package/src/token/token-claims.ts +0 -22
  150. package/src/token/token-data.ts +0 -40
  151. package/src/token/token-id.ts +0 -25
  152. package/src/token/token-manager.ts +0 -427
  153. package/src/token/token-store.ts +0 -88
  154. package/src/types/authorization-response-error.ts +0 -27
  155. package/src/types/color-hue.ts +0 -3
  156. package/src/types/email-otp.ts +0 -3
  157. package/src/types/email.ts +0 -26
  158. package/src/types/handle.ts +0 -23
  159. package/src/types/invite-code.ts +0 -4
  160. package/src/types/par-response-error.ts +0 -25
  161. package/src/types/password.ts +0 -4
  162. package/src/types/rgb-color.ts +0 -21
  163. package/tsconfig.build.json +0 -8
  164. package/tsconfig.build.tsbuildinfo +0 -1
  165. package/tsconfig.json +0 -4
@@ -1,182 +0,0 @@
1
- export type Simplify<T> = { [K in keyof T]: T[K] } & {}
2
- export type Override<T, V> = Simplify<{
3
- [K in keyof (V & T)]: K extends keyof V
4
- ? V[K]
5
- : K extends keyof T
6
- ? T[K]
7
- : never
8
- }>
9
- export type Awaitable<T> = T | Promise<T>
10
- export type NonNullableKeys<T, K extends keyof T> = Simplify<
11
- OmitKey<T, K> & {
12
- [P in K]-?: NonNullable<T[P]>
13
- }
14
- >
15
- /**
16
- * When a type has an `[x: string]: unknown` index signature, in addition to
17
- * some known properties, using {@link Omit} will result in a type that only has
18
- * the index signature, and no known properties.
19
- *
20
- * ```ts
21
- * Omit<{ a: 3; b: 4; [x: string]: unknown }, 'a'> // { [x: string]: unknown }
22
- * ```
23
- *
24
- * In order to properly omit specific known properties from a type with an index
25
- * signature, we need to use another utility type that will behave correctly.
26
- *
27
- * ```ts
28
- * OmitKey<{ a: 3; b: 4; [x: string]: unknown }, 'a'> // { b: 4; [x: string]: unknown }
29
- * ```
30
- */
31
- export type OmitKey<T, K extends keyof T> = {
32
- [K2 in keyof T as K2 extends K ? never : K2]: T[K2]
33
- }
34
-
35
- export type RequiredKey<T, K extends keyof T = never> = Simplify<
36
- T & {
37
- [L in K]-?: unknown extends T[L]
38
- ? NonNullable<unknown> | null
39
- : Exclude<T[L], undefined>
40
- }
41
- >
42
-
43
- /**
44
- * Converts a tuple to the equivalent type of combining every item into a single
45
- * one. If any of the item in the tuple is non nullish, the result will be non
46
- * nullish.
47
- */
48
- export type CombinedTuple<T extends readonly unknown[]> = T extends []
49
- ? undefined
50
- : Exclude<
51
- T[number],
52
- // If any item in the tuple is never `null` (resp. `undefined`), exclude
53
- // `null` (resp. `undefined`) from `T[number]`
54
- {
55
- [K in keyof T]-?:
56
- | (null extends T[K] ? never : null)
57
- | (undefined extends T[K] ? never : undefined)
58
- }[keyof T]
59
- >
60
-
61
- /**
62
- * Similar to {@link Required} but also ensures that all values are defined.
63
- */
64
- export type RequiredDefined<T> = { [K in keyof T]-?: Exclude<T[K], undefined> }
65
-
66
- // <hardcore-mode> (don't touch this)
67
-
68
- /**
69
- * @example
70
- * ```ts
71
- * type F = UnionToFnUnion<'a' | 'b'> // (() => 'a') | (() => 'b')
72
- * ```
73
- */
74
- type UnionToFnUnion<T> = T extends any ? () => T : never
75
-
76
- /**
77
- * @example
78
- * ```ts
79
- * type A = UnionToIntersection<(() => 'a') | (() => 'b')> // (() => 'a') & (() => 'b')
80
- *
81
- * UnionToIntersection<{ foo: string | number } | { foo: number; bar: 4 }> // { foo: number; bar: 4 }
82
- * ```
83
- */
84
- type UnionToIntersection<T> = (T extends any ? (x: T) => void : never) extends (
85
- x: infer U,
86
- ) => void
87
- ? U
88
- : never
89
-
90
- /**
91
- * @example
92
- * ```ts
93
- * type B = ExtractUnionItem<'a' | 'b'> // 'b'
94
- * ```
95
- */
96
- type ExtractUnionItem<T> =
97
- // There exists a quirk in the way TypeScript works when inferring return
98
- // types of an (disjoined) intersection of functions:
99
- //
100
- // type AnB = (() => 'a') & (() => 'b')
101
- // type B = AnB extends () => infer R ? R : never // 'b'
102
- //
103
- // By turning the input union T (e.g. 'a' | 'b') into a union of function
104
- // (() => 'a') | (() => 'b') and then into an intersection of those functions
105
- // (() => 'a') & (() => 'b'), we can exploit the special TypeScript behavior
106
- // to infer only the last return type from the functions, which is effectively
107
- // equal to the last item of the input union T.
108
- UnionToIntersection<UnionToFnUnion<T>> extends () => infer R ? R : never
109
-
110
- /**
111
- * Utility that turn a union of types (`'a' | 'b'`) into a tuple with matching
112
- * types (`['a', 'b']`).
113
- *
114
- * @note this only work with unions of "const" types. Using this with globals
115
- * types (`string`, etc.) will yield unexpected results.
116
- *
117
- * @example
118
- * ```ts
119
- * type T = UnionToTuple<'a' | 'b'> // ['a', 'b']
120
- * type T = UnionToTuple<'a' | 'b' | 'c'> // ['a', 'b', 'c']
121
- * ```
122
- */
123
- type UnionToTuple<T> = UnionToTupleInternal<T>
124
-
125
- type UnionToTupleInternal<
126
- T,
127
- // Accumulator for terminal recursivity (initialized to empty tuple)
128
- Acc extends readonly any[] = [],
129
- // Get the next item from the union (if any)
130
- Next = ExtractUnionItem<T>,
131
- > =
132
- // If there were no more items to extract from the union T, then we are done
133
- [Next] extends [never]
134
- ? // Return result of previous recursive calls
135
- Acc
136
- : // Recursively call UnionToTupleInternal by Exclude'ing the Next item from
137
- // the union (T) and adding it to the accumulator.
138
- UnionToTupleInternal<Exclude<T, Next>, readonly [Next, ...Acc]>
139
-
140
- /**
141
- * This utility allows to create an assertion function that checks if a
142
- * particular interface is fully implemented by some value.
143
- *
144
- * The use of the (rather complex) {@link UnionToTuple} allows to ensure that,
145
- * at runtime, all the required interface keys are indeed checked, and that
146
- * future additions to the interface do not result in a false sense of type
147
- * safety.
148
- *
149
- * @note This function should not be made public, as it relies on a quirk of
150
- * TypeScript to work properly.
151
- *
152
- * @example Valid use
153
- *
154
- * ```ts
155
- * const isFoo = buildInterfaceChecker<{ foo: string }>(['foo'])
156
- * const isFooBar = buildInterfaceChecker<{ foo: string; bar: boolean }>([
157
- * 'foo',
158
- * 'bar',
159
- * ])
160
- *
161
- * declare const val: { foo?: string }
162
- *
163
- * if (isFoo(val)) {
164
- * val // { foo: string }
165
- * }
166
- * ```
167
- *
168
- * @example Use cases where the runtime keys do not match the interface keys
169
- *
170
- * ```ts
171
- * buildInterfaceChecker<{ foo: string }>([])
172
- * buildInterfaceChecker<{ foo: string }>(['fee'])
173
- * buildInterfaceChecker<{ foo: string; bar: string }>(['foo'])
174
- * buildInterfaceChecker<{ foo: string; bar: string }>(['foo', 'baz'])
175
- * ```
176
- */
177
- export const buildInterfaceChecker =
178
- <I extends object>(keys: readonly string[] & UnionToTuple<keyof I>) =>
179
- <V extends Partial<I>>(value: V): value is V & RequiredDefined<I> =>
180
- keys.every((name) => value[name] !== undefined)
181
-
182
- // </hardcore-mode>
@@ -1,14 +0,0 @@
1
- export function parseUi8Hex(v: string) {
2
- return asUi8(parseInt(v, 16))
3
- }
4
-
5
- export function parseUi8Dec(v: string) {
6
- return asUi8(parseInt(v, 10))
7
- }
8
-
9
- export function asUi8(v: number) {
10
- if (v >= 0 && v <= 255 && Number.isInteger(v)) return v
11
- throw new TypeError(
12
- `Invalid value "${v}" (expected an integer between 0 and 255)`,
13
- )
14
- }
@@ -1,8 +0,0 @@
1
- export function buildWellknownUrl(url: URL, name: string): URL {
2
- const path =
3
- url.pathname === '/'
4
- ? `/.well-known/${name}`
5
- : `${url.pathname.replace(/\/+$/, '')}/${name}`
6
-
7
- return new URL(path, url)
8
- }
@@ -1,26 +0,0 @@
1
- import { ZodError, ZodIssue, ZodIssueCode } from 'zod'
2
-
3
- export function formatZodError(err: ZodError, prefix?: string): string {
4
- const message = err.issues.length
5
- ? err.issues.map(formatZodIssue).join('; ')
6
- : err.message // Should never happen (issues should never be empty)
7
- return prefix ? `${prefix}: ${message}` : message
8
- }
9
-
10
- export function formatZodIssue(issue: ZodIssue): string {
11
- if (issue.code === ZodIssueCode.invalid_union) {
12
- return issue.unionErrors
13
- .map((err) => err.issues.map(formatZodIssue).join('; '))
14
- .join(', or ')
15
- }
16
-
17
- if (issue.path.length === 1 && typeof issue.path[0] === 'number') {
18
- return `${issue.message} at index ${issue.path[0]}`
19
- }
20
-
21
- if (issue.path.length) {
22
- return `${issue.message} at ${issue.path.join('.')}`
23
- }
24
-
25
- return issue.message
26
- }
@@ -1,58 +0,0 @@
1
- import type { ServerResponse } from 'node:http'
2
- import { html, js } from './html/index.js'
3
- import { setCookie } from './http/request.js'
4
- import { SecurityHeadersOptions } from './http/security-headers.js'
5
- import { writeHtml } from './write-html.js'
6
-
7
- export type WriteFormRedirectOptions = SecurityHeadersOptions
8
-
9
- // We prevent the user from coming "back" to this page and resubmitting the form
10
- // repeatedly by disabling the submit button after the first submission.
11
- const SCRIPT = js`
12
- const form = document.forms[0];
13
-
14
- let canSubmit = true;
15
-
16
- form.addEventListener('submit', (event) => {
17
- if (!canSubmit) {
18
- event.preventDefault();
19
- } else {
20
- canSubmit = false;
21
- }
22
- });
23
-
24
- setTimeout(() => {
25
- form.submit();
26
- }, 1);
27
- `
28
-
29
- // @NOTE If translations and design are needed, consider replacing this with a
30
- // web app page.
31
-
32
- export function writeFormRedirect(
33
- res: ServerResponse,
34
- method: 'post' | 'get',
35
- uri: string,
36
- params: Iterable<[string, string]>,
37
- options?: WriteFormRedirectOptions,
38
- ): void {
39
- res.setHeader('Cache-Control', 'no-store')
40
-
41
- // Prevent the Chrome from caching this page
42
- // see: https://latesthackingnews.com/2023/12/12/google-updates-chrome-bfcache-for-faster-page-viewing/
43
- setCookie(res, 'bfCacheBypass', 'foo', { maxAge: 1, sameSite: 'lax' })
44
-
45
- return writeHtml(res, {
46
- ...options,
47
- htmlAttrs: { lang: 'en' },
48
- scripts: [SCRIPT],
49
- body: html`
50
- <form method="${method}" action="${uri}">
51
- ${Array.from(params, ([key, value]) => [
52
- html`<input type="hidden" name="${key}" value="${value}" />`,
53
- ])}
54
- <input type="submit" value="Continue" />
55
- </form>
56
- `,
57
- })
58
- }
@@ -1,70 +0,0 @@
1
- import { createHash } from 'node:crypto'
2
- import type { ServerResponse } from 'node:http'
3
- import { CspValue, mergeCsp } from './csp/index.js'
4
- import {
5
- AssetRef,
6
- BuildDocumentOptions,
7
- Html,
8
- buildDocument,
9
- } from './html/index.js'
10
- import { WriteResponseOptions, writeBuffer } from './http/response.js'
11
- import {
12
- SecurityHeadersOptions,
13
- setSecurityHeaders,
14
- } from './http/security-headers.js'
15
-
16
- export type WriteHtmlOptions = BuildDocumentOptions &
17
- WriteResponseOptions &
18
- SecurityHeadersOptions
19
-
20
- export function writeHtml(
21
- res: ServerResponse,
22
- options: WriteHtmlOptions,
23
- ): void {
24
- // @NOTE the csp string might be quite long. In that case it might be tempting
25
- // to set it through the http-equiv <meta> in the HTML. However, some
26
- // directives cannot be enforced by browsers when set through the meta tag
27
- // (e.g. 'frame-ancestors'). Therefore, it's better to set the CSP through the
28
- // HTTP header.
29
- const csp = mergeCsp(
30
- {
31
- // Keep "upgrade-insecure-requests" in sync with HSTS setting. HSTS is
32
- // typically set to false for localhost endpoints. Chrome and FF will
33
- // ignore "upgrade-insecure-requests" from localhost, but Safari will
34
- // enforce it, requiring to be explicitly disable it for localhost.
35
- 'upgrade-insecure-requests': options.hsts !== false,
36
- 'default-src': ["'none'"],
37
- 'base-uri': options.base?.origin as undefined | `https://${string}`,
38
- 'script-src': options.scripts?.map(assetToCsp).filter((v) => v != null),
39
- 'style-src': options.styles?.map(assetToCsp).filter((v) => v != null),
40
- },
41
- options.csp,
42
- )
43
-
44
- const html = buildDocument(options).toString()
45
-
46
- // HTML pages should always be served with safety protection headers
47
- setSecurityHeaders(res, { ...options, csp })
48
- writeBuffer(res, html, {
49
- ...options,
50
- contentType: options?.contentType ?? 'text/html; charset=utf-8',
51
- })
52
- }
53
-
54
- function assetToCsp(asset?: Html | AssetRef): undefined | CspValue {
55
- if (asset == null) return undefined
56
- if (asset instanceof Html) {
57
- // Inline assets are "allowed" by their hash
58
- const hash = createHash('sha256')
59
- for (const fragment of asset) hash.update(fragment)
60
- return `'sha256-${hash.digest('base64')}'`
61
- } else {
62
- // External assets are referenced by their origin
63
- if (asset.url.startsWith('https:') || asset.url.startsWith('http:')) {
64
- return new URL(asset.url).origin as `https:${string}` | `http:${string}`
65
- }
66
-
67
- // Internal assets are served from the same origin
68
- return `'self'`
69
- }
70
- }
@@ -1,141 +0,0 @@
1
- import { Keyset } from '@atproto/jwk'
2
- import {
3
- OAuthAuthorizationServerMetadata,
4
- OAuthIssuerIdentifier,
5
- oauthAuthorizationServerMetadataValidator,
6
- } from '@atproto/oauth-types'
7
- import { Client } from '../client/client.js'
8
- import { VERIFY_ALGOS } from '../lib/util/crypto.js'
9
-
10
- export type CustomMetadata = {
11
- authorization_details_types_supported?: string[]
12
- protected_resources?: string[]
13
- }
14
-
15
- /**
16
- * @see {@link https://datatracker.ietf.org/doc/html/rfc8414#section-2}
17
- * @see {@link https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata}
18
- * @see {@link https://openid.net/specs/openid-connect-prompt-create-1_0.html}
19
- */
20
- export function buildMetadata(
21
- issuer: OAuthIssuerIdentifier,
22
- keyset: Keyset,
23
- customMetadata?: CustomMetadata,
24
- ): OAuthAuthorizationServerMetadata {
25
- return oauthAuthorizationServerMetadataValidator.parse({
26
- issuer,
27
-
28
- scopes_supported: [
29
- 'atproto',
30
-
31
- // These serve as hint that this server supports the transitional scopes.
32
- // This is not a specced behavior.
33
- 'transition:email',
34
- 'transition:generic',
35
- 'transition:chat.bsky',
36
-
37
- // Other atproto scopes can't be enumerated as they are dynamic.
38
- ],
39
- subject_types_supported: [
40
- //
41
- 'public', // The same "sub" is returned for all clients
42
- // 'pairwise', // A different "sub" is returned for each client
43
- ],
44
- response_types_supported: [
45
- // OAuth
46
- 'code',
47
- // 'token',
48
-
49
- // OpenID
50
- // 'none',
51
- // 'code id_token token',
52
- // 'code id_token',
53
- // 'code token',
54
- // 'id_token token',
55
- // 'id_token',
56
- ],
57
- response_modes_supported: [
58
- // https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#ResponseModes
59
- 'query',
60
- 'fragment',
61
- // https://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html#FormPostResponseMode
62
- 'form_post',
63
- ],
64
- grant_types_supported: [
65
- //
66
- 'authorization_code',
67
- 'refresh_token',
68
- ],
69
- code_challenge_methods_supported: [
70
- // https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#pkce-code-challenge-method
71
- 'S256',
72
-
73
- // atproto does not allow "plain"
74
- // 'plain',
75
- ],
76
- ui_locales_supported: [
77
- //
78
- 'en-US',
79
- ],
80
- display_values_supported: [
81
- //
82
- 'page',
83
- 'popup',
84
- 'touch',
85
- // 'wap', LoL
86
- ],
87
-
88
- // https://openid.net/specs/openid-connect-prompt-create-1_0.html
89
- prompt_values_supported: [
90
- 'none',
91
- 'login',
92
- 'consent',
93
- 'select_account',
94
- 'create',
95
- ],
96
-
97
- // https://datatracker.ietf.org/doc/html/rfc9207
98
- authorization_response_iss_parameter_supported: true,
99
-
100
- // https://datatracker.ietf.org/doc/html/rfc9101#section-4
101
- request_object_signing_alg_values_supported: [...VERIFY_ALGOS, 'none'],
102
- request_object_encryption_alg_values_supported: [], // None
103
- request_object_encryption_enc_values_supported: [], // None
104
-
105
- request_parameter_supported: true,
106
- request_uri_parameter_supported: true,
107
- require_request_uri_registration: true,
108
-
109
- jwks_uri: new URL('/oauth/jwks', issuer).href,
110
-
111
- authorization_endpoint: new URL('/oauth/authorize', issuer).href,
112
-
113
- token_endpoint: new URL('/oauth/token', issuer).href,
114
- token_endpoint_auth_methods_supported: [...Client.AUTH_METHODS_SUPPORTED],
115
- token_endpoint_auth_signing_alg_values_supported: [...VERIFY_ALGOS],
116
-
117
- revocation_endpoint: new URL('/oauth/revoke', issuer).href,
118
-
119
- // @TODO Should we implement these endpoints?
120
- // introspection_endpoint: new URL('/oauth/introspect', issuer).href,
121
- // end_session_endpoint: new URL('/oauth/logout', issuer).href,
122
-
123
- // https://datatracker.ietf.org/doc/html/rfc9126#section-5
124
- pushed_authorization_request_endpoint: new URL('/oauth/par', issuer).href,
125
-
126
- require_pushed_authorization_requests: true,
127
-
128
- // https://datatracker.ietf.org/doc/html/rfc9449#section-5.1
129
- dpop_signing_alg_values_supported: [...VERIFY_ALGOS],
130
-
131
- // https://datatracker.ietf.org/doc/html/rfc9396#section-14.4
132
- authorization_details_types_supported:
133
- customMetadata?.authorization_details_types_supported,
134
-
135
- // https://www.rfc-editor.org/rfc/rfc9728.html#section-4
136
- protected_resources: customMetadata?.protected_resources,
137
-
138
- // https://www.ietf.org/archive/id/draft-ietf-oauth-client-id-metadata-document-00.html
139
- client_id_metadata_document_supported: true,
140
- })
141
- }
@@ -1,3 +0,0 @@
1
- export * from '@atproto/oauth-types'
2
- export type * from './client/client.js'
3
- export * from './client/client-utils.js'
package/src/oauth-dpop.ts DELETED
@@ -1,2 +0,0 @@
1
- export * from './dpop/dpop-nonce.js'
2
- export * from './dpop/dpop-manager.js'
@@ -1,26 +0,0 @@
1
- // Root Error class
2
- export { OAuthError } from './errors/oauth-error.js'
3
-
4
- export * from './errors/access-denied-error.js'
5
- export * from './errors/account-selection-required-error.js'
6
- export * from './errors/authorization-error.js'
7
- export * from './errors/consent-required-error.js'
8
- export * from './errors/handle-unavailable-error.js'
9
- export * from './errors/invalid-authorization-details-error.js'
10
- export * from './errors/invalid-client-error.js'
11
- export * from './errors/invalid-client-id-error.js'
12
- export * from './errors/invalid-client-metadata-error.js'
13
- export * from './errors/invalid-credentials-error.js'
14
- export * from './errors/invalid-dpop-key-binding-error.js'
15
- export * from './errors/invalid-dpop-proof-error.js'
16
- export * from './errors/invalid-grant-error.js'
17
- export * from './errors/invalid-invite-code-error.js'
18
- export * from './errors/invalid-redirect-uri-error.js'
19
- export * from './errors/invalid-request-error.js'
20
- export * from './errors/invalid-scope-error.js'
21
- export * from './errors/invalid-token-error.js'
22
- export * from './errors/login-required-error.js'
23
- export * from './errors/second-authentication-factor-required-error.js'
24
- export * from './errors/unauthorized-client-error.js'
25
- export * from './errors/use-dpop-nonce-error.js'
26
- export * from './errors/www-authenticate-error.js'