@atproto/oauth-types 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (146) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/LICENSE.txt +7 -0
  3. package/README.md +3 -0
  4. package/dist/access-token.d.ts +4 -0
  5. package/dist/access-token.d.ts.map +1 -0
  6. package/dist/access-token.js +6 -0
  7. package/dist/access-token.js.map +1 -0
  8. package/dist/atproto-loopback-client-metadata.d.ts +3 -0
  9. package/dist/atproto-loopback-client-metadata.d.ts.map +1 -0
  10. package/dist/atproto-loopback-client-metadata.js +26 -0
  11. package/dist/atproto-loopback-client-metadata.js.map +1 -0
  12. package/dist/constants.d.ts +3 -0
  13. package/dist/constants.d.ts.map +1 -0
  14. package/dist/constants.js +11 -0
  15. package/dist/constants.js.map +1 -0
  16. package/dist/index.d.ts +27 -0
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/index.js +43 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/oauth-authentication-request-parameters.d.ts +128 -0
  21. package/dist/oauth-authentication-request-parameters.d.ts.map +1 -0
  22. package/dist/oauth-authentication-request-parameters.js +76 -0
  23. package/dist/oauth-authentication-request-parameters.js.map +1 -0
  24. package/dist/oauth-authorization-details.d.ts +54 -0
  25. package/dist/oauth-authorization-details.d.ts.map +1 -0
  26. package/dist/oauth-authorization-details.js +20 -0
  27. package/dist/oauth-authorization-details.js.map +1 -0
  28. package/dist/oauth-authorization-server-metadata.d.ts +428 -0
  29. package/dist/oauth-authorization-server-metadata.d.ts.map +1 -0
  30. package/dist/oauth-authorization-server-metadata.js +88 -0
  31. package/dist/oauth-authorization-server-metadata.js.map +1 -0
  32. package/dist/oauth-client-credentials.d.ts +66 -0
  33. package/dist/oauth-client-credentials.d.ts.map +1 -0
  34. package/dist/oauth-client-credentials.js +30 -0
  35. package/dist/oauth-client-credentials.js.map +1 -0
  36. package/dist/oauth-client-id-discoverable.d.ts +8 -0
  37. package/dist/oauth-client-id-discoverable.d.ts.map +1 -0
  38. package/dist/oauth-client-id-discoverable.js +48 -0
  39. package/dist/oauth-client-id-discoverable.js.map +1 -0
  40. package/dist/oauth-client-id-loopback.d.ts +5 -0
  41. package/dist/oauth-client-id-loopback.d.ts.map +1 -0
  42. package/dist/oauth-client-id-loopback.js +44 -0
  43. package/dist/oauth-client-id-loopback.js.map +1 -0
  44. package/dist/oauth-client-id-url.d.ts +3 -0
  45. package/dist/oauth-client-id-url.d.ts.map +1 -0
  46. package/dist/oauth-client-id-url.js +21 -0
  47. package/dist/oauth-client-id-url.js.map +1 -0
  48. package/dist/oauth-client-id.d.ts +4 -0
  49. package/dist/oauth-client-id.d.ts.map +1 -0
  50. package/dist/oauth-client-id.js +6 -0
  51. package/dist/oauth-client-id.js.map +1 -0
  52. package/dist/oauth-client-identification.d.ts +31 -0
  53. package/dist/oauth-client-identification.d.ts.map +1 -0
  54. package/dist/oauth-client-identification.js +12 -0
  55. package/dist/oauth-client-identification.js.map +1 -0
  56. package/dist/oauth-client-metadata.d.ts +1576 -0
  57. package/dist/oauth-client-metadata.d.ts.map +1 -0
  58. package/dist/oauth-client-metadata.js +70 -0
  59. package/dist/oauth-client-metadata.js.map +1 -0
  60. package/dist/oauth-endpoint-auth-method.d.ts +4 -0
  61. package/dist/oauth-endpoint-auth-method.d.ts.map +1 -0
  62. package/dist/oauth-endpoint-auth-method.js +14 -0
  63. package/dist/oauth-endpoint-auth-method.js.map +1 -0
  64. package/dist/oauth-endpoint-name.d.ts +2 -0
  65. package/dist/oauth-endpoint-name.d.ts.map +1 -0
  66. package/dist/oauth-endpoint-name.js +3 -0
  67. package/dist/oauth-endpoint-name.js.map +1 -0
  68. package/dist/oauth-grant-type.d.ts +4 -0
  69. package/dist/oauth-grant-type.d.ts.map +1 -0
  70. package/dist/oauth-grant-type.js +14 -0
  71. package/dist/oauth-grant-type.js.map +1 -0
  72. package/dist/oauth-issuer-identifier.d.ts +3 -0
  73. package/dist/oauth-issuer-identifier.d.ts.map +1 -0
  74. package/dist/oauth-issuer-identifier.js +59 -0
  75. package/dist/oauth-issuer-identifier.js.map +1 -0
  76. package/dist/oauth-par-response.d.ts +10 -0
  77. package/dist/oauth-par-response.d.ts.map +1 -0
  78. package/dist/oauth-par-response.js +8 -0
  79. package/dist/oauth-par-response.js.map +1 -0
  80. package/dist/oauth-protected-resource-metadata.d.ts +90 -0
  81. package/dist/oauth-protected-resource-metadata.d.ts.map +1 -0
  82. package/dist/oauth-protected-resource-metadata.js +75 -0
  83. package/dist/oauth-protected-resource-metadata.js.map +1 -0
  84. package/dist/oauth-response-mode.d.ts +4 -0
  85. package/dist/oauth-response-mode.d.ts.map +1 -0
  86. package/dist/oauth-response-mode.js +10 -0
  87. package/dist/oauth-response-mode.js.map +1 -0
  88. package/dist/oauth-response-type.d.ts +4 -0
  89. package/dist/oauth-response-type.d.ts.map +1 -0
  90. package/dist/oauth-response-type.js +17 -0
  91. package/dist/oauth-response-type.js.map +1 -0
  92. package/dist/oauth-token-response.d.ts +103 -0
  93. package/dist/oauth-token-response.d.ts.map +1 -0
  94. package/dist/oauth-token-response.js +26 -0
  95. package/dist/oauth-token-response.js.map +1 -0
  96. package/dist/oauth-token-type.d.ts +4 -0
  97. package/dist/oauth-token-type.d.ts.map +1 -0
  98. package/dist/oauth-token-type.js +16 -0
  99. package/dist/oauth-token-type.js.map +1 -0
  100. package/dist/oidc-claims-parameter.d.ts +4 -0
  101. package/dist/oidc-claims-parameter.d.ts.map +1 -0
  102. package/dist/oidc-claims-parameter.js +36 -0
  103. package/dist/oidc-claims-parameter.js.map +1 -0
  104. package/dist/oidc-claims-properties.d.ts +16 -0
  105. package/dist/oidc-claims-properties.d.ts.map +1 -0
  106. package/dist/oidc-claims-properties.js +11 -0
  107. package/dist/oidc-claims-properties.js.map +1 -0
  108. package/dist/oidc-entity-type.d.ts +4 -0
  109. package/dist/oidc-entity-type.d.ts.map +1 -0
  110. package/dist/oidc-entity-type.js +6 -0
  111. package/dist/oidc-entity-type.js.map +1 -0
  112. package/dist/util.d.ts +5 -0
  113. package/dist/util.d.ts.map +1 -0
  114. package/dist/util.js +23 -0
  115. package/dist/util.js.map +1 -0
  116. package/package.json +37 -0
  117. package/src/access-token.ts +4 -0
  118. package/src/atproto-loopback-client-metadata.ts +30 -0
  119. package/src/constants.ts +9 -0
  120. package/src/index.ts +27 -0
  121. package/src/oauth-authentication-request-parameters.ts +104 -0
  122. package/src/oauth-authorization-details.ts +28 -0
  123. package/src/oauth-authorization-server-metadata.ts +106 -0
  124. package/src/oauth-client-credentials.ts +34 -0
  125. package/src/oauth-client-id-discoverable.ts +66 -0
  126. package/src/oauth-client-id-loopback.ts +58 -0
  127. package/src/oauth-client-id-url.ts +25 -0
  128. package/src/oauth-client-id.ts +4 -0
  129. package/src/oauth-client-identification.ts +14 -0
  130. package/src/oauth-client-metadata.ts +75 -0
  131. package/src/oauth-endpoint-auth-method.ts +13 -0
  132. package/src/oauth-endpoint-name.ts +5 -0
  133. package/src/oauth-grant-type.ts +13 -0
  134. package/src/oauth-issuer-identifier.ts +61 -0
  135. package/src/oauth-par-response.ts +7 -0
  136. package/src/oauth-protected-resource-metadata.ts +85 -0
  137. package/src/oauth-response-mode.ts +9 -0
  138. package/src/oauth-response-type.ts +17 -0
  139. package/src/oauth-token-response.ts +29 -0
  140. package/src/oauth-token-type.ts +15 -0
  141. package/src/oidc-claims-parameter.ts +40 -0
  142. package/src/oidc-claims-properties.ts +11 -0
  143. package/src/oidc-entity-type.ts +5 -0
  144. package/src/util.ts +20 -0
  145. package/tsconfig.build.json +8 -0
  146. package/tsconfig.json +4 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-token-response.js","sourceRoot":"","sources":["../src/oauth-token-response.ts"],"names":[],"mappings":";;;AAAA,sCAA8C;AAC9C,6BAAuB;AAEvB,qFAAkF;AAClF,+DAA4D;AAE5D;;GAEG;AACU,QAAA,wBAAwB,GAAG,OAAC;KACtC,MAAM,CAAC;IACN,YAAY,EAAE,OAAC,CAAC,MAAM,EAAE;IACxB,UAAU,EAAE,0CAAoB;IAChC,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACnC,GAAG,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC1B,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,QAAQ,EAAE,qBAAe,CAAC,QAAQ,EAAE;IACpC,aAAa,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,qBAAqB,EAAE,gEAA+B,CAAC,QAAQ,EAAE;CAClE,CAAC;IACF,0DAA0D;IAC1D,qEAAqE;KACpE,WAAW,EAAE,CAAA"}
