@atproto/oauth-provider 0.1.1 → 0.1.2-rc.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,43 @@
1
+ /// <reference types="node" />
2
+ import { OAuthAuthenticationRequestParameters, OAuthClientMetadata } from '@atproto/oauth-types';
3
+ import { ServerResponse } from 'node:http';
4
+ import { DeviceAccountInfo } from '../account/account-store.js';
5
+ import { Account } from '../account/account.js';
6
+ import { Client } from '../client/client.js';
7
+ import { RequestUri } from '../request/request-uri.js';
8
+ import { Customization } from './customization.js';
9
+ export type AuthorizationResultAuthorize = {
10
+ issuer: string;
11
+ client: Client;
12
+ parameters: OAuthAuthenticationRequestParameters;
13
+ authorize: {
14
+ uri: RequestUri;
15
+ sessions: readonly {
16
+ account: Account;
17
+ info: DeviceAccountInfo;
18
+ selected: boolean;
19
+ loginRequired: boolean;
20
+ consentRequired: boolean;
21
+ }[];
22
+ };
23
+ };
24
+ type Session = {
25
+ account: Account;
26
+ info?: never;
27
+ selected: boolean;
28
+ loginRequired: boolean;
29
+ consentRequired: boolean;
30
+ };
31
+ export type AuthorizeData = {
32
+ clientId: string;
33
+ clientMetadata: OAuthClientMetadata;
34
+ clientTrusted: boolean;
35
+ requestUri: string;
36
+ csrfCookie: string;
37
+ loginHint?: string;
38
+ newSessionsRequireConsent: boolean;
39
+ sessions: Session[];
40
+ };
41
+ export declare function sendAuthorizePage(res: ServerResponse, data: AuthorizationResultAuthorize, customization?: Customization): Promise<void>;
42
+ export {};
43
+ //# sourceMappingURL=send-authorize-page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send-authorize-page.d.ts","sourceRoot":"","sources":["../../src/output/send-authorize-page.ts"],"names":[],"mappings":";AAAA,OAAO,EACL,oCAAoC,EACpC,mBAAmB,EACpB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAE1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAE/C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAE5C,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AACtD,OAAO,EACL,aAAa,EAGd,MAAM,oBAAoB,CAAA;AAG3B,MAAM,MAAM,4BAA4B,GAAG;IACzC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,oCAAoC,CAAA;IAChD,SAAS,EAAE;QACT,GAAG,EAAE,UAAU,CAAA;QACf,QAAQ,EAAE,SAAS;YACjB,OAAO,EAAE,OAAO,CAAA;YAChB,IAAI,EAAE,iBAAiB,CAAA;YAEvB,QAAQ,EAAE,OAAO,CAAA;YACjB,aAAa,EAAE,OAAO,CAAA;YACtB,eAAe,EAAE,OAAO,CAAA;SACzB,EAAE,CAAA;KACJ,CAAA;CACF,CAAA;AAKD,KAAK,OAAO,GAAG;IACb,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,CAAC,EAAE,KAAK,CAAA;IAEZ,QAAQ,EAAE,OAAO,CAAA;IACjB,aAAa,EAAE,OAAO,CAAA;IACtB,eAAe,EAAE,OAAO,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE,mBAAmB,CAAA;IACnC,aAAa,EAAE,OAAO,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,yBAAyB,EAAE,OAAO,CAAA;IAClC,QAAQ,EAAE,OAAO,EAAE,CAAA;CACpB,CAAA;AAsBD,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE,4BAA4B,EAClC,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC,IAAI,CAAC,CA2Bf"}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sendAuthorizePage = void 0;
4
+ const index_js_1 = require("../assets/index.js");
5
+ const index_js_2 = require("../lib/html/index.js");
6
+ const customization_js_1 = require("./customization.js");
7
+ const send_web_page_js_1 = require("./send-web-page.js");
8
+ function buildAuthorizeData(data) {
9
+ return {
10
+ clientId: data.client.id,
11
+ clientMetadata: data.client.metadata,
12
+ clientTrusted: data.client.info.isTrusted,
13
+ requestUri: data.authorize.uri,
14
+ csrfCookie: `csrf-${data.authorize.uri}`,
15
+ loginHint: data.parameters.login_hint,
16
+ newSessionsRequireConsent: data.parameters.prompt === 'consent',
17
+ sessions: data.authorize.sessions.map((session) => ({
18
+ account: session.account,
19
+ selected: session.selected,
20
+ loginRequired: session.loginRequired,
21
+ consentRequired: session.consentRequired,
22
+ })),
23
+ };
24
+ }
25
+ async function sendAuthorizePage(res, data, customization) {
26
+ res.setHeader('Cache-Control', 'no-store');
27
+ res.setHeader('Permissions-Policy', 'otp-credentials=*, document-domain=()');
28
+ const [jsAsset, cssAsset] = await Promise.all([
29
+ (0, index_js_1.getAsset)('main.js'),
30
+ (0, index_js_1.getAsset)('main.css'),
31
+ ]);
32
+ return (0, send_web_page_js_1.sendWebPage)(res, {
33
+ scripts: [
34
+ (0, send_web_page_js_1.declareBackendData)('__customizationData', (0, customization_js_1.buildCustomizationData)(customization)),
35
+ (0, send_web_page_js_1.declareBackendData)('__authorizeData', buildAuthorizeData(data)),
36
+ jsAsset, // Last (to be able to read the global variables)
37
+ ],
38
+ styles: [
39
+ cssAsset, // First (to be overridden by customization)
40
+ (0, index_js_2.cssCode)((0, customization_js_1.buildCustomizationCss)(customization)),
41
+ ],
42
+ links: customization?.links,
43
+ htmlAttrs: { lang: 'en' },
44
+ title: 'Authorize',
45
+ body: (0, index_js_2.html) `<div id="root"></div>`,
46
+ });
47
+ }
48
+ exports.sendAuthorizePage = sendAuthorizePage;
49
+ //# sourceMappingURL=send-authorize-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send-authorize-page.js","sourceRoot":"","sources":["../../src/output/send-authorize-page.ts"],"names":[],"mappings":";;;AAQA,iDAA6C;AAE7C,mDAAoD;AAEpD,yDAI2B;AAC3B,yDAAoE;AA0CpE,SAAS,kBAAkB,CAAC,IAAkC;IAC5D,OAAO;QACL,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE;QACxB,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;QACpC,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS;QACzC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG;QAC9B,UAAU,EAAE,QAAQ,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE;QACxC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU;QACrC,yBAAyB,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,SAAS;QAC/D,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CACnC,CAAC,OAAO,EAAW,EAAE,CAAC,CAAC;YACrB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,eAAe,EAAE,OAAO,CAAC,eAAe;SACzC,CAAC,CACH;KACF,CAAA;AACH,CAAC;AAEM,KAAK,UAAU,iBAAiB,CACrC,GAAmB,EACnB,IAAkC,EAClC,aAA6B;IAE7B,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,UAAU,CAAC,CAAA;IAC1C,GAAG,CAAC,SAAS,CAAC,oBAAoB,EAAE,uCAAuC,CAAC,CAAA;IAE5E,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC5C,IAAA,mBAAQ,EAAC,SAAS,CAAC;QACnB,IAAA,mBAAQ,EAAC,UAAU,CAAC;KACrB,CAAC,CAAA;IAEF,OAAO,IAAA,8BAAW,EAAC,GAAG,EAAE;QACtB,OAAO,EAAE;YACP,IAAA,qCAAkB,EAChB,qBAAqB,EACrB,IAAA,yCAAsB,EAAC,aAAa,CAAC,CACtC;YACD,IAAA,qCAAkB,EAAC,iBAAiB,EAAE,kBAAkB,CAAC,IAAI,CAAC,CAAC;YAC/D,OAAO,EAAE,iDAAiD;SAC3D;QACD,MAAM,EAAE;YACN,QAAQ,EAAE,4CAA4C;YACtD,IAAA,kBAAO,EAAC,IAAA,wCAAqB,EAAC,aAAa,CAAC,CAAC;SAC9C;QACD,KAAK,EAAE,aAAa,EAAE,KAAK;QAC3B,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;QACzB,KAAK,EAAE,WAAW;QAClB,IAAI,EAAE,IAAA,eAAI,EAAA,uBAAuB;KAClC,CAAC,CAAA;AACJ,CAAC;AA/BD,8CA+BC"}
@@ -0,0 +1,5 @@
1
+ /// <reference types="node" />
2
+ import { ServerResponse } from 'node:http';
3
+ import { Customization } from './customization.js';
4
+ export declare function sendErrorPage(res: ServerResponse, err: unknown, customization?: Customization): Promise<void>;
5
+ //# sourceMappingURL=send-error-page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send-error-page.d.ts","sourceRoot":"","sources":["../../src/output/send-error-page.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAK1C,OAAO,EACL,aAAa,EAGd,MAAM,oBAAoB,CAAA;AAG3B,wBAAsB,aAAa,CACjC,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,OAAO,EACZ,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC,IAAI,CAAC,CAwBf"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sendErrorPage = void 0;
4
+ const index_js_1 = require("../assets/index.js");
5
+ const index_js_2 = require("../lib/html/index.js");
6
+ const build_error_payload_js_1 = require("./build-error-payload.js");
7
+ const customization_js_1 = require("./customization.js");
8
+ const send_web_page_js_1 = require("./send-web-page.js");
9
+ async function sendErrorPage(res, err, customization) {
10
+ const [jsAsset, cssAsset] = await Promise.all([
11
+ (0, index_js_1.getAsset)('main.js'),
12
+ (0, index_js_1.getAsset)('main.css'),
13
+ ]);
14
+ return (0, send_web_page_js_1.sendWebPage)(res, {
15
+ status: (0, build_error_payload_js_1.buildErrorStatus)(err),
16
+ scripts: [
17
+ (0, send_web_page_js_1.declareBackendData)('__customizationData', (0, customization_js_1.buildCustomizationData)(customization)),
18
+ (0, send_web_page_js_1.declareBackendData)('__errorData', (0, build_error_payload_js_1.buildErrorPayload)(err)),
19
+ jsAsset, // Last (to be able to read the global variables)
20
+ ],
21
+ styles: [
22
+ cssAsset, // First (to be overridden by customization)
23
+ (0, index_js_2.cssCode)((0, customization_js_1.buildCustomizationCss)(customization)),
24
+ ],
25
+ htmlAttrs: { lang: 'en' },
26
+ title: 'Error',
27
+ body: (0, index_js_2.html) `<div id="root"></div>`,
28
+ });
29
+ }
30
+ exports.sendErrorPage = sendErrorPage;
31
+ //# sourceMappingURL=send-error-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send-error-page.js","sourceRoot":"","sources":["../../src/output/send-error-page.ts"],"names":[],"mappings":";;;AAEA,iDAA6C;AAC7C,mDAAoD;AACpD,qEAA8E;AAC9E,yDAI2B;AAC3B,yDAAoE;AAE7D,KAAK,UAAU,aAAa,CACjC,GAAmB,EACnB,GAAY,EACZ,aAA6B;IAE7B,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC5C,IAAA,mBAAQ,EAAC,SAAS,CAAC;QACnB,IAAA,mBAAQ,EAAC,UAAU,CAAC;KACrB,CAAC,CAAA;IAEF,OAAO,IAAA,8BAAW,EAAC,GAAG,EAAE;QACtB,MAAM,EAAE,IAAA,yCAAgB,EAAC,GAAG,CAAC;QAC7B,OAAO,EAAE;YACP,IAAA,qCAAkB,EAChB,qBAAqB,EACrB,IAAA,yCAAsB,EAAC,aAAa,CAAC,CACtC;YACD,IAAA,qCAAkB,EAAC,aAAa,EAAE,IAAA,0CAAiB,EAAC,GAAG,CAAC,CAAC;YACzD,OAAO,EAAE,iDAAiD;SAC3D;QACD,MAAM,EAAE;YACN,QAAQ,EAAE,4CAA4C;YACtD,IAAA,kBAAO,EAAC,IAAA,wCAAqB,EAAC,aAAa,CAAC,CAAC;SAC9C;QACD,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;QACzB,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,IAAA,eAAI,EAAA,uBAAuB;KAClC,CAAC,CAAA;AACJ,CAAC;AA5BD,sCA4BC"}
@@ -24,7 +24,7 @@ export interface TokenStore {
24
24
  rotateToken(tokenId: TokenId, newTokenId: TokenId, newRefreshToken: RefreshToken, newData: NewTokenData): Awaitable<void>;
25
25
  /**
26
26
  * Find a token by its refresh token. Note that previous refresh tokens
27
- * should also return the token. The data model is reponsible for storing
27
+ * should also return the token. The data model is responsible for storing
28
28
  * old refresh tokens when a new one is issued.
29
29
  */
30
30
  findTokenByRefreshToken(refreshToken: RefreshToken): Awaitable<null | TokenInfo>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/oauth-provider",
3
- "version": "0.1.1",
3
+ "version": "0.1.2-rc.1",
4
4
  "license": "MIT",
5
5
  "description": "Generic OAuth2 and OpenID Connect provider for Node.js. Currently only supports features needed for Atproto.",
6
6
  "keywords": [
@@ -41,11 +41,11 @@
41
41
  "@atproto-labs/fetch": "0.1.0",
42
42
  "@atproto-labs/fetch-node": "0.1.0",
43
43
  "@atproto-labs/pipe": "0.1.0",
44
- "@atproto-labs/simple-store-memory": "0.1.1",
45
44
  "@atproto-labs/simple-store": "0.1.1",
45
+ "@atproto/jwk-jose": "0.1.2-rc.0",
46
+ "@atproto/oauth-types": "0.1.2-rc.0",
46
47
  "@atproto/jwk": "0.1.1",
47
- "@atproto/jwk-jose": "0.1.1",
48
- "@atproto/oauth-types": "0.1.1"
48
+ "@atproto-labs/simple-store-memory": "0.1.1"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@rollup/plugin-commonjs": "^25.0.7",
@@ -45,7 +45,7 @@ export interface TokenStore {
45
45
 
46
46
  /**
47
47
  * Find a token by its refresh token. Note that previous refresh tokens
48
- * should also return the token. The data model is reponsible for storing
48
+ * should also return the token. The data model is responsible for storing
49
49
  * old refresh tokens when a new one is issued.
50
50
  */
51
51
  findTokenByRefreshToken(
@@ -1,41 +0,0 @@
1
- import { HtmlHTMLAttributes } from 'react'
2
- import { clsx } from '../lib/clsx'
3
-
4
- export type ErrorCardProps = {
5
- message?: null | string
6
- role?: 'alert' | 'status'
7
- }
8
-
9
- export function ErrorCard({
10
- message,
11
-
12
- role = 'alert',
13
- className,
14
- ...attrs
15
- }: Partial<ErrorCardProps> &
16
- Omit<HtmlHTMLAttributes<HTMLDivElement>, keyof ErrorCardProps | 'children'>) {
17
- return (
18
- <div
19
- {...attrs}
20
- className={clsx(
21
- 'flex items-center rounded bg-error py-1 px-2 text-white dark:text-black shadow-md',
22
- className,
23
- )}
24
- role={role}
25
- >
26
- <svg
27
- className="fill-current h-4 w-4"
28
- xmlns="http://www.w3.org/2000/svg"
29
- viewBox="0 0 20 20"
30
- >
31
- <path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm12.73-1.41A8 8 0 1 0 4.34 4.34a8 8 0 0 0 11.32 11.32zM9 11V9h2v6H9v-4zm0-6h2v2H9V5z" />
32
- </svg>
33
-
34
- <div className="ml-4">
35
- <p>
36
- {typeof message === 'string' ? message : 'An unknown error occurred'}
37
- </p>
38
- </div>
39
- </div>
40
- )
41
- }