@@ -0,0 +1,4 @@
1
+ import { z } from 'zod';
2
+ export declare const oauthTokenTypeSchema: z.ZodUnion<[z.ZodEffects<z.ZodString, "DPoP", string>, z.ZodEffects<z.ZodString, "Bearer", string>]>;
3
+ export type OAuthTokenType = z.infer<typeof oauthTokenTypeSchema>;
4
+ //# sourceMappingURL=oauth-token-type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-token-type.d.ts","sourceRoot":"","sources":["../src/oauth-token-type.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,eAAO,MAAM,oBAAoB,sGAS/B,CAAA;AAEF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.oauthTokenTypeSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ // Case insensitive input, normalized output
6
+ exports.oauthTokenTypeSchema = zod_1.z.union([
7
+ zod_1.z
8
+ .string()
9
+ .regex(/^DPoP$/i)
10
+ .transform(() => 'DPoP'),
11
+ zod_1.z
12
+ .string()
13
+ .regex(/^Bearer$/i)
14
+ .transform(() => 'Bearer'),
15
+ ]);
16
+ //# sourceMappingURL=oauth-token-type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-token-type.js","sourceRoot":"","sources":["../src/oauth-token-type.ts"],"names":[],"mappings":";;;AAAA,6BAAuB;AAEvB,4CAA4C;AAC/B,QAAA,oBAAoB,GAAG,OAAC,CAAC,KAAK,CAAC;IAC1C,OAAC;SACE,MAAM,EAAE;SACR,KAAK,CAAC,SAAS,CAAC;SAChB,SAAS,CAAC,GAAG,EAAE,CAAC,MAAe,CAAC;IACnC,OAAC;SACE,MAAM,EAAE;SACR,KAAK,CAAC,WAAW,CAAC;SAClB,SAAS,CAAC,GAAG,EAAE,CAAC,QAAiB,CAAC;CACtC,CAAC,CAAA"}
@@ -0,0 +1,4 @@
1
+ import { z } from 'zod';
2
+ export declare const oidcClaimsParameterSchema: z.ZodEnum<["auth_time", "nonce", "acr", "name", "family_name", "given_name", "middle_name", "nickname", "preferred_username", "gender", "picture", "profile", "website", "birthdate", "zoneinfo", "locale", "updated_at", "email", "email_verified", "phone_number", "phone_number_verified", "address"]>;
3
+ export type OidcClaimsParameter = z.infer<typeof oidcClaimsParameterSchema>;
4
+ //# sourceMappingURL=oidc-claims-parameter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oidc-claims-parameter.d.ts","sourceRoot":"","sources":["../src/oidc-claims-parameter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,yBAAyB,2SAmCpC,CAAA;AAEF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAA"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.oidcClaimsParameterSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.oidcClaimsParameterSchema = zod_1.z.enum([
6
+ // https://openid.net/specs/openid-provider-authentication-policy-extension-1_0.html#rfc.section.5.2
7
+ // if client metadata "require_auth_time" is true, this *must* be provided
8
+ 'auth_time',
9
+ // OIDC
10
+ 'nonce',
11
+ 'acr',
12
+ // OpenID: "profile" scope
13
+ 'name',
14
+ 'family_name',
15
+ 'given_name',
16
+ 'middle_name',
17
+ 'nickname',
18
+ 'preferred_username',
19
+ 'gender',
20
+ 'picture',
21
+ 'profile',
22
+ 'website',
23
+ 'birthdate',
24
+ 'zoneinfo',
25
+ 'locale',
26
+ 'updated_at',
27
+ // OpenID: "email" scope
28
+ 'email',
29
+ 'email_verified',
30
+ // OpenID: "phone" scope
31
+ 'phone_number',
32
+ 'phone_number_verified',
33
+ // OpenID: "address" scope
34
+ 'address',
35
+ ]);
36
+ //# sourceMappingURL=oidc-claims-parameter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oidc-claims-parameter.js","sourceRoot":"","sources":["../src/oidc-claims-parameter.ts"],"names":[],"mappings":";;;AAAA,6BAAuB;AAEV,QAAA,yBAAyB,GAAG,OAAC,CAAC,IAAI,CAAC;IAC9C,oGAAoG;IACpG,0EAA0E;IAC1E,WAAW;IAEX,OAAO;IACP,OAAO;IACP,KAAK;IAEL,0BAA0B;IAC1B,MAAM;IACN,aAAa;IACb,YAAY;IACZ,aAAa;IACb,UAAU;IACV,oBAAoB;IACpB,QAAQ;IACR,SAAS;IACT,SAAS;IACT,SAAS;IACT,WAAW;IACX,UAAU;IACV,QAAQ;IACR,YAAY;IAEZ,wBAAwB;IACxB,OAAO;IACP,gBAAgB;IAEhB,wBAAwB;IACxB,cAAc;IACd,uBAAuB;IAEvB,0BAA0B;IAC1B,SAAS;CACV,CAAC,CAAA"}
@@ -0,0 +1,16 @@
1
+ import { z } from 'zod';
2
+ export declare const oidcClaimsPropertiesSchema: z.ZodObject<{
3
+ essential: z.ZodOptional<z.ZodBoolean>;
4
+ value: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
5
+ values: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>, "many">>;
6
+ }, "strip", z.ZodTypeAny, {
7
+ values?: (string | number | boolean)[] | undefined;
8
+ value?: string | number | boolean | undefined;
9
+ essential?: boolean | undefined;
10
+ }, {
11
+ values?: (string | number | boolean)[] | undefined;
12
+ value?: string | number | boolean | undefined;
13
+ essential?: boolean | undefined;
14
+ }>;
15
+ export type OidcClaimsProperties = z.infer<typeof oidcClaimsPropertiesSchema>;
16
+ //# sourceMappingURL=oidc-claims-properties.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oidc-claims-properties.d.ts","sourceRoot":"","sources":["../src/oidc-claims-properties.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,eAAO,MAAM,0BAA0B;;;;;;;;;;;;EAIrC,CAAA;AAEF,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAA"}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.oidcClaimsPropertiesSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const oidcClaimsValueSchema = zod_1.z.union([zod_1.z.string(), zod_1.z.number(), zod_1.z.boolean()]);
6
+ exports.oidcClaimsPropertiesSchema = zod_1.z.object({
7
+ essential: zod_1.z.boolean().optional(),
8
+ value: oidcClaimsValueSchema.optional(),
9
+ values: zod_1.z.array(oidcClaimsValueSchema).optional(),
10
+ });
11
+ //# sourceMappingURL=oidc-claims-properties.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oidc-claims-properties.js","sourceRoot":"","sources":["../src/oidc-claims-properties.ts"],"names":[],"mappings":";;;AAAA,6BAAuB;AAEvB,MAAM,qBAAqB,GAAG,OAAC,CAAC,KAAK,CAAC,CAAC,OAAC,CAAC,MAAM,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;AAE/D,QAAA,0BAA0B,GAAG,OAAC,CAAC,MAAM,CAAC;IACjD,SAAS,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACjC,KAAK,EAAE,qBAAqB,CAAC,QAAQ,EAAE;IACvC,MAAM,EAAE,OAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,QAAQ,EAAE;CAClD,CAAC,CAAA"}
@@ -0,0 +1,4 @@
1
+ import { z } from 'zod';
2
+ export declare const oidcEntityTypeSchema: z.ZodEnum<["userinfo", "id_token"]>;
3
+ export type OidcEntityType = z.infer<typeof oidcEntityTypeSchema>;
4
+ //# sourceMappingURL=oidc-entity-type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oidc-entity-type.d.ts","sourceRoot":"","sources":["../src/oidc-entity-type.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,oBAAoB,qCAAmC,CAAA;AAEpE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.oidcEntityTypeSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.oidcEntityTypeSchema = zod_1.z.enum(['userinfo', 'id_token']);
6
+ //# sourceMappingURL=oidc-entity-type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oidc-entity-type.js","sourceRoot":"","sources":["../src/oidc-entity-type.ts"],"names":[],"mappings":";;;AAAA,6BAAuB;AAEV,QAAA,oBAAoB,GAAG,OAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAA"}
package/dist/util.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export declare function isIP(hostname: string): boolean;
2
+ export type LoopbackHost = 'localhost' | '127.0.0.1' | '[::1]';
3
+ export declare function isLoopbackHost(host: unknown): host is LoopbackHost;
4
+ export declare function isLoopbackUrl(input: URL | string): boolean;
5
+ //# sourceMappingURL=util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,wBAAgB,IAAI,CAAC,QAAQ,EAAE,MAAM,WAQpC;AAED,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,WAAW,GAAG,OAAO,CAAA;AAE9D,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,YAAY,CAElE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,GAAG,GAAG,MAAM,GAAG,OAAO,CAG1D"}
package/dist/util.js ADDED
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isLoopbackUrl = exports.isLoopbackHost = exports.isIP = void 0;
4
+ function isIP(hostname) {
5
+ // IPv4
6
+ if (hostname.match(/^\d+\.\d+\.\d+\.\d+$/))
7
+ return true;
8
+ // IPv6
9
+ if (hostname.startsWith('[') && hostname.endsWith(']'))
10
+ return true;
11
+ return false;
12
+ }
13
+ exports.isIP = isIP;
14
+ function isLoopbackHost(host) {
15
+ return host === 'localhost' || host === '127.0.0.1' || host === '[::1]';
16
+ }
17
+ exports.isLoopbackHost = isLoopbackHost;
18
+ function isLoopbackUrl(input) {
19
+ const url = typeof input === 'string' ? new URL(input) : input;
20
+ return isLoopbackHost(url.hostname);
21
+ }
22
+ exports.isLoopbackUrl = isLoopbackUrl;
23
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";;;AAAA,SAAgB,IAAI,CAAC,QAAgB;IACnC,OAAO;IACP,IAAI,QAAQ,CAAC,KAAK,CAAC,sBAAsB,CAAC;QAAE,OAAO,IAAI,CAAA;IAEvD,OAAO;IACP,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IAEnE,OAAO,KAAK,CAAA;AACd,CAAC;AARD,oBAQC;AAID,SAAgB,cAAc,CAAC,IAAa;IAC1C,OAAO,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,OAAO,CAAA;AACzE,CAAC;AAFD,wCAEC;AAED,SAAgB,aAAa,CAAC,KAAmB;IAC/C,MAAM,GAAG,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;IAC9D,OAAO,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;AACrC,CAAC;AAHD,sCAGC"}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@atproto/oauth-types",
3
+ "version": "0.1.0",
4
+ "license": "MIT",
5
+ "description": "OAuth typing & validation library",
6
+ "keywords": [
7
+ "atproto",
8
+ "oauth",
9
+ "types",
10
+ "isomorphic"
11
+ ],
12
+ "homepage": "https://atproto.com",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/bluesky-social/atproto",
16
+ "directory": "packages/oauth/oauth-types"
17
+ },
18
+ "type": "commonjs",
19
+ "main": "dist/index.js",
20
+ "types": "dist/index.d.ts",
21
+ "exports": {
22
+ ".": {
23
+ "types": "./dist/index.d.ts",
24
+ "default": "./dist/index.js"
25
+ }
26
+ },
27
+ "dependencies": {
28
+ "zod": "^3.23.8",
29
+ "@atproto/jwk": "0.1.0"
30
+ },
31
+ "devDependencies": {
32
+ "typescript": "^5.3.3"
33
+ },
34
+ "scripts": {
35
+ "build": "tsc --build tsconfig.build.json"
36
+ }
37
+ }
@@ -0,0 +1,4 @@
1
+ import { z } from 'zod'
2
+
3
+ export const accessTokenSchema = z.string().min(1)
4
+ export type AccessToken = z.infer<typeof accessTokenSchema>
@@ -0,0 +1,30 @@
1
+ import { isOAuthClientIdLoopback } from './oauth-client-id-loopback.js'
2
+ import { OAuthClientMetadataInput } from './oauth-client-metadata.js'
3
+ import { parseOAuthClientIdUrl } from './oauth-client-id-url.js'
4
+
5
+ export function atprotoLoopbackClientMetadata(
6
+ clientId: string,
7
+ ): OAuthClientMetadataInput {
8
+ if (!isOAuthClientIdLoopback(clientId)) {
9
+ throw new TypeError(`Invalid loopback client ID ${clientId}`)
10
+ }
11
+
12
+ const { origin, pathname, searchParams } = parseOAuthClientIdUrl(clientId)
13
+
14
+ return {
15
+ client_id: clientId,
16
+ client_name: 'Loopback client',
17
+ response_types: ['code id_token', 'code'],
18
+ grant_types: ['authorization_code', 'implicit', 'refresh_token'],
19
+ scope: 'openid profile offline_access',
20
+ redirect_uris: searchParams.has('redirect_uri')
21
+ ? (searchParams.getAll('redirect_uri') as [string, ...string[]])
22
+ : (['127.0.0.1', '[::1]'].map(
23
+ (ip) =>
24
+ Object.assign(new URL(pathname, origin), { hostname: ip }).href,
25
+ ) as [string, ...string[]]),
26
+ token_endpoint_auth_method: 'none',
27
+ application_type: 'native',
28
+ dpop_bound_access_tokens: true,
29
+ }
30
+ }
@@ -0,0 +1,9 @@
1
+ export const CLIENT_ASSERTION_TYPE_JWT_BEARER =
2
+ 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer'
3
+
4
+ export const OAUTH_AUTHENTICATED_ENDPOINT_NAMES = [
5
+ 'token',
6
+ 'revocation',
7
+ 'introspection',
8
+ 'pushed_authorization_request',
9
+ ] as const
package/src/index.ts ADDED
@@ -0,0 +1,27 @@
1
+ export * from './constants.js'
2
+ export * from './util.js'
3
+
4
+ export * from './access-token.js'
5
+ export * from './atproto-loopback-client-metadata.js'
6
+ export * from './oauth-client-id-discoverable.js'
7
+ export * from './oauth-client-id-loopback.js'
8
+ export * from './oauth-authentication-request-parameters.js'
9
+ export * from './oauth-authorization-details.js'
10
+ export * from './oauth-authorization-server-metadata.js'
11
+ export * from './oauth-client-credentials.js'
12
+ export * from './oauth-client-id.js'
13
+ export * from './oauth-client-identification.js'
14
+ export * from './oauth-client-metadata.js'
15
+ export * from './oauth-endpoint-auth-method.js'
16
+ export * from './oauth-endpoint-name.js'
17
+ export * from './oauth-grant-type.js'
18
+ export * from './oauth-issuer-identifier.js'
19
+ export * from './oauth-par-response.js'
20
+ export * from './oauth-protected-resource-metadata.js'
21
+ export * from './oauth-response-mode.js'
22
+ export * from './oauth-response-type.js'
23
+ export * from './oauth-token-response.js'
24
+ export * from './oauth-token-type.js'
25
+ export * from './oidc-claims-parameter.js'
26
+ export * from './oidc-claims-properties.js'
27
+ export * from './oidc-entity-type.js'
@@ -0,0 +1,104 @@
1
+ import { signedJwtSchema } from '@atproto/jwk'
2
+ import { z } from 'zod'
3
+
4
+ import { oauthAuthorizationDetailsSchema } from './oauth-authorization-details.js'
5
+ import { oauthClientIdSchema } from './oauth-client-id.js'
6
+ import { oidcClaimsParameterSchema } from './oidc-claims-parameter.js'
7
+ import { oidcClaimsPropertiesSchema } from './oidc-claims-properties.js'
8
+ import { oidcEntityTypeSchema } from './oidc-entity-type.js'
9
+
10
+ /**
11
+ * @see {@link https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest | OIDC}
12
+ */
13
+ export const oauthAuthenticationRequestParametersSchema = z.object({
14
+ client_id: oauthClientIdSchema,
15
+
16
+ state: z.string().optional(),
17
+ nonce: z.string().optional(),
18
+ dpop_jkt: z.string().optional(),
19
+
20
+ response_type: z.enum([
21
+ // OAuth2 (https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-10#section-4.1.1)
22
+ 'code',
23
+ 'token',
24
+
25
+ // OIDC (https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html)
26
+ 'id_token',
27
+ 'none',
28
+ 'code token',
29
+ 'code id_token',
30
+ 'id_token token',
31
+ 'code id_token token',
32
+ ]),
33
+
34
+ // Default depend on response_type
35
+ response_mode: z.enum(['query', 'fragment', 'form_post']).optional(),
36
+
37
+ // PKCE
38
+ code_challenge: z.string().optional(),
39
+ code_challenge_method: z.enum(['S256', 'plain']).default('S256').optional(),
40
+
41
+ redirect_uri: z.string().url().optional(),
42
+
43
+ // email profile openid (other?)
44
+ scope: z
45
+ .string()
46
+ .regex(/^[a-zA-Z0-9_]+( [a-zA-Z0-9_]+)*$/)
47
+ .optional(),
48
+
49
+ // OIDC
50
+
51
+ // Specifies the allowable elapsed time in seconds since the last time the
52
+ // End-User was actively authenticated by the OP. If the elapsed time is
53
+ // greater than this value, the OP MUST attempt to actively re-authenticate
54
+ // the End-User. (The max_age request parameter corresponds to the OpenID 2.0
55
+ // PAPE [OpenID.PAPE] max_auth_age request parameter.) When max_age is used,
56
+ // the ID Token returned MUST include an auth_time Claim Value. Note that
57
+ // max_age=0 is equivalent to prompt=login.
58
+ max_age: z.number().int().min(0).optional(),
59
+
60
+ claims: z
61
+ .record(
62
+ oidcEntityTypeSchema,
63
+ z.record(
64
+ oidcClaimsParameterSchema,
65
+ z.union([z.literal(null), oidcClaimsPropertiesSchema]),
66
+ ),
67
+ )
68
+ .optional(),
69
+
70
+ // https://openid.net/specs/openid-connect-core-1_0.html#RegistrationParameter
71
+ // Not supported by this library (yet?)
72
+ // registration: clientMetadataSchema.optional(),
73
+
74
+ login_hint: z.string().min(1).optional(),
75
+
76
+ ui_locales: z
77
+ .string()
78
+ .regex(/^[a-z]{2}(-[A-Z]{2})?( [a-z]{2}(-[A-Z]{2})?)*$/) // fr-CA fr en
79
+ .optional(),
80
+
81
+ // Previous ID Token, should be provided when prompt=none is used
82
+ id_token_hint: signedJwtSchema.optional(),
83
+
84
+ // Type of UI the AS is displayed on
85
+ display: z.enum(['page', 'popup', 'touch']).optional(),
86
+
87
+ /**
88
+ * - "none" will only be allowed if the user already allowed the client on the same device
89
+ * - "login" will force the user to login again, unless he very recently logged in
90
+ * - "consent" will force the user to consent again
91
+ * - "select_account" will force the user to select an account
92
+ */
93
+ prompt: z.enum(['none', 'login', 'consent', 'select_account']).optional(),
94
+
95
+ // https://datatracker.ietf.org/doc/html/rfc9396
96
+ authorization_details: oauthAuthorizationDetailsSchema.optional(),
97
+ })
98
+
99
+ /**
100
+ * @see {oauthAuthenticationRequestParametersSchema}
101
+ */
102
+ export type OAuthAuthenticationRequestParameters = z.infer<
103
+ typeof oauthAuthenticationRequestParametersSchema
104
+ >
@@ -0,0 +1,28 @@
1
+ import { z } from 'zod'
2
+
3
+ /**
4
+ * @see {@link https://datatracker.ietf.org/doc/html/rfc9396#section-2 | RFC 9396, Section 2}
5
+ */
6
+ export const oauthAuthorizationDetailSchema = z.object({
7
+ type: z.string(),
8
+ locations: z.array(z.string().url()).optional(),
9
+ actions: z.array(z.string()).optional(),
10
+ datatypes: z.array(z.string()).optional(),
11
+ identifier: z.string().optional(),
12
+ privileges: z.array(z.string()).optional(),
13
+ })
14
+
15
+ export type OAuthAuthorizationDetail = z.infer<
16
+ typeof oauthAuthorizationDetailSchema
17
+ >
18
+
19
+ /**
20
+ * @see {@link https://datatracker.ietf.org/doc/html/rfc9396#section-2 | RFC 9396, Section 2}
21
+ */
22
+ export const oauthAuthorizationDetailsSchema = z.array(
23
+ oauthAuthorizationDetailSchema,
24
+ )
25
+
26
+ export type OAuthAuthorizationDetails = z.infer<
27
+ typeof oauthAuthorizationDetailsSchema
28
+ >
@@ -0,0 +1,106 @@
1
+ import { z } from 'zod'
2
+
3
+ import { oauthIssuerIdentifierSchema } from './oauth-issuer-identifier.js'
4
+
5
+ /**
6
+ * @see {@link https://datatracker.ietf.org/doc/html/rfc8414}
7
+ */
8
+ export const oauthAuthorizationServerMetadataSchema = z.object({
9
+ issuer: oauthIssuerIdentifierSchema,
10
+
11
+ claims_supported: z.array(z.string()).optional(),
12
+ claims_locales_supported: z.array(z.string()).optional(),
13
+ claims_parameter_supported: z.boolean().optional(),
14
+ request_parameter_supported: z.boolean().optional(),
15
+ request_uri_parameter_supported: z.boolean().optional(),
16
+ require_request_uri_registration: z.boolean().optional(),
17
+ scopes_supported: z.array(z.string()).optional(),
18
+ subject_types_supported: z.array(z.string()).optional(),
19
+ response_types_supported: z.array(z.string()).optional(),
20
+ response_modes_supported: z.array(z.string()).optional(),
21
+ grant_types_supported: z.array(z.string()).optional(),
22
+ code_challenge_methods_supported: z.array(z.string()).min(1).optional(),
23
+ ui_locales_supported: z.array(z.string()).optional(),
24
+ id_token_signing_alg_values_supported: z.array(z.string()).optional(),
25
+ display_values_supported: z.array(z.string()).optional(),
26
+ request_object_signing_alg_values_supported: z.array(z.string()).optional(),
27
+ authorization_response_iss_parameter_supported: z.boolean().optional(),
28
+ authorization_details_types_supported: z.array(z.string()).optional(),
29
+ request_object_encryption_alg_values_supported: z
30
+ .array(z.string())
31
+ .optional(),
32
+ request_object_encryption_enc_values_supported: z
33
+ .array(z.string())
34
+ .optional(),
35
+
36
+ jwks_uri: z.string().url().optional(),
37
+
38
+ authorization_endpoint: z.string().url(), // .optional(),
39
+
40
+ token_endpoint: z.string().url(), // .optional(),
41
+ token_endpoint_auth_methods_supported: z.array(z.string()).optional(),
42
+ token_endpoint_auth_signing_alg_values_supported: z
43
+ .array(z.string())
44
+ .optional(),
45
+
46
+ revocation_endpoint: z.string().url().optional(),
47
+ revocation_endpoint_auth_methods_supported: z.array(z.string()).optional(),
48
+ revocation_endpoint_auth_signing_alg_values_supported: z
49
+ .array(z.string())
50
+ .optional(),
51
+
52
+ introspection_endpoint: z.string().url().optional(),
53
+ introspection_endpoint_auth_methods_supported: z.array(z.string()).optional(),
54
+ introspection_endpoint_auth_signing_alg_values_supported: z
55
+ .array(z.string())
56
+ .optional(),
57
+
58
+ pushed_authorization_request_endpoint: z.string().url().optional(),
59
+ pushed_authorization_request_endpoint_auth_methods_supported: z
60
+ .array(z.string())
61
+ .optional(),
62
+ pushed_authorization_request_endpoint_auth_signing_alg_values_supported: z
63
+ .array(z.string())
64
+ .optional(),
65
+
66
+ require_pushed_authorization_requests: z.boolean().optional(),
67
+
68
+ userinfo_endpoint: z.string().url().optional(),
69
+ end_session_endpoint: z.string().url().optional(),
70
+ registration_endpoint: z.string().url().optional(),
71
+
72
+ // https://datatracker.ietf.org/doc/html/rfc9449#section-5.1
73
+ dpop_signing_alg_values_supported: z.array(z.string()).optional(),
74
+
75
+ // https://datatracker.ietf.org/doc/html/draft-ietf-oauth-resource-metadata-05#section-4
76
+ protected_resources: z.array(z.string().url()).optional(),
77
+ })
78
+
79
+ export type OAuthAuthorizationServerMetadata = z.infer<
80
+ typeof oauthAuthorizationServerMetadataSchema
81
+ >
82
+
83
+ export const oauthAuthorizationServerMetadataValidator =
84
+ oauthAuthorizationServerMetadataSchema
85
+ .superRefine((data, ctx) => {
86
+ if (
87
+ data.require_pushed_authorization_requests &&
88
+ !data.pushed_authorization_request_endpoint
89
+ ) {
90
+ ctx.addIssue({
91
+ code: z.ZodIssueCode.custom,
92
+ message:
93
+ '"pushed_authorization_request_endpoint" required when "require_pushed_authorization_requests" is true',
94
+ })
95
+ }
96
+ })
97
+ .superRefine((data, ctx) => {
98
+ if (data.response_types_supported) {
99
+ if (!data.response_types_supported.includes('code')) {
100
+ ctx.addIssue({
101
+ code: z.ZodIssueCode.custom,
102
+ message: 'Response type "code" is required',
103
+ })
104
+ }
105
+ }
106
+ })
@@ -0,0 +1,34 @@
1
+ import { z } from 'zod'
2
+ import { signedJwtSchema } from '@atproto/jwk'
3
+
4
+ import { oauthClientIdSchema } from './oauth-client-id.js'
5
+ import { CLIENT_ASSERTION_TYPE_JWT_BEARER } from './constants.js'
6
+
7
+ export const oauthClientCredentialsJwtBearerSchema = z.object({
8
+ client_id: oauthClientIdSchema,
9
+ client_assertion_type: z.literal(CLIENT_ASSERTION_TYPE_JWT_BEARER),
10
+ /**
11
+ * - "sub" the subject MUST be the "client_id" of the OAuth client
12
+ * - "iat" is required and MUST be less than one minute
13
+ * - "aud" must containing a value that identifies the authorization server
14
+ * - The JWT MAY contain a "jti" (JWT ID) claim that provides a unique identifier for the token.
15
+ * - Note that the authorization server may reject JWTs with an "exp" claim value that is unreasonably far in the future.
16
+ *
17
+ * @see {@link https://datatracker.ietf.org/doc/html/draft-ietf-oauth-jwt-bearer-11#section-3}
18
+ */
19
+ client_assertion: signedJwtSchema,
20
+ })
21
+
22
+ export const oauthClientCredentialsSecretPostSchema = z.object({
23
+ client_id: oauthClientIdSchema,
24
+ client_secret: z.string(),
25
+ })
26
+
27
+ export const oauthClientCredentialsSchema = z.union([
28
+ oauthClientCredentialsJwtBearerSchema,
29
+ oauthClientCredentialsSecretPostSchema,
30
+ ])
31
+
32
+ export type OAuthClientCredentials = z.infer<
33
+ typeof oauthClientCredentialsSchema
34
+ >
@@ -0,0 +1,66 @@
1
+ import { parseOAuthClientIdUrl } from './oauth-client-id-url.js'
2
+ import { OAuthClientId } from './oauth-client-id.js'
3
+ import { isIP } from './util.js'
4
+
5
+ /**
6
+ * @see {@link https://drafts.aaronpk.com/draft-parecki-oauth-client-id-metadata-document/draft-parecki-oauth-client-id-metadata-document.html}
7
+ */
8
+ export type OAuthClientIdDiscoverable = OAuthClientId & `https://${string}`
9
+
10
+ export function isOAuthClientIdDiscoverable<C extends OAuthClientId>(
11
+ clientId: C,
12
+ ): clientId is C & OAuthClientIdDiscoverable {
13
+ try {
14
+ parseOAuthDiscoverableClientId(clientId)
15
+ return true
16
+ } catch {
17
+ return false
18
+ }
19
+ }
20
+
21
+ export function parseOAuthDiscoverableClientId(clientId: OAuthClientId): URL {
22
+ const url = parseOAuthClientIdUrl(clientId)
23
+
24
+ // Optimization: cheap checks first
25
+
26
+ if (url.hostname === 'localhost') {
27
+ throw new TypeError('ClientID must not be a loopback hostname')
28
+ }
29
+
30
+ if (url.protocol !== 'https:') {
31
+ throw new TypeError('ClientID must use the "https:" protocol')
32
+ }
33
+
34
+ if (url.hash) {
35
+ throw new TypeError('ClientID must not contain a fragment')
36
+ }
37
+
38
+ if (url.username || url.password) {
39
+ throw new TypeError('ClientID must not contain credentials')
40
+ }
41
+
42
+ if (url.pathname === '/') {
43
+ throw new TypeError(
44
+ 'ClientID must contain a path (e.g. "/client-metadata")',
45
+ )
46
+ }
47
+
48
+ if (url.pathname !== '/' && url.pathname.endsWith('/')) {
49
+ throw new TypeError('ClientID must not end with a trailing slash')
50
+ }
51
+
52
+ if (url.pathname.includes('//')) {
53
+ throw new TypeError(
54
+ `ClientID must not contain any double slashes in its path`,
55
+ )
56
+ }
57
+
58
+ // Note: Query string is allowed
59
+ // Note: no restriction on the port for non-loopback URIs
60
+
61
+ if (isIP(url.hostname)) {
62
+ throw new TypeError('ClientID must not be an IP address')
63
+ }
64
+
65
+ return url
66
+ }