@workos-inc/node 8.0.0-beta.1 → 8.0.0-beta.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/lib/actions/actions.cjs +1 -0
- package/lib/actions/actions.cjs.map +1 -1
- package/lib/actions/actions.js +1 -0
- package/lib/actions/actions.js.map +1 -1
- package/lib/common/crypto/crypto-provider.cjs +1 -3
- package/lib/common/crypto/crypto-provider.cjs.map +1 -1
- package/lib/common/crypto/crypto-provider.js +1 -3
- package/lib/common/crypto/crypto-provider.js.map +1 -1
- package/lib/common/crypto/signature-provider.cjs +1 -0
- package/lib/common/crypto/signature-provider.cjs.map +1 -1
- package/lib/common/crypto/signature-provider.js +1 -0
- package/lib/common/crypto/signature-provider.js.map +1 -1
- package/lib/common/crypto/subtle-crypto-provider.cjs +1 -0
- package/lib/common/crypto/subtle-crypto-provider.cjs.map +1 -1
- package/lib/common/crypto/subtle-crypto-provider.js +1 -0
- package/lib/common/crypto/subtle-crypto-provider.js.map +1 -1
- package/lib/common/exceptions/bad-request.exception.cjs +9 -6
- package/lib/common/exceptions/bad-request.exception.cjs.map +1 -1
- package/lib/common/exceptions/bad-request.exception.js +9 -6
- package/lib/common/exceptions/bad-request.exception.js.map +1 -1
- package/lib/common/exceptions/conflict.exception.cjs +6 -5
- package/lib/common/exceptions/conflict.exception.cjs.map +1 -1
- package/lib/common/exceptions/conflict.exception.js +6 -5
- package/lib/common/exceptions/conflict.exception.js.map +1 -1
- package/lib/common/exceptions/generic-server.exception.cjs +2 -2
- package/lib/common/exceptions/generic-server.exception.cjs.map +1 -1
- package/lib/common/exceptions/generic-server.exception.js +2 -2
- package/lib/common/exceptions/generic-server.exception.js.map +1 -1
- package/lib/common/exceptions/no-api-key-provided.exception.cjs +3 -6
- package/lib/common/exceptions/no-api-key-provided.exception.cjs.map +1 -1
- package/lib/common/exceptions/no-api-key-provided.exception.js +3 -6
- package/lib/common/exceptions/no-api-key-provided.exception.js.map +1 -1
- package/lib/common/exceptions/not-found.exception.cjs +8 -5
- package/lib/common/exceptions/not-found.exception.cjs.map +1 -1
- package/lib/common/exceptions/not-found.exception.js +8 -5
- package/lib/common/exceptions/not-found.exception.js.map +1 -1
- package/lib/common/exceptions/oauth.exception.cjs +1 -1
- package/lib/common/exceptions/oauth.exception.cjs.map +1 -1
- package/lib/common/exceptions/oauth.exception.js +1 -1
- package/lib/common/exceptions/oauth.exception.js.map +1 -1
- package/lib/common/exceptions/rate-limit-exceeded.exception.cjs +1 -1
- package/lib/common/exceptions/rate-limit-exceeded.exception.cjs.map +1 -1
- package/lib/common/exceptions/rate-limit-exceeded.exception.js +1 -1
- package/lib/common/exceptions/rate-limit-exceeded.exception.js.map +1 -1
- package/lib/common/exceptions/signature-verification.exception.cjs +4 -4
- package/lib/common/exceptions/signature-verification.exception.cjs.map +1 -1
- package/lib/common/exceptions/signature-verification.exception.js +4 -4
- package/lib/common/exceptions/signature-verification.exception.js.map +1 -1
- package/lib/common/exceptions/unauthorized.exception.cjs +3 -2
- package/lib/common/exceptions/unauthorized.exception.cjs.map +1 -1
- package/lib/common/exceptions/unauthorized.exception.js +3 -2
- package/lib/common/exceptions/unauthorized.exception.js.map +1 -1
- package/lib/common/exceptions/unprocessable-entity.exception.cjs +8 -6
- package/lib/common/exceptions/unprocessable-entity.exception.cjs.map +1 -1
- package/lib/common/exceptions/unprocessable-entity.exception.js +8 -6
- package/lib/common/exceptions/unprocessable-entity.exception.js.map +1 -1
- package/lib/common/net/fetch-client.cjs +2 -0
- package/lib/common/net/fetch-client.cjs.map +1 -1
- package/lib/common/net/fetch-client.js +2 -0
- package/lib/common/net/fetch-client.js.map +1 -1
- package/lib/common/net/http-client.cjs +15 -12
- package/lib/common/net/http-client.cjs.map +1 -1
- package/lib/common/net/http-client.js +15 -12
- package/lib/common/net/http-client.js.map +1 -1
- package/lib/common/utils/fetch-error.cjs +6 -5
- package/lib/common/utils/fetch-error.cjs.map +1 -1
- package/lib/common/utils/fetch-error.js +6 -5
- package/lib/common/utils/fetch-error.js.map +1 -1
- package/lib/common/utils/pagination.cjs +2 -1
- package/lib/common/utils/pagination.cjs.map +1 -1
- package/lib/common/utils/pagination.js +2 -1
- package/lib/common/utils/pagination.js.map +1 -1
- package/lib/fga/interfaces/check.interface.cjs +5 -0
- package/lib/fga/interfaces/check.interface.cjs.map +1 -1
- package/lib/fga/interfaces/check.interface.js +5 -0
- package/lib/fga/interfaces/check.interface.js.map +1 -1
- package/lib/fga/utils/fga-paginatable.cjs +1 -0
- package/lib/fga/utils/fga-paginatable.cjs.map +1 -1
- package/lib/fga/utils/fga-paginatable.js +1 -0
- package/lib/fga/utils/fga-paginatable.js.map +1 -1
- package/lib/user-management/session.cjs +4 -0
- package/lib/user-management/session.cjs.map +1 -1
- package/lib/user-management/session.js +4 -0
- package/lib/user-management/session.js.map +1 -1
- package/lib/user-management/user-management.cjs +2 -0
- package/lib/user-management/user-management.cjs.map +1 -1
- package/lib/user-management/user-management.js +2 -0
- package/lib/user-management/user-management.js.map +1 -1
- package/lib/vault/vault.cjs +1 -0
- package/lib/vault/vault.cjs.map +1 -1
- package/lib/vault/vault.js +1 -0
- package/lib/vault/vault.js.map +1 -1
- package/lib/webhooks/webhooks.cjs +1 -0
- package/lib/webhooks/webhooks.cjs.map +1 -1
- package/lib/webhooks/webhooks.js +1 -0
- package/lib/webhooks/webhooks.js.map +1 -1
- package/lib/workos.cjs +19 -13
- package/lib/workos.cjs.map +1 -1
- package/lib/workos.js +19 -13
- package/lib/workos.js.map +1 -1
- package/package.json +1 -1
|
@@ -4,17 +4,14 @@ class HttpClient {
|
|
|
4
4
|
constructor(baseURL, options) {
|
|
5
5
|
this.baseURL = baseURL;
|
|
6
6
|
this.options = options;
|
|
7
|
-
this.MAX_RETRY_ATTEMPTS = 3;
|
|
8
|
-
this.BACKOFF_MULTIPLIER = 1.5;
|
|
9
|
-
this.MINIMUM_SLEEP_TIME_IN_MILLISECONDS = 500;
|
|
10
|
-
this.RETRY_STATUS_CODES = [500, 502, 504];
|
|
11
|
-
this.sleep = /* @__PURE__ */ __name((retryAttempt) => new Promise(
|
|
12
|
-
(resolve) => setTimeout(resolve, this.getSleepTimeInMilliseconds(retryAttempt))
|
|
13
|
-
), "sleep");
|
|
14
7
|
}
|
|
15
8
|
static {
|
|
16
9
|
__name(this, "HttpClient");
|
|
17
10
|
}
|
|
11
|
+
MAX_RETRY_ATTEMPTS = 3;
|
|
12
|
+
BACKOFF_MULTIPLIER = 1.5;
|
|
13
|
+
MINIMUM_SLEEP_TIME_IN_MILLISECONDS = 500;
|
|
14
|
+
RETRY_STATUS_CODES = [500, 502, 504];
|
|
18
15
|
/** The HTTP client name used for diagnostics */
|
|
19
16
|
getClientName() {
|
|
20
17
|
throw new Error("getClientName not implemented");
|
|
@@ -58,11 +55,16 @@ class HttpClient {
|
|
|
58
55
|
const jitter = Math.random() + 0.5;
|
|
59
56
|
return sleepTime * jitter;
|
|
60
57
|
}
|
|
58
|
+
sleep = /* @__PURE__ */ __name((retryAttempt) => new Promise(
|
|
59
|
+
(resolve) => setTimeout(resolve, this.getSleepTimeInMilliseconds(retryAttempt))
|
|
60
|
+
), "sleep");
|
|
61
61
|
}
|
|
62
62
|
class HttpClientResponse {
|
|
63
63
|
static {
|
|
64
64
|
__name(this, "HttpClientResponse");
|
|
65
65
|
}
|
|
66
|
+
_statusCode;
|
|
67
|
+
_headers;
|
|
66
68
|
constructor(statusCode, headers) {
|
|
67
69
|
this._statusCode = statusCode;
|
|
68
70
|
this._headers = headers;
|
|
@@ -75,19 +77,20 @@ class HttpClientResponse {
|
|
|
75
77
|
}
|
|
76
78
|
}
|
|
77
79
|
class HttpClientError extends Error {
|
|
80
|
+
static {
|
|
81
|
+
__name(this, "HttpClientError");
|
|
82
|
+
}
|
|
83
|
+
name = "HttpClientError";
|
|
84
|
+
message = "The request could not be completed.";
|
|
85
|
+
response;
|
|
78
86
|
constructor({
|
|
79
87
|
message,
|
|
80
88
|
response
|
|
81
89
|
}) {
|
|
82
90
|
super(message);
|
|
83
|
-
this.name = "HttpClientError";
|
|
84
|
-
this.message = "The request could not be completed.";
|
|
85
91
|
this.message = message;
|
|
86
92
|
this.response = response;
|
|
87
93
|
}
|
|
88
|
-
static {
|
|
89
|
-
__name(this, "HttpClientError");
|
|
90
|
-
}
|
|
91
94
|
}
|
|
92
95
|
export {
|
|
93
96
|
HttpClient,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/common/net/http-client.ts"],"sourcesContent":["import {\n HttpClientInterface,\n HttpClientResponseInterface,\n RequestHeaders,\n RequestOptions,\n ResponseHeaders,\n} from '../interfaces/http-client.interface';\n\nexport abstract class HttpClient implements HttpClientInterface {\n readonly MAX_RETRY_ATTEMPTS = 3;\n readonly BACKOFF_MULTIPLIER = 1.5;\n readonly MINIMUM_SLEEP_TIME_IN_MILLISECONDS = 500;\n readonly RETRY_STATUS_CODES = [500, 502, 504];\n\n constructor(\n readonly baseURL: string,\n readonly options?: RequestInit,\n ) {}\n\n /** The HTTP client name used for diagnostics */\n getClientName(): string {\n throw new Error('getClientName not implemented');\n }\n\n abstract get(\n path: string,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface>;\n\n abstract post<Entity = any>(\n path: string,\n entity: Entity,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface>;\n\n abstract put<Entity = any>(\n path: string,\n entity: Entity,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface>;\n\n abstract delete(\n path: string,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface>;\n\n addClientToUserAgent(userAgent: string): string {\n if (userAgent.indexOf(' ') > -1) {\n return userAgent.replace(/\\b\\s/, `/${this.getClientName()} `);\n } else {\n return (userAgent += `/${this.getClientName()}`);\n }\n }\n\n static getResourceURL(\n baseURL: string,\n path: string,\n params?: Record<string, any>,\n ) {\n const queryString = HttpClient.getQueryString(params);\n const url = new URL([path, queryString].filter(Boolean).join('?'), baseURL);\n return url.toString();\n }\n\n static getQueryString(queryObj?: Record<string, any>) {\n if (!queryObj) return undefined;\n\n const sanitizedQueryObj: Record<string, any> = {};\n\n Object.entries(queryObj).forEach(([param, value]) => {\n if (value !== '' && value !== undefined) sanitizedQueryObj[param] = value;\n });\n\n return new URLSearchParams(sanitizedQueryObj).toString();\n }\n\n static getContentTypeHeader(entity: any): RequestHeaders | undefined {\n if (entity instanceof URLSearchParams) {\n return {\n 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',\n };\n }\n return undefined;\n }\n\n static getBody(entity: any): BodyInit | null | undefined {\n if (entity === null || entity instanceof URLSearchParams) {\n return entity;\n }\n\n return JSON.stringify(entity);\n }\n\n private getSleepTimeInMilliseconds(retryAttempt: number): number {\n const sleepTime =\n this.MINIMUM_SLEEP_TIME_IN_MILLISECONDS *\n Math.pow(this.BACKOFF_MULTIPLIER, retryAttempt);\n const jitter = Math.random() + 0.5;\n return sleepTime * jitter;\n }\n\n sleep = (retryAttempt: number) =>\n new Promise((resolve) =>\n setTimeout(resolve, this.getSleepTimeInMilliseconds(retryAttempt)),\n );\n}\n\n// tslint:disable-next-line\nexport abstract class HttpClientResponse\n implements HttpClientResponseInterface\n{\n _statusCode: number;\n _headers: ResponseHeaders;\n\n constructor(statusCode: number, headers: ResponseHeaders) {\n this._statusCode = statusCode;\n this._headers = headers;\n }\n\n getStatusCode(): number {\n return this._statusCode;\n }\n\n getHeaders(): ResponseHeaders {\n return this._headers;\n }\n\n abstract getRawResponse(): unknown;\n\n abstract toJSON(): any | null;\n}\n\n// tslint:disable-next-line\nexport class HttpClientError<T> extends Error {\n readonly name: string = 'HttpClientError';\n readonly message: string = 'The request could not be completed.';\n readonly response: { status: number; headers: any; data: T };\n\n constructor({\n message,\n response,\n }: {\n message: string;\n readonly response: HttpClientError<T>['response'];\n }) {\n super(message);\n this.message = message;\n this.response = response;\n }\n}\n"],"mappings":";;AAQO,MAAe,WAA0C;AAAA,EAM9D,YACW,SACA,SACT;AAFS;AACA;
|
|
1
|
+
{"version":3,"sources":["../../../src/common/net/http-client.ts"],"sourcesContent":["import {\n HttpClientInterface,\n HttpClientResponseInterface,\n RequestHeaders,\n RequestOptions,\n ResponseHeaders,\n} from '../interfaces/http-client.interface';\n\nexport abstract class HttpClient implements HttpClientInterface {\n readonly MAX_RETRY_ATTEMPTS = 3;\n readonly BACKOFF_MULTIPLIER = 1.5;\n readonly MINIMUM_SLEEP_TIME_IN_MILLISECONDS = 500;\n readonly RETRY_STATUS_CODES = [500, 502, 504];\n\n constructor(\n readonly baseURL: string,\n readonly options?: RequestInit,\n ) {}\n\n /** The HTTP client name used for diagnostics */\n getClientName(): string {\n throw new Error('getClientName not implemented');\n }\n\n abstract get(\n path: string,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface>;\n\n abstract post<Entity = any>(\n path: string,\n entity: Entity,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface>;\n\n abstract put<Entity = any>(\n path: string,\n entity: Entity,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface>;\n\n abstract delete(\n path: string,\n options: RequestOptions,\n ): Promise<HttpClientResponseInterface>;\n\n addClientToUserAgent(userAgent: string): string {\n if (userAgent.indexOf(' ') > -1) {\n return userAgent.replace(/\\b\\s/, `/${this.getClientName()} `);\n } else {\n return (userAgent += `/${this.getClientName()}`);\n }\n }\n\n static getResourceURL(\n baseURL: string,\n path: string,\n params?: Record<string, any>,\n ) {\n const queryString = HttpClient.getQueryString(params);\n const url = new URL([path, queryString].filter(Boolean).join('?'), baseURL);\n return url.toString();\n }\n\n static getQueryString(queryObj?: Record<string, any>) {\n if (!queryObj) return undefined;\n\n const sanitizedQueryObj: Record<string, any> = {};\n\n Object.entries(queryObj).forEach(([param, value]) => {\n if (value !== '' && value !== undefined) sanitizedQueryObj[param] = value;\n });\n\n return new URLSearchParams(sanitizedQueryObj).toString();\n }\n\n static getContentTypeHeader(entity: any): RequestHeaders | undefined {\n if (entity instanceof URLSearchParams) {\n return {\n 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',\n };\n }\n return undefined;\n }\n\n static getBody(entity: any): BodyInit | null | undefined {\n if (entity === null || entity instanceof URLSearchParams) {\n return entity;\n }\n\n return JSON.stringify(entity);\n }\n\n private getSleepTimeInMilliseconds(retryAttempt: number): number {\n const sleepTime =\n this.MINIMUM_SLEEP_TIME_IN_MILLISECONDS *\n Math.pow(this.BACKOFF_MULTIPLIER, retryAttempt);\n const jitter = Math.random() + 0.5;\n return sleepTime * jitter;\n }\n\n sleep = (retryAttempt: number) =>\n new Promise((resolve) =>\n setTimeout(resolve, this.getSleepTimeInMilliseconds(retryAttempt)),\n );\n}\n\n// tslint:disable-next-line\nexport abstract class HttpClientResponse\n implements HttpClientResponseInterface\n{\n _statusCode: number;\n _headers: ResponseHeaders;\n\n constructor(statusCode: number, headers: ResponseHeaders) {\n this._statusCode = statusCode;\n this._headers = headers;\n }\n\n getStatusCode(): number {\n return this._statusCode;\n }\n\n getHeaders(): ResponseHeaders {\n return this._headers;\n }\n\n abstract getRawResponse(): unknown;\n\n abstract toJSON(): any | null;\n}\n\n// tslint:disable-next-line\nexport class HttpClientError<T> extends Error {\n readonly name: string = 'HttpClientError';\n readonly message: string = 'The request could not be completed.';\n readonly response: { status: number; headers: any; data: T };\n\n constructor({\n message,\n response,\n }: {\n message: string;\n readonly response: HttpClientError<T>['response'];\n }) {\n super(message);\n this.message = message;\n this.response = response;\n }\n}\n"],"mappings":";;AAQO,MAAe,WAA0C;AAAA,EAM9D,YACW,SACA,SACT;AAFS;AACA;AAAA,EACR;AAAA,EAjBL,OAQgE;AAAA;AAAA;AAAA,EACrD,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,qCAAqC;AAAA,EACrC,qBAAqB,CAAC,KAAK,KAAK,GAAG;AAAA;AAAA,EAQ5C,gBAAwB;AACtB,UAAM,IAAI,MAAM,+BAA+B;AAAA,EACjD;AAAA,EAwBA,qBAAqB,WAA2B;AAC9C,QAAI,UAAU,QAAQ,GAAG,IAAI,IAAI;AAC/B,aAAO,UAAU,QAAQ,QAAQ,IAAI,KAAK,cAAc,CAAC,GAAG;AAAA,IAC9D,OAAO;AACL,aAAQ,aAAa,IAAI,KAAK,cAAc,CAAC;AAAA,IAC/C;AAAA,EACF;AAAA,EAEA,OAAO,eACL,SACA,MACA,QACA;AACA,UAAM,cAAc,WAAW,eAAe,MAAM;AACpD,UAAM,MAAM,IAAI,IAAI,CAAC,MAAM,WAAW,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,OAAO;AAC1E,WAAO,IAAI,SAAS;AAAA,EACtB;AAAA,EAEA,OAAO,eAAe,UAAgC;AACpD,QAAI,CAAC,SAAU,QAAO;AAEtB,UAAM,oBAAyC,CAAC;AAEhD,WAAO,QAAQ,QAAQ,EAAE,QAAQ,CAAC,CAAC,OAAO,KAAK,MAAM;AACnD,UAAI,UAAU,MAAM,UAAU,OAAW,mBAAkB,KAAK,IAAI;AAAA,IACtE,CAAC;AAED,WAAO,IAAI,gBAAgB,iBAAiB,EAAE,SAAS;AAAA,EACzD;AAAA,EAEA,OAAO,qBAAqB,QAAyC;AACnE,QAAI,kBAAkB,iBAAiB;AACrC,aAAO;AAAA,QACL,gBAAgB;AAAA,MAClB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,QAAQ,QAA0C;AACvD,QAAI,WAAW,QAAQ,kBAAkB,iBAAiB;AACxD,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,UAAU,MAAM;AAAA,EAC9B;AAAA,EAEQ,2BAA2B,cAA8B;AAC/D,UAAM,YACJ,KAAK,qCACL,KAAK,IAAI,KAAK,oBAAoB,YAAY;AAChD,UAAM,SAAS,KAAK,OAAO,IAAI;AAC/B,WAAO,YAAY;AAAA,EACrB;AAAA,EAEA,QAAQ,wBAAC,iBACP,IAAI;AAAA,IAAQ,CAAC,YACX,WAAW,SAAS,KAAK,2BAA2B,YAAY,CAAC;AAAA,EACnE,GAHM;AAIV;AAGO,MAAe,mBAEtB;AAAA,EA9GA,OA8GA;AAAA;AAAA;AAAA,EACE;AAAA,EACA;AAAA,EAEA,YAAY,YAAoB,SAA0B;AACxD,SAAK,cAAc;AACnB,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,gBAAwB;AACtB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,aAA8B;AAC5B,WAAO,KAAK;AAAA,EACd;AAKF;AAGO,MAAM,wBAA2B,MAAM;AAAA,EArI9C,OAqI8C;AAAA;AAAA;AAAA,EACnC,OAAe;AAAA,EACf,UAAkB;AAAA,EAClB;AAAA,EAET,YAAY;AAAA,IACV;AAAA,IACA;AAAA,EACF,GAGG;AACD,UAAM,OAAO;AACb,SAAK,UAAU;AACf,SAAK,WAAW;AAAA,EAClB;AACF;","names":[]}
|
|
@@ -23,19 +23,20 @@ __export(fetch_error_exports, {
|
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(fetch_error_exports);
|
|
25
25
|
class FetchError extends Error {
|
|
26
|
+
static {
|
|
27
|
+
__name(this, "FetchError");
|
|
28
|
+
}
|
|
29
|
+
name = "FetchError";
|
|
30
|
+
message = "The request could not be completed.";
|
|
31
|
+
response;
|
|
26
32
|
constructor({
|
|
27
33
|
message,
|
|
28
34
|
response
|
|
29
35
|
}) {
|
|
30
36
|
super(message);
|
|
31
|
-
this.name = "FetchError";
|
|
32
|
-
this.message = "The request could not be completed.";
|
|
33
37
|
this.message = message;
|
|
34
38
|
this.response = response;
|
|
35
39
|
}
|
|
36
|
-
static {
|
|
37
|
-
__name(this, "FetchError");
|
|
38
|
-
}
|
|
39
40
|
}
|
|
40
41
|
// Annotate the CommonJS export names for ESM import in node:
|
|
41
42
|
0 && (module.exports = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/common/utils/fetch-error.ts"],"sourcesContent":["export class FetchError<T> extends Error {\n readonly name: string = 'FetchError';\n readonly message: string = 'The request could not be completed.';\n readonly response: { status: number; headers: Headers; data: T };\n\n constructor({\n message,\n response,\n }: {\n message: string;\n readonly response: FetchError<T>['response'];\n }) {\n super(message);\n this.message = message;\n this.response = response;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,mBAAsB,MAAM;AAAA,
|
|
1
|
+
{"version":3,"sources":["../../../src/common/utils/fetch-error.ts"],"sourcesContent":["export class FetchError<T> extends Error {\n readonly name: string = 'FetchError';\n readonly message: string = 'The request could not be completed.';\n readonly response: { status: number; headers: Headers; data: T };\n\n constructor({\n message,\n response,\n }: {\n message: string;\n readonly response: FetchError<T>['response'];\n }) {\n super(message);\n this.message = message;\n this.response = response;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,mBAAsB,MAAM;AAAA,EAAzC,OAAyC;AAAA;AAAA;AAAA,EAC9B,OAAe;AAAA,EACf,UAAkB;AAAA,EAClB;AAAA,EAET,YAAY;AAAA,IACV;AAAA,IACA;AAAA,EACF,GAGG;AACD,UAAM,OAAO;AACb,SAAK,UAAU;AACf,SAAK,WAAW;AAAA,EAClB;AACF;","names":[]}
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
3
|
class FetchError extends Error {
|
|
4
|
+
static {
|
|
5
|
+
__name(this, "FetchError");
|
|
6
|
+
}
|
|
7
|
+
name = "FetchError";
|
|
8
|
+
message = "The request could not be completed.";
|
|
9
|
+
response;
|
|
4
10
|
constructor({
|
|
5
11
|
message,
|
|
6
12
|
response
|
|
7
13
|
}) {
|
|
8
14
|
super(message);
|
|
9
|
-
this.name = "FetchError";
|
|
10
|
-
this.message = "The request could not be completed.";
|
|
11
15
|
this.message = message;
|
|
12
16
|
this.response = response;
|
|
13
17
|
}
|
|
14
|
-
static {
|
|
15
|
-
__name(this, "FetchError");
|
|
16
|
-
}
|
|
17
18
|
}
|
|
18
19
|
export {
|
|
19
20
|
FetchError
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/common/utils/fetch-error.ts"],"sourcesContent":["export class FetchError<T> extends Error {\n readonly name: string = 'FetchError';\n readonly message: string = 'The request could not be completed.';\n readonly response: { status: number; headers: Headers; data: T };\n\n constructor({\n message,\n response,\n }: {\n message: string;\n readonly response: FetchError<T>['response'];\n }) {\n super(message);\n this.message = message;\n this.response = response;\n }\n}\n"],"mappings":";;AAAO,MAAM,mBAAsB,MAAM;AAAA,
|
|
1
|
+
{"version":3,"sources":["../../../src/common/utils/fetch-error.ts"],"sourcesContent":["export class FetchError<T> extends Error {\n readonly name: string = 'FetchError';\n readonly message: string = 'The request could not be completed.';\n readonly response: { status: number; headers: Headers; data: T };\n\n constructor({\n message,\n response,\n }: {\n message: string;\n readonly response: FetchError<T>['response'];\n }) {\n super(message);\n this.message = message;\n this.response = response;\n }\n}\n"],"mappings":";;AAAO,MAAM,mBAAsB,MAAM;AAAA,EAAzC,OAAyC;AAAA;AAAA;AAAA,EAC9B,OAAe;AAAA,EACf,UAAkB;AAAA,EAClB;AAAA,EAET,YAAY;AAAA,IACV;AAAA,IACA;AAAA,EACF,GAGG;AACD,UAAM,OAAO;AACb,SAAK,UAAU;AACf,SAAK,WAAW;AAAA,EAClB;AACF;","names":[]}
|
|
@@ -26,12 +26,13 @@ class AutoPaginatable {
|
|
|
26
26
|
constructor(list, apiCall, options) {
|
|
27
27
|
this.list = list;
|
|
28
28
|
this.apiCall = apiCall;
|
|
29
|
-
this.object = "list";
|
|
30
29
|
this.options = options ?? {};
|
|
31
30
|
}
|
|
32
31
|
static {
|
|
33
32
|
__name(this, "AutoPaginatable");
|
|
34
33
|
}
|
|
34
|
+
object = "list";
|
|
35
|
+
options;
|
|
35
36
|
get data() {
|
|
36
37
|
return this.list.data;
|
|
37
38
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/common/utils/pagination.ts"],"sourcesContent":["import { List, PaginationOptions } from '../interfaces';\n\nexport class AutoPaginatable<\n ResourceType,\n ParametersType extends PaginationOptions,\n> {\n readonly object = 'list' as const;\n readonly options: ParametersType;\n\n constructor(\n protected list: List<ResourceType>,\n private apiCall: (params: PaginationOptions) => Promise<List<ResourceType>>,\n options?: ParametersType,\n ) {\n this.options = options ?? ({} as ParametersType);\n }\n\n get data(): ResourceType[] {\n return this.list.data;\n }\n\n get listMetadata() {\n return this.list.listMetadata;\n }\n\n private async *generatePages(\n params: PaginationOptions,\n ): AsyncGenerator<ResourceType[]> {\n const result = await this.apiCall({\n ...this.options,\n limit: 100,\n after: params.after,\n });\n\n yield result.data;\n\n if (result.listMetadata.after) {\n // Delay of 4rps to respect list users rate limits\n await new Promise((resolve) => setTimeout(resolve, 250));\n yield* this.generatePages({\n after: result.listMetadata.after,\n });\n }\n }\n\n /**\n * Automatically paginates over the list of results, returning the complete data set.\n * Returns the first result if `options.limit` is passed to the first request.\n */\n async autoPagination(): Promise<ResourceType[]> {\n if (this.options.limit) {\n return this.data;\n }\n\n const results: ResourceType[] = [];\n\n for await (const page of this.generatePages({\n after: this.options.after,\n })) {\n results.push(...page);\n }\n\n return results;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEO,MAAM,gBAGX;AAAA,EAIA,YACY,MACF,SACR,SACA;AAHU;AACF;
|
|
1
|
+
{"version":3,"sources":["../../../src/common/utils/pagination.ts"],"sourcesContent":["import { List, PaginationOptions } from '../interfaces';\n\nexport class AutoPaginatable<\n ResourceType,\n ParametersType extends PaginationOptions,\n> {\n readonly object = 'list' as const;\n readonly options: ParametersType;\n\n constructor(\n protected list: List<ResourceType>,\n private apiCall: (params: PaginationOptions) => Promise<List<ResourceType>>,\n options?: ParametersType,\n ) {\n this.options = options ?? ({} as ParametersType);\n }\n\n get data(): ResourceType[] {\n return this.list.data;\n }\n\n get listMetadata() {\n return this.list.listMetadata;\n }\n\n private async *generatePages(\n params: PaginationOptions,\n ): AsyncGenerator<ResourceType[]> {\n const result = await this.apiCall({\n ...this.options,\n limit: 100,\n after: params.after,\n });\n\n yield result.data;\n\n if (result.listMetadata.after) {\n // Delay of 4rps to respect list users rate limits\n await new Promise((resolve) => setTimeout(resolve, 250));\n yield* this.generatePages({\n after: result.listMetadata.after,\n });\n }\n }\n\n /**\n * Automatically paginates over the list of results, returning the complete data set.\n * Returns the first result if `options.limit` is passed to the first request.\n */\n async autoPagination(): Promise<ResourceType[]> {\n if (this.options.limit) {\n return this.data;\n }\n\n const results: ResourceType[] = [];\n\n for await (const page of this.generatePages({\n after: this.options.after,\n })) {\n results.push(...page);\n }\n\n return results;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEO,MAAM,gBAGX;AAAA,EAIA,YACY,MACF,SACR,SACA;AAHU;AACF;AAGR,SAAK,UAAU,WAAY,CAAC;AAAA,EAC9B;AAAA,EAfF,OAKE;AAAA;AAAA;AAAA,EACS,SAAS;AAAA,EACT;AAAA,EAUT,IAAI,OAAuB;AACzB,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA,EAEA,IAAI,eAAe;AACjB,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA,EAEA,OAAe,cACb,QACgC;AAChC,UAAM,SAAS,MAAM,KAAK,QAAQ;AAAA,MAChC,GAAG,KAAK;AAAA,MACR,OAAO;AAAA,MACP,OAAO,OAAO;AAAA,IAChB,CAAC;AAED,UAAM,OAAO;AAEb,QAAI,OAAO,aAAa,OAAO;AAE7B,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,GAAG,CAAC;AACvD,aAAO,KAAK,cAAc;AAAA,QACxB,OAAO,OAAO,aAAa;AAAA,MAC7B,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,iBAA0C;AAC9C,QAAI,KAAK,QAAQ,OAAO;AACtB,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,UAA0B,CAAC;AAEjC,qBAAiB,QAAQ,KAAK,cAAc;AAAA,MAC1C,OAAO,KAAK,QAAQ;AAAA,IACtB,CAAC,GAAG;AACF,cAAQ,KAAK,GAAG,IAAI;AAAA,IACtB;AAEA,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -4,12 +4,13 @@ class AutoPaginatable {
|
|
|
4
4
|
constructor(list, apiCall, options) {
|
|
5
5
|
this.list = list;
|
|
6
6
|
this.apiCall = apiCall;
|
|
7
|
-
this.object = "list";
|
|
8
7
|
this.options = options ?? {};
|
|
9
8
|
}
|
|
10
9
|
static {
|
|
11
10
|
__name(this, "AutoPaginatable");
|
|
12
11
|
}
|
|
12
|
+
object = "list";
|
|
13
|
+
options;
|
|
13
14
|
get data() {
|
|
14
15
|
return this.list.data;
|
|
15
16
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/common/utils/pagination.ts"],"sourcesContent":["import { List, PaginationOptions } from '../interfaces';\n\nexport class AutoPaginatable<\n ResourceType,\n ParametersType extends PaginationOptions,\n> {\n readonly object = 'list' as const;\n readonly options: ParametersType;\n\n constructor(\n protected list: List<ResourceType>,\n private apiCall: (params: PaginationOptions) => Promise<List<ResourceType>>,\n options?: ParametersType,\n ) {\n this.options = options ?? ({} as ParametersType);\n }\n\n get data(): ResourceType[] {\n return this.list.data;\n }\n\n get listMetadata() {\n return this.list.listMetadata;\n }\n\n private async *generatePages(\n params: PaginationOptions,\n ): AsyncGenerator<ResourceType[]> {\n const result = await this.apiCall({\n ...this.options,\n limit: 100,\n after: params.after,\n });\n\n yield result.data;\n\n if (result.listMetadata.after) {\n // Delay of 4rps to respect list users rate limits\n await new Promise((resolve) => setTimeout(resolve, 250));\n yield* this.generatePages({\n after: result.listMetadata.after,\n });\n }\n }\n\n /**\n * Automatically paginates over the list of results, returning the complete data set.\n * Returns the first result if `options.limit` is passed to the first request.\n */\n async autoPagination(): Promise<ResourceType[]> {\n if (this.options.limit) {\n return this.data;\n }\n\n const results: ResourceType[] = [];\n\n for await (const page of this.generatePages({\n after: this.options.after,\n })) {\n results.push(...page);\n }\n\n return results;\n }\n}\n"],"mappings":";;AAEO,MAAM,gBAGX;AAAA,EAIA,YACY,MACF,SACR,SACA;AAHU;AACF;
|
|
1
|
+
{"version":3,"sources":["../../../src/common/utils/pagination.ts"],"sourcesContent":["import { List, PaginationOptions } from '../interfaces';\n\nexport class AutoPaginatable<\n ResourceType,\n ParametersType extends PaginationOptions,\n> {\n readonly object = 'list' as const;\n readonly options: ParametersType;\n\n constructor(\n protected list: List<ResourceType>,\n private apiCall: (params: PaginationOptions) => Promise<List<ResourceType>>,\n options?: ParametersType,\n ) {\n this.options = options ?? ({} as ParametersType);\n }\n\n get data(): ResourceType[] {\n return this.list.data;\n }\n\n get listMetadata() {\n return this.list.listMetadata;\n }\n\n private async *generatePages(\n params: PaginationOptions,\n ): AsyncGenerator<ResourceType[]> {\n const result = await this.apiCall({\n ...this.options,\n limit: 100,\n after: params.after,\n });\n\n yield result.data;\n\n if (result.listMetadata.after) {\n // Delay of 4rps to respect list users rate limits\n await new Promise((resolve) => setTimeout(resolve, 250));\n yield* this.generatePages({\n after: result.listMetadata.after,\n });\n }\n }\n\n /**\n * Automatically paginates over the list of results, returning the complete data set.\n * Returns the first result if `options.limit` is passed to the first request.\n */\n async autoPagination(): Promise<ResourceType[]> {\n if (this.options.limit) {\n return this.data;\n }\n\n const results: ResourceType[] = [];\n\n for await (const page of this.generatePages({\n after: this.options.after,\n })) {\n results.push(...page);\n }\n\n return results;\n }\n}\n"],"mappings":";;AAEO,MAAM,gBAGX;AAAA,EAIA,YACY,MACF,SACR,SACA;AAHU;AACF;AAGR,SAAK,UAAU,WAAY,CAAC;AAAA,EAC9B;AAAA,EAfF,OAKE;AAAA;AAAA;AAAA,EACS,SAAS;AAAA,EACT;AAAA,EAUT,IAAI,OAAuB;AACzB,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA,EAEA,IAAI,eAAe;AACjB,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA,EAEA,OAAe,cACb,QACgC;AAChC,UAAM,SAAS,MAAM,KAAK,QAAQ;AAAA,MAChC,GAAG,KAAK;AAAA,MACR,OAAO;AAAA,MACP,OAAO,OAAO;AAAA,IAChB,CAAC;AAED,UAAM,OAAO;AAEb,QAAI,OAAO,aAAa,OAAO;AAE7B,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,GAAG,CAAC;AACvD,aAAO,KAAK,cAAc;AAAA,QACxB,OAAO,OAAO,aAAa;AAAA,MAC7B,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,iBAA0C;AAC9C,QAAI,KAAK,QAAQ,OAAO;AACtB,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,UAA0B,CAAC;AAEjC,qBAAiB,QAAQ,KAAK,cAAc;AAAA,MAC1C,OAAO,KAAK,QAAQ;AAAA,IACtB,CAAC,GAAG;AACF,cAAQ,KAAK,GAAG,IAAI;AAAA,IACtB;AAEA,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/fga/interfaces/check.interface.ts"],"sourcesContent":["import { ResourceInterface, ResourceOptions } from './resource.interface';\nimport { PolicyContext, SerializedSubject, Subject } from './warrant.interface';\nimport { CheckOp } from './check-op.enum';\nimport { PostOptions } from '../../common/interfaces';\nimport { deserializeDecisionTreeNode } from '../serializers/check-options.serializer';\nimport { Warning } from './warning.interface';\n\nconst CHECK_RESULT_AUTHORIZED = 'authorized';\n\nexport interface CheckWarrantOptions {\n resource: ResourceInterface | ResourceOptions;\n relation: string;\n subject: ResourceInterface | Subject;\n context?: PolicyContext;\n}\n\nexport interface SerializedCheckWarrantOptions {\n resource_type: string;\n resource_id: string;\n relation: string;\n subject: SerializedSubject;\n context: PolicyContext;\n}\n\nexport interface CheckOptions {\n op?: CheckOp;\n checks: CheckWarrantOptions[];\n debug?: boolean;\n}\n\nexport interface CheckBatchOptions {\n checks: CheckWarrantOptions[];\n debug?: boolean;\n}\n\nexport interface SerializedCheckOptions {\n op?: CheckOp;\n checks: SerializedCheckWarrantOptions[];\n debug?: boolean;\n}\n\nexport interface SerializedCheckBatchOptions {\n op: 'batch';\n checks: SerializedCheckWarrantOptions[];\n debug?: boolean;\n}\n\nexport interface CheckResultResponse {\n result: string;\n is_implicit: boolean;\n warrant_token: string;\n debug_info?: DebugInfoResponse;\n warnings?: Warning[];\n}\n\nexport interface DebugInfo {\n processingTime: number;\n decisionTree: DecisionTreeNode;\n}\n\nexport interface DecisionTreeNode {\n check: CheckWarrantOptions;\n policy?: string;\n decision: string;\n processingTime: number;\n children: DecisionTreeNode[];\n}\n\nexport interface DebugInfoResponse {\n processing_time: number;\n decision_tree: DecisionTreeNodeResponse;\n}\n\nexport interface DecisionTreeNodeResponse {\n check: SerializedCheckWarrantOptions;\n policy?: string;\n decision: string;\n processing_time: number;\n children: DecisionTreeNodeResponse[];\n}\n\nexport interface CheckResultInterface {\n result: string;\n isImplicit: boolean;\n warrantToken: string;\n debugInfo?: DebugInfo;\n warnings?: Warning[];\n}\n\nexport class CheckResult implements CheckResultInterface {\n public result: string;\n public isImplicit: boolean;\n public warrantToken: string;\n public debugInfo?: DebugInfo;\n public warnings?: Warning[];\n\n constructor(json: CheckResultResponse) {\n this.result = json.result;\n this.isImplicit = json.is_implicit;\n this.warrantToken = json.warrant_token;\n this.debugInfo = json.debug_info\n ? {\n processingTime: json.debug_info.processing_time,\n decisionTree: deserializeDecisionTreeNode(\n json.debug_info.decision_tree,\n ),\n }\n : undefined;\n this.warnings = json.warnings;\n }\n\n isAuthorized(): boolean {\n return this.result === CHECK_RESULT_AUTHORIZED;\n }\n}\n\nexport type CheckRequestOptions = Pick<PostOptions, 'warrantToken'>;\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,2BAA4C;AAG5C,MAAM,0BAA0B;AAkFzB,MAAM,YAA4C;AAAA,EAzFzD,OAyFyD;AAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"sources":["../../../src/fga/interfaces/check.interface.ts"],"sourcesContent":["import { ResourceInterface, ResourceOptions } from './resource.interface';\nimport { PolicyContext, SerializedSubject, Subject } from './warrant.interface';\nimport { CheckOp } from './check-op.enum';\nimport { PostOptions } from '../../common/interfaces';\nimport { deserializeDecisionTreeNode } from '../serializers/check-options.serializer';\nimport { Warning } from './warning.interface';\n\nconst CHECK_RESULT_AUTHORIZED = 'authorized';\n\nexport interface CheckWarrantOptions {\n resource: ResourceInterface | ResourceOptions;\n relation: string;\n subject: ResourceInterface | Subject;\n context?: PolicyContext;\n}\n\nexport interface SerializedCheckWarrantOptions {\n resource_type: string;\n resource_id: string;\n relation: string;\n subject: SerializedSubject;\n context: PolicyContext;\n}\n\nexport interface CheckOptions {\n op?: CheckOp;\n checks: CheckWarrantOptions[];\n debug?: boolean;\n}\n\nexport interface CheckBatchOptions {\n checks: CheckWarrantOptions[];\n debug?: boolean;\n}\n\nexport interface SerializedCheckOptions {\n op?: CheckOp;\n checks: SerializedCheckWarrantOptions[];\n debug?: boolean;\n}\n\nexport interface SerializedCheckBatchOptions {\n op: 'batch';\n checks: SerializedCheckWarrantOptions[];\n debug?: boolean;\n}\n\nexport interface CheckResultResponse {\n result: string;\n is_implicit: boolean;\n warrant_token: string;\n debug_info?: DebugInfoResponse;\n warnings?: Warning[];\n}\n\nexport interface DebugInfo {\n processingTime: number;\n decisionTree: DecisionTreeNode;\n}\n\nexport interface DecisionTreeNode {\n check: CheckWarrantOptions;\n policy?: string;\n decision: string;\n processingTime: number;\n children: DecisionTreeNode[];\n}\n\nexport interface DebugInfoResponse {\n processing_time: number;\n decision_tree: DecisionTreeNodeResponse;\n}\n\nexport interface DecisionTreeNodeResponse {\n check: SerializedCheckWarrantOptions;\n policy?: string;\n decision: string;\n processing_time: number;\n children: DecisionTreeNodeResponse[];\n}\n\nexport interface CheckResultInterface {\n result: string;\n isImplicit: boolean;\n warrantToken: string;\n debugInfo?: DebugInfo;\n warnings?: Warning[];\n}\n\nexport class CheckResult implements CheckResultInterface {\n public result: string;\n public isImplicit: boolean;\n public warrantToken: string;\n public debugInfo?: DebugInfo;\n public warnings?: Warning[];\n\n constructor(json: CheckResultResponse) {\n this.result = json.result;\n this.isImplicit = json.is_implicit;\n this.warrantToken = json.warrant_token;\n this.debugInfo = json.debug_info\n ? {\n processingTime: json.debug_info.processing_time,\n decisionTree: deserializeDecisionTreeNode(\n json.debug_info.decision_tree,\n ),\n }\n : undefined;\n this.warnings = json.warnings;\n }\n\n isAuthorized(): boolean {\n return this.result === CHECK_RESULT_AUTHORIZED;\n }\n}\n\nexport type CheckRequestOptions = Pick<PostOptions, 'warrantToken'>;\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,2BAA4C;AAG5C,MAAM,0BAA0B;AAkFzB,MAAM,YAA4C;AAAA,EAzFzD,OAyFyD;AAAA;AAAA;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEP,YAAY,MAA2B;AACrC,SAAK,SAAS,KAAK;AACnB,SAAK,aAAa,KAAK;AACvB,SAAK,eAAe,KAAK;AACzB,SAAK,YAAY,KAAK,aAClB;AAAA,MACE,gBAAgB,KAAK,WAAW;AAAA,MAChC,kBAAc;AAAA,QACZ,KAAK,WAAW;AAAA,MAClB;AAAA,IACF,IACA;AACJ,SAAK,WAAW,KAAK;AAAA,EACvB;AAAA,EAEA,eAAwB;AACtB,WAAO,KAAK,WAAW;AAAA,EACzB;AACF;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/fga/interfaces/check.interface.ts"],"sourcesContent":["import { ResourceInterface, ResourceOptions } from './resource.interface';\nimport { PolicyContext, SerializedSubject, Subject } from './warrant.interface';\nimport { CheckOp } from './check-op.enum';\nimport { PostOptions } from '../../common/interfaces';\nimport { deserializeDecisionTreeNode } from '../serializers/check-options.serializer';\nimport { Warning } from './warning.interface';\n\nconst CHECK_RESULT_AUTHORIZED = 'authorized';\n\nexport interface CheckWarrantOptions {\n resource: ResourceInterface | ResourceOptions;\n relation: string;\n subject: ResourceInterface | Subject;\n context?: PolicyContext;\n}\n\nexport interface SerializedCheckWarrantOptions {\n resource_type: string;\n resource_id: string;\n relation: string;\n subject: SerializedSubject;\n context: PolicyContext;\n}\n\nexport interface CheckOptions {\n op?: CheckOp;\n checks: CheckWarrantOptions[];\n debug?: boolean;\n}\n\nexport interface CheckBatchOptions {\n checks: CheckWarrantOptions[];\n debug?: boolean;\n}\n\nexport interface SerializedCheckOptions {\n op?: CheckOp;\n checks: SerializedCheckWarrantOptions[];\n debug?: boolean;\n}\n\nexport interface SerializedCheckBatchOptions {\n op: 'batch';\n checks: SerializedCheckWarrantOptions[];\n debug?: boolean;\n}\n\nexport interface CheckResultResponse {\n result: string;\n is_implicit: boolean;\n warrant_token: string;\n debug_info?: DebugInfoResponse;\n warnings?: Warning[];\n}\n\nexport interface DebugInfo {\n processingTime: number;\n decisionTree: DecisionTreeNode;\n}\n\nexport interface DecisionTreeNode {\n check: CheckWarrantOptions;\n policy?: string;\n decision: string;\n processingTime: number;\n children: DecisionTreeNode[];\n}\n\nexport interface DebugInfoResponse {\n processing_time: number;\n decision_tree: DecisionTreeNodeResponse;\n}\n\nexport interface DecisionTreeNodeResponse {\n check: SerializedCheckWarrantOptions;\n policy?: string;\n decision: string;\n processing_time: number;\n children: DecisionTreeNodeResponse[];\n}\n\nexport interface CheckResultInterface {\n result: string;\n isImplicit: boolean;\n warrantToken: string;\n debugInfo?: DebugInfo;\n warnings?: Warning[];\n}\n\nexport class CheckResult implements CheckResultInterface {\n public result: string;\n public isImplicit: boolean;\n public warrantToken: string;\n public debugInfo?: DebugInfo;\n public warnings?: Warning[];\n\n constructor(json: CheckResultResponse) {\n this.result = json.result;\n this.isImplicit = json.is_implicit;\n this.warrantToken = json.warrant_token;\n this.debugInfo = json.debug_info\n ? {\n processingTime: json.debug_info.processing_time,\n decisionTree: deserializeDecisionTreeNode(\n json.debug_info.decision_tree,\n ),\n }\n : undefined;\n this.warnings = json.warnings;\n }\n\n isAuthorized(): boolean {\n return this.result === CHECK_RESULT_AUTHORIZED;\n }\n}\n\nexport type CheckRequestOptions = Pick<PostOptions, 'warrantToken'>;\n"],"mappings":";;AAIA,SAAS,mCAAmC;AAG5C,MAAM,0BAA0B;AAkFzB,MAAM,YAA4C;AAAA,EAzFzD,OAyFyD;AAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"sources":["../../../src/fga/interfaces/check.interface.ts"],"sourcesContent":["import { ResourceInterface, ResourceOptions } from './resource.interface';\nimport { PolicyContext, SerializedSubject, Subject } from './warrant.interface';\nimport { CheckOp } from './check-op.enum';\nimport { PostOptions } from '../../common/interfaces';\nimport { deserializeDecisionTreeNode } from '../serializers/check-options.serializer';\nimport { Warning } from './warning.interface';\n\nconst CHECK_RESULT_AUTHORIZED = 'authorized';\n\nexport interface CheckWarrantOptions {\n resource: ResourceInterface | ResourceOptions;\n relation: string;\n subject: ResourceInterface | Subject;\n context?: PolicyContext;\n}\n\nexport interface SerializedCheckWarrantOptions {\n resource_type: string;\n resource_id: string;\n relation: string;\n subject: SerializedSubject;\n context: PolicyContext;\n}\n\nexport interface CheckOptions {\n op?: CheckOp;\n checks: CheckWarrantOptions[];\n debug?: boolean;\n}\n\nexport interface CheckBatchOptions {\n checks: CheckWarrantOptions[];\n debug?: boolean;\n}\n\nexport interface SerializedCheckOptions {\n op?: CheckOp;\n checks: SerializedCheckWarrantOptions[];\n debug?: boolean;\n}\n\nexport interface SerializedCheckBatchOptions {\n op: 'batch';\n checks: SerializedCheckWarrantOptions[];\n debug?: boolean;\n}\n\nexport interface CheckResultResponse {\n result: string;\n is_implicit: boolean;\n warrant_token: string;\n debug_info?: DebugInfoResponse;\n warnings?: Warning[];\n}\n\nexport interface DebugInfo {\n processingTime: number;\n decisionTree: DecisionTreeNode;\n}\n\nexport interface DecisionTreeNode {\n check: CheckWarrantOptions;\n policy?: string;\n decision: string;\n processingTime: number;\n children: DecisionTreeNode[];\n}\n\nexport interface DebugInfoResponse {\n processing_time: number;\n decision_tree: DecisionTreeNodeResponse;\n}\n\nexport interface DecisionTreeNodeResponse {\n check: SerializedCheckWarrantOptions;\n policy?: string;\n decision: string;\n processing_time: number;\n children: DecisionTreeNodeResponse[];\n}\n\nexport interface CheckResultInterface {\n result: string;\n isImplicit: boolean;\n warrantToken: string;\n debugInfo?: DebugInfo;\n warnings?: Warning[];\n}\n\nexport class CheckResult implements CheckResultInterface {\n public result: string;\n public isImplicit: boolean;\n public warrantToken: string;\n public debugInfo?: DebugInfo;\n public warnings?: Warning[];\n\n constructor(json: CheckResultResponse) {\n this.result = json.result;\n this.isImplicit = json.is_implicit;\n this.warrantToken = json.warrant_token;\n this.debugInfo = json.debug_info\n ? {\n processingTime: json.debug_info.processing_time,\n decisionTree: deserializeDecisionTreeNode(\n json.debug_info.decision_tree,\n ),\n }\n : undefined;\n this.warnings = json.warnings;\n }\n\n isAuthorized(): boolean {\n return this.result === CHECK_RESULT_AUTHORIZED;\n }\n}\n\nexport type CheckRequestOptions = Pick<PostOptions, 'warrantToken'>;\n"],"mappings":";;AAIA,SAAS,mCAAmC;AAG5C,MAAM,0BAA0B;AAkFzB,MAAM,YAA4C;AAAA,EAzFzD,OAyFyD;AAAA;AAAA;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEP,YAAY,MAA2B;AACrC,SAAK,SAAS,KAAK;AACnB,SAAK,aAAa,KAAK;AACvB,SAAK,eAAe,KAAK;AACzB,SAAK,YAAY,KAAK,aAClB;AAAA,MACE,gBAAgB,KAAK,WAAW;AAAA,MAChC,cAAc;AAAA,QACZ,KAAK,WAAW;AAAA,MAClB;AAAA,IACF,IACA;AACJ,SAAK,WAAW,KAAK;AAAA,EACvB;AAAA,EAEA,eAAwB;AACtB,WAAO,KAAK,WAAW;AAAA,EACzB;AACF;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/fga/utils/fga-paginatable.ts"],"sourcesContent":["import { AutoPaginatable } from '../../common/utils/pagination';\nimport { FGAList } from '../interfaces/list.interface';\nimport { Warning } from '../interfaces/warning.interface';\nimport { PaginationOptions } from '../../common/interfaces';\n\nexport class FgaPaginatable
|
|
1
|
+
{"version":3,"sources":["../../../src/fga/utils/fga-paginatable.ts"],"sourcesContent":["import { AutoPaginatable } from '../../common/utils/pagination';\nimport { FGAList } from '../interfaces/list.interface';\nimport { Warning } from '../interfaces/warning.interface';\nimport { PaginationOptions } from '../../common/interfaces';\n\nexport class FgaPaginatable<\n T,\n P extends PaginationOptions = PaginationOptions,\n> extends AutoPaginatable<T, P> {\n protected override list: FGAList<T>;\n\n constructor(\n list: FGAList<T>,\n apiCall: (params: PaginationOptions) => Promise<FGAList<T>>,\n options?: P,\n ) {\n super(list, apiCall, options);\n this.list = list;\n }\n\n get warnings(): Warning[] | undefined {\n return this.list.warnings;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAgC;AAKzB,MAAM,uBAGH,kCAAsB;AAAA,EARhC,OAQgC;AAAA;AAAA;AAAA,EACX;AAAA,EAEnB,YACE,MACA,SACA,SACA;AACA,UAAM,MAAM,SAAS,OAAO;AAC5B,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,IAAI,WAAkC;AACpC,WAAO,KAAK,KAAK;AAAA,EACnB;AACF;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/fga/utils/fga-paginatable.ts"],"sourcesContent":["import { AutoPaginatable } from '../../common/utils/pagination';\nimport { FGAList } from '../interfaces/list.interface';\nimport { Warning } from '../interfaces/warning.interface';\nimport { PaginationOptions } from '../../common/interfaces';\n\nexport class FgaPaginatable
|
|
1
|
+
{"version":3,"sources":["../../../src/fga/utils/fga-paginatable.ts"],"sourcesContent":["import { AutoPaginatable } from '../../common/utils/pagination';\nimport { FGAList } from '../interfaces/list.interface';\nimport { Warning } from '../interfaces/warning.interface';\nimport { PaginationOptions } from '../../common/interfaces';\n\nexport class FgaPaginatable<\n T,\n P extends PaginationOptions = PaginationOptions,\n> extends AutoPaginatable<T, P> {\n protected override list: FGAList<T>;\n\n constructor(\n list: FGAList<T>,\n apiCall: (params: PaginationOptions) => Promise<FGAList<T>>,\n options?: P,\n ) {\n super(list, apiCall, options);\n this.list = list;\n }\n\n get warnings(): Warning[] | undefined {\n return this.list.warnings;\n }\n}\n"],"mappings":";;AAAA,SAAS,uBAAuB;AAKzB,MAAM,uBAGH,gBAAsB;AAAA,EARhC,OAQgC;AAAA;AAAA;AAAA,EACX;AAAA,EAEnB,YACE,MACA,SACA,SACA;AACA,UAAM,MAAM,SAAS,OAAO;AAC5B,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,IAAI,WAAkC;AACpC,WAAO,KAAK,KAAK;AAAA,EACnB;AACF;","names":[]}
|
|
@@ -30,6 +30,10 @@ class Session {
|
|
|
30
30
|
static {
|
|
31
31
|
__name(this, "Session");
|
|
32
32
|
}
|
|
33
|
+
jwks;
|
|
34
|
+
userManagement;
|
|
35
|
+
cookiePassword;
|
|
36
|
+
sessionData;
|
|
33
37
|
constructor(userManagement, sessionData, cookiePassword) {
|
|
34
38
|
if (!cookiePassword) {
|
|
35
39
|
throw new Error("cookiePassword is required");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/user-management/session.ts"],"sourcesContent":["import { createRemoteJWKSet, decodeJwt, jwtVerify } from 'jose';\nimport { OauthException } from '../common/exceptions/oauth.exception';\nimport {\n AccessToken,\n AuthenticateWithSessionCookieFailedResponse,\n AuthenticateWithSessionCookieFailureReason,\n AuthenticateWithSessionCookieSuccessResponse,\n AuthenticationResponse,\n RefreshSessionFailureReason,\n RefreshSessionResponse,\n SessionCookieData,\n} from './interfaces';\nimport { UserManagement } from './user-management';\nimport { unsealData } from 'iron-session';\n\ntype RefreshOptions = {\n cookiePassword?: string;\n organizationId?: string;\n};\n\nexport class Session {\n private jwks: ReturnType<typeof createRemoteJWKSet> | undefined;\n private userManagement: UserManagement;\n private cookiePassword: string;\n private sessionData: string;\n\n constructor(\n userManagement: UserManagement,\n sessionData: string,\n cookiePassword: string,\n ) {\n if (!cookiePassword) {\n throw new Error('cookiePassword is required');\n }\n\n this.userManagement = userManagement;\n this.cookiePassword = cookiePassword;\n this.sessionData = sessionData;\n\n this.jwks = this.userManagement.jwks;\n }\n\n /**\n * Authenticates a user with a session cookie.\n *\n * @returns An object indicating whether the authentication was successful or not. If successful, it will include the user's session data.\n */\n async authenticate(): Promise<\n | AuthenticateWithSessionCookieSuccessResponse\n | AuthenticateWithSessionCookieFailedResponse\n > {\n if (!this.sessionData) {\n return {\n authenticated: false,\n reason:\n AuthenticateWithSessionCookieFailureReason.NO_SESSION_COOKIE_PROVIDED,\n };\n }\n\n let session: SessionCookieData;\n\n try {\n session = await unsealData<SessionCookieData>(this.sessionData, {\n password: this.cookiePassword,\n });\n } catch (e) {\n return {\n authenticated: false,\n reason:\n AuthenticateWithSessionCookieFailureReason.INVALID_SESSION_COOKIE,\n };\n }\n\n if (!session.accessToken) {\n return {\n authenticated: false,\n reason:\n AuthenticateWithSessionCookieFailureReason.INVALID_SESSION_COOKIE,\n };\n }\n\n if (!(await this.isValidJwt(session.accessToken))) {\n return {\n authenticated: false,\n reason: AuthenticateWithSessionCookieFailureReason.INVALID_JWT,\n };\n }\n\n const {\n sid: sessionId,\n org_id: organizationId,\n role,\n permissions,\n entitlements,\n } = decodeJwt<AccessToken>(session.accessToken);\n\n return {\n authenticated: true,\n sessionId,\n organizationId,\n role,\n permissions,\n entitlements,\n user: session.user,\n impersonator: session.impersonator,\n accessToken: session.accessToken,\n };\n }\n\n /**\n * Refreshes the user's session.\n *\n * @param options - Optional options for refreshing the session.\n * @param options.cookiePassword - The password to use for the new session cookie.\n * @param options.organizationId - The organization ID to use for the new session cookie.\n * @returns An object indicating whether the refresh was successful or not. If successful, it will include the new sealed session data.\n */\n async refresh(options: RefreshOptions = {}): Promise<RefreshSessionResponse> {\n const session = await unsealData<SessionCookieData>(this.sessionData, {\n password: this.cookiePassword,\n });\n\n if (!session.refreshToken || !session.user) {\n return {\n authenticated: false,\n reason: RefreshSessionFailureReason.INVALID_SESSION_COOKIE,\n };\n }\n\n const { org_id: organizationIdFromAccessToken } = decodeJwt<AccessToken>(\n session.accessToken,\n );\n\n try {\n const cookiePassword = options.cookiePassword ?? this.cookiePassword;\n\n const authenticationResponse =\n await this.userManagement.authenticateWithRefreshToken({\n clientId: this.userManagement.clientId as string,\n refreshToken: session.refreshToken,\n organizationId:\n options.organizationId ?? organizationIdFromAccessToken,\n session: {\n // We want to store the new sealed session in this class instance, so this always needs to be true\n sealSession: true,\n cookiePassword,\n },\n });\n\n // Update the password if a new one was provided\n if (options.cookiePassword) {\n this.cookiePassword = options.cookiePassword;\n }\n\n this.sessionData = authenticationResponse.sealedSession as string;\n\n const {\n sid: sessionId,\n org_id: organizationId,\n role,\n permissions,\n entitlements,\n } = decodeJwt<AccessToken>(authenticationResponse.accessToken);\n\n // TODO: Returning `session` here means there's some duplicated data.\n // Slim down the return type in a future major version.\n return {\n authenticated: true,\n sealedSession: authenticationResponse.sealedSession,\n session: authenticationResponse as AuthenticationResponse,\n sessionId,\n organizationId,\n role,\n permissions,\n entitlements,\n user: session.user,\n impersonator: session.impersonator,\n };\n } catch (error) {\n if (\n error instanceof OauthException &&\n // TODO: Add additional known errors and remove re-throw\n (error.error === RefreshSessionFailureReason.INVALID_GRANT ||\n error.error === RefreshSessionFailureReason.MFA_ENROLLMENT ||\n error.error === RefreshSessionFailureReason.SSO_REQUIRED)\n ) {\n return {\n authenticated: false,\n reason: error.error,\n };\n }\n\n throw error;\n }\n }\n\n /**\n * Gets the URL to redirect the user to for logging out.\n *\n * @returns The URL to redirect the user to for logging out.\n */\n async getLogoutUrl({\n returnTo,\n }: { returnTo?: string } = {}): Promise<string> {\n const authenticationResponse = await this.authenticate();\n\n if (!authenticationResponse.authenticated) {\n const { reason } = authenticationResponse;\n throw new Error(`Failed to extract session ID for logout URL: ${reason}`);\n }\n\n return this.userManagement.getLogoutUrl({\n sessionId: authenticationResponse.sessionId,\n returnTo,\n });\n }\n\n private async isValidJwt(accessToken: string): Promise<boolean> {\n if (!this.jwks) {\n throw new Error(\n 'Missing client ID. Did you provide it when initializing WorkOS?',\n );\n }\n\n try {\n await jwtVerify(accessToken, this.jwks);\n return true;\n } catch (e) {\n return false;\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAyD;AACzD,mBAA+B;AAC/B,wBASO;AAEP,0BAA2B;AAOpB,MAAM,QAAQ;AAAA,EApBrB,OAoBqB;AAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"sources":["../../src/user-management/session.ts"],"sourcesContent":["import { createRemoteJWKSet, decodeJwt, jwtVerify } from 'jose';\nimport { OauthException } from '../common/exceptions/oauth.exception';\nimport {\n AccessToken,\n AuthenticateWithSessionCookieFailedResponse,\n AuthenticateWithSessionCookieFailureReason,\n AuthenticateWithSessionCookieSuccessResponse,\n AuthenticationResponse,\n RefreshSessionFailureReason,\n RefreshSessionResponse,\n SessionCookieData,\n} from './interfaces';\nimport { UserManagement } from './user-management';\nimport { unsealData } from 'iron-session';\n\ntype RefreshOptions = {\n cookiePassword?: string;\n organizationId?: string;\n};\n\nexport class Session {\n private jwks: ReturnType<typeof createRemoteJWKSet> | undefined;\n private userManagement: UserManagement;\n private cookiePassword: string;\n private sessionData: string;\n\n constructor(\n userManagement: UserManagement,\n sessionData: string,\n cookiePassword: string,\n ) {\n if (!cookiePassword) {\n throw new Error('cookiePassword is required');\n }\n\n this.userManagement = userManagement;\n this.cookiePassword = cookiePassword;\n this.sessionData = sessionData;\n\n this.jwks = this.userManagement.jwks;\n }\n\n /**\n * Authenticates a user with a session cookie.\n *\n * @returns An object indicating whether the authentication was successful or not. If successful, it will include the user's session data.\n */\n async authenticate(): Promise<\n | AuthenticateWithSessionCookieSuccessResponse\n | AuthenticateWithSessionCookieFailedResponse\n > {\n if (!this.sessionData) {\n return {\n authenticated: false,\n reason:\n AuthenticateWithSessionCookieFailureReason.NO_SESSION_COOKIE_PROVIDED,\n };\n }\n\n let session: SessionCookieData;\n\n try {\n session = await unsealData<SessionCookieData>(this.sessionData, {\n password: this.cookiePassword,\n });\n } catch (e) {\n return {\n authenticated: false,\n reason:\n AuthenticateWithSessionCookieFailureReason.INVALID_SESSION_COOKIE,\n };\n }\n\n if (!session.accessToken) {\n return {\n authenticated: false,\n reason:\n AuthenticateWithSessionCookieFailureReason.INVALID_SESSION_COOKIE,\n };\n }\n\n if (!(await this.isValidJwt(session.accessToken))) {\n return {\n authenticated: false,\n reason: AuthenticateWithSessionCookieFailureReason.INVALID_JWT,\n };\n }\n\n const {\n sid: sessionId,\n org_id: organizationId,\n role,\n permissions,\n entitlements,\n } = decodeJwt<AccessToken>(session.accessToken);\n\n return {\n authenticated: true,\n sessionId,\n organizationId,\n role,\n permissions,\n entitlements,\n user: session.user,\n impersonator: session.impersonator,\n accessToken: session.accessToken,\n };\n }\n\n /**\n * Refreshes the user's session.\n *\n * @param options - Optional options for refreshing the session.\n * @param options.cookiePassword - The password to use for the new session cookie.\n * @param options.organizationId - The organization ID to use for the new session cookie.\n * @returns An object indicating whether the refresh was successful or not. If successful, it will include the new sealed session data.\n */\n async refresh(options: RefreshOptions = {}): Promise<RefreshSessionResponse> {\n const session = await unsealData<SessionCookieData>(this.sessionData, {\n password: this.cookiePassword,\n });\n\n if (!session.refreshToken || !session.user) {\n return {\n authenticated: false,\n reason: RefreshSessionFailureReason.INVALID_SESSION_COOKIE,\n };\n }\n\n const { org_id: organizationIdFromAccessToken } = decodeJwt<AccessToken>(\n session.accessToken,\n );\n\n try {\n const cookiePassword = options.cookiePassword ?? this.cookiePassword;\n\n const authenticationResponse =\n await this.userManagement.authenticateWithRefreshToken({\n clientId: this.userManagement.clientId as string,\n refreshToken: session.refreshToken,\n organizationId:\n options.organizationId ?? organizationIdFromAccessToken,\n session: {\n // We want to store the new sealed session in this class instance, so this always needs to be true\n sealSession: true,\n cookiePassword,\n },\n });\n\n // Update the password if a new one was provided\n if (options.cookiePassword) {\n this.cookiePassword = options.cookiePassword;\n }\n\n this.sessionData = authenticationResponse.sealedSession as string;\n\n const {\n sid: sessionId,\n org_id: organizationId,\n role,\n permissions,\n entitlements,\n } = decodeJwt<AccessToken>(authenticationResponse.accessToken);\n\n // TODO: Returning `session` here means there's some duplicated data.\n // Slim down the return type in a future major version.\n return {\n authenticated: true,\n sealedSession: authenticationResponse.sealedSession,\n session: authenticationResponse as AuthenticationResponse,\n sessionId,\n organizationId,\n role,\n permissions,\n entitlements,\n user: session.user,\n impersonator: session.impersonator,\n };\n } catch (error) {\n if (\n error instanceof OauthException &&\n // TODO: Add additional known errors and remove re-throw\n (error.error === RefreshSessionFailureReason.INVALID_GRANT ||\n error.error === RefreshSessionFailureReason.MFA_ENROLLMENT ||\n error.error === RefreshSessionFailureReason.SSO_REQUIRED)\n ) {\n return {\n authenticated: false,\n reason: error.error,\n };\n }\n\n throw error;\n }\n }\n\n /**\n * Gets the URL to redirect the user to for logging out.\n *\n * @returns The URL to redirect the user to for logging out.\n */\n async getLogoutUrl({\n returnTo,\n }: { returnTo?: string } = {}): Promise<string> {\n const authenticationResponse = await this.authenticate();\n\n if (!authenticationResponse.authenticated) {\n const { reason } = authenticationResponse;\n throw new Error(`Failed to extract session ID for logout URL: ${reason}`);\n }\n\n return this.userManagement.getLogoutUrl({\n sessionId: authenticationResponse.sessionId,\n returnTo,\n });\n }\n\n private async isValidJwt(accessToken: string): Promise<boolean> {\n if (!this.jwks) {\n throw new Error(\n 'Missing client ID. Did you provide it when initializing WorkOS?',\n );\n }\n\n try {\n await jwtVerify(accessToken, this.jwks);\n return true;\n } catch (e) {\n return false;\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -11,6 +11,10 @@ class Session {
|
|
|
11
11
|
static {
|
|
12
12
|
__name(this, "Session");
|
|
13
13
|
}
|
|
14
|
+
jwks;
|
|
15
|
+
userManagement;
|
|
16
|
+
cookiePassword;
|
|
17
|
+
sessionData;
|
|
14
18
|
constructor(userManagement, sessionData, cookiePassword) {
|
|
15
19
|
if (!cookiePassword) {
|
|
16
20
|
throw new Error("cookiePassword is required");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/user-management/session.ts"],"sourcesContent":["import { createRemoteJWKSet, decodeJwt, jwtVerify } from 'jose';\nimport { OauthException } from '../common/exceptions/oauth.exception';\nimport {\n AccessToken,\n AuthenticateWithSessionCookieFailedResponse,\n AuthenticateWithSessionCookieFailureReason,\n AuthenticateWithSessionCookieSuccessResponse,\n AuthenticationResponse,\n RefreshSessionFailureReason,\n RefreshSessionResponse,\n SessionCookieData,\n} from './interfaces';\nimport { UserManagement } from './user-management';\nimport { unsealData } from 'iron-session';\n\ntype RefreshOptions = {\n cookiePassword?: string;\n organizationId?: string;\n};\n\nexport class Session {\n private jwks: ReturnType<typeof createRemoteJWKSet> | undefined;\n private userManagement: UserManagement;\n private cookiePassword: string;\n private sessionData: string;\n\n constructor(\n userManagement: UserManagement,\n sessionData: string,\n cookiePassword: string,\n ) {\n if (!cookiePassword) {\n throw new Error('cookiePassword is required');\n }\n\n this.userManagement = userManagement;\n this.cookiePassword = cookiePassword;\n this.sessionData = sessionData;\n\n this.jwks = this.userManagement.jwks;\n }\n\n /**\n * Authenticates a user with a session cookie.\n *\n * @returns An object indicating whether the authentication was successful or not. If successful, it will include the user's session data.\n */\n async authenticate(): Promise<\n | AuthenticateWithSessionCookieSuccessResponse\n | AuthenticateWithSessionCookieFailedResponse\n > {\n if (!this.sessionData) {\n return {\n authenticated: false,\n reason:\n AuthenticateWithSessionCookieFailureReason.NO_SESSION_COOKIE_PROVIDED,\n };\n }\n\n let session: SessionCookieData;\n\n try {\n session = await unsealData<SessionCookieData>(this.sessionData, {\n password: this.cookiePassword,\n });\n } catch (e) {\n return {\n authenticated: false,\n reason:\n AuthenticateWithSessionCookieFailureReason.INVALID_SESSION_COOKIE,\n };\n }\n\n if (!session.accessToken) {\n return {\n authenticated: false,\n reason:\n AuthenticateWithSessionCookieFailureReason.INVALID_SESSION_COOKIE,\n };\n }\n\n if (!(await this.isValidJwt(session.accessToken))) {\n return {\n authenticated: false,\n reason: AuthenticateWithSessionCookieFailureReason.INVALID_JWT,\n };\n }\n\n const {\n sid: sessionId,\n org_id: organizationId,\n role,\n permissions,\n entitlements,\n } = decodeJwt<AccessToken>(session.accessToken);\n\n return {\n authenticated: true,\n sessionId,\n organizationId,\n role,\n permissions,\n entitlements,\n user: session.user,\n impersonator: session.impersonator,\n accessToken: session.accessToken,\n };\n }\n\n /**\n * Refreshes the user's session.\n *\n * @param options - Optional options for refreshing the session.\n * @param options.cookiePassword - The password to use for the new session cookie.\n * @param options.organizationId - The organization ID to use for the new session cookie.\n * @returns An object indicating whether the refresh was successful or not. If successful, it will include the new sealed session data.\n */\n async refresh(options: RefreshOptions = {}): Promise<RefreshSessionResponse> {\n const session = await unsealData<SessionCookieData>(this.sessionData, {\n password: this.cookiePassword,\n });\n\n if (!session.refreshToken || !session.user) {\n return {\n authenticated: false,\n reason: RefreshSessionFailureReason.INVALID_SESSION_COOKIE,\n };\n }\n\n const { org_id: organizationIdFromAccessToken } = decodeJwt<AccessToken>(\n session.accessToken,\n );\n\n try {\n const cookiePassword = options.cookiePassword ?? this.cookiePassword;\n\n const authenticationResponse =\n await this.userManagement.authenticateWithRefreshToken({\n clientId: this.userManagement.clientId as string,\n refreshToken: session.refreshToken,\n organizationId:\n options.organizationId ?? organizationIdFromAccessToken,\n session: {\n // We want to store the new sealed session in this class instance, so this always needs to be true\n sealSession: true,\n cookiePassword,\n },\n });\n\n // Update the password if a new one was provided\n if (options.cookiePassword) {\n this.cookiePassword = options.cookiePassword;\n }\n\n this.sessionData = authenticationResponse.sealedSession as string;\n\n const {\n sid: sessionId,\n org_id: organizationId,\n role,\n permissions,\n entitlements,\n } = decodeJwt<AccessToken>(authenticationResponse.accessToken);\n\n // TODO: Returning `session` here means there's some duplicated data.\n // Slim down the return type in a future major version.\n return {\n authenticated: true,\n sealedSession: authenticationResponse.sealedSession,\n session: authenticationResponse as AuthenticationResponse,\n sessionId,\n organizationId,\n role,\n permissions,\n entitlements,\n user: session.user,\n impersonator: session.impersonator,\n };\n } catch (error) {\n if (\n error instanceof OauthException &&\n // TODO: Add additional known errors and remove re-throw\n (error.error === RefreshSessionFailureReason.INVALID_GRANT ||\n error.error === RefreshSessionFailureReason.MFA_ENROLLMENT ||\n error.error === RefreshSessionFailureReason.SSO_REQUIRED)\n ) {\n return {\n authenticated: false,\n reason: error.error,\n };\n }\n\n throw error;\n }\n }\n\n /**\n * Gets the URL to redirect the user to for logging out.\n *\n * @returns The URL to redirect the user to for logging out.\n */\n async getLogoutUrl({\n returnTo,\n }: { returnTo?: string } = {}): Promise<string> {\n const authenticationResponse = await this.authenticate();\n\n if (!authenticationResponse.authenticated) {\n const { reason } = authenticationResponse;\n throw new Error(`Failed to extract session ID for logout URL: ${reason}`);\n }\n\n return this.userManagement.getLogoutUrl({\n sessionId: authenticationResponse.sessionId,\n returnTo,\n });\n }\n\n private async isValidJwt(accessToken: string): Promise<boolean> {\n if (!this.jwks) {\n throw new Error(\n 'Missing client ID. Did you provide it when initializing WorkOS?',\n );\n }\n\n try {\n await jwtVerify(accessToken, this.jwks);\n return true;\n } catch (e) {\n return false;\n }\n }\n}\n"],"mappings":";;AAAA,SAA6B,WAAW,iBAAiB;AACzD,SAAS,sBAAsB;AAC/B;AAAA,EAGE;AAAA,EAGA;AAAA,OAGK;AAEP,SAAS,kBAAkB;AAOpB,MAAM,QAAQ;AAAA,EApBrB,OAoBqB;AAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"sources":["../../src/user-management/session.ts"],"sourcesContent":["import { createRemoteJWKSet, decodeJwt, jwtVerify } from 'jose';\nimport { OauthException } from '../common/exceptions/oauth.exception';\nimport {\n AccessToken,\n AuthenticateWithSessionCookieFailedResponse,\n AuthenticateWithSessionCookieFailureReason,\n AuthenticateWithSessionCookieSuccessResponse,\n AuthenticationResponse,\n RefreshSessionFailureReason,\n RefreshSessionResponse,\n SessionCookieData,\n} from './interfaces';\nimport { UserManagement } from './user-management';\nimport { unsealData } from 'iron-session';\n\ntype RefreshOptions = {\n cookiePassword?: string;\n organizationId?: string;\n};\n\nexport class Session {\n private jwks: ReturnType<typeof createRemoteJWKSet> | undefined;\n private userManagement: UserManagement;\n private cookiePassword: string;\n private sessionData: string;\n\n constructor(\n userManagement: UserManagement,\n sessionData: string,\n cookiePassword: string,\n ) {\n if (!cookiePassword) {\n throw new Error('cookiePassword is required');\n }\n\n this.userManagement = userManagement;\n this.cookiePassword = cookiePassword;\n this.sessionData = sessionData;\n\n this.jwks = this.userManagement.jwks;\n }\n\n /**\n * Authenticates a user with a session cookie.\n *\n * @returns An object indicating whether the authentication was successful or not. If successful, it will include the user's session data.\n */\n async authenticate(): Promise<\n | AuthenticateWithSessionCookieSuccessResponse\n | AuthenticateWithSessionCookieFailedResponse\n > {\n if (!this.sessionData) {\n return {\n authenticated: false,\n reason:\n AuthenticateWithSessionCookieFailureReason.NO_SESSION_COOKIE_PROVIDED,\n };\n }\n\n let session: SessionCookieData;\n\n try {\n session = await unsealData<SessionCookieData>(this.sessionData, {\n password: this.cookiePassword,\n });\n } catch (e) {\n return {\n authenticated: false,\n reason:\n AuthenticateWithSessionCookieFailureReason.INVALID_SESSION_COOKIE,\n };\n }\n\n if (!session.accessToken) {\n return {\n authenticated: false,\n reason:\n AuthenticateWithSessionCookieFailureReason.INVALID_SESSION_COOKIE,\n };\n }\n\n if (!(await this.isValidJwt(session.accessToken))) {\n return {\n authenticated: false,\n reason: AuthenticateWithSessionCookieFailureReason.INVALID_JWT,\n };\n }\n\n const {\n sid: sessionId,\n org_id: organizationId,\n role,\n permissions,\n entitlements,\n } = decodeJwt<AccessToken>(session.accessToken);\n\n return {\n authenticated: true,\n sessionId,\n organizationId,\n role,\n permissions,\n entitlements,\n user: session.user,\n impersonator: session.impersonator,\n accessToken: session.accessToken,\n };\n }\n\n /**\n * Refreshes the user's session.\n *\n * @param options - Optional options for refreshing the session.\n * @param options.cookiePassword - The password to use for the new session cookie.\n * @param options.organizationId - The organization ID to use for the new session cookie.\n * @returns An object indicating whether the refresh was successful or not. If successful, it will include the new sealed session data.\n */\n async refresh(options: RefreshOptions = {}): Promise<RefreshSessionResponse> {\n const session = await unsealData<SessionCookieData>(this.sessionData, {\n password: this.cookiePassword,\n });\n\n if (!session.refreshToken || !session.user) {\n return {\n authenticated: false,\n reason: RefreshSessionFailureReason.INVALID_SESSION_COOKIE,\n };\n }\n\n const { org_id: organizationIdFromAccessToken } = decodeJwt<AccessToken>(\n session.accessToken,\n );\n\n try {\n const cookiePassword = options.cookiePassword ?? this.cookiePassword;\n\n const authenticationResponse =\n await this.userManagement.authenticateWithRefreshToken({\n clientId: this.userManagement.clientId as string,\n refreshToken: session.refreshToken,\n organizationId:\n options.organizationId ?? organizationIdFromAccessToken,\n session: {\n // We want to store the new sealed session in this class instance, so this always needs to be true\n sealSession: true,\n cookiePassword,\n },\n });\n\n // Update the password if a new one was provided\n if (options.cookiePassword) {\n this.cookiePassword = options.cookiePassword;\n }\n\n this.sessionData = authenticationResponse.sealedSession as string;\n\n const {\n sid: sessionId,\n org_id: organizationId,\n role,\n permissions,\n entitlements,\n } = decodeJwt<AccessToken>(authenticationResponse.accessToken);\n\n // TODO: Returning `session` here means there's some duplicated data.\n // Slim down the return type in a future major version.\n return {\n authenticated: true,\n sealedSession: authenticationResponse.sealedSession,\n session: authenticationResponse as AuthenticationResponse,\n sessionId,\n organizationId,\n role,\n permissions,\n entitlements,\n user: session.user,\n impersonator: session.impersonator,\n };\n } catch (error) {\n if (\n error instanceof OauthException &&\n // TODO: Add additional known errors and remove re-throw\n (error.error === RefreshSessionFailureReason.INVALID_GRANT ||\n error.error === RefreshSessionFailureReason.MFA_ENROLLMENT ||\n error.error === RefreshSessionFailureReason.SSO_REQUIRED)\n ) {\n return {\n authenticated: false,\n reason: error.error,\n };\n }\n\n throw error;\n }\n }\n\n /**\n * Gets the URL to redirect the user to for logging out.\n *\n * @returns The URL to redirect the user to for logging out.\n */\n async getLogoutUrl({\n returnTo,\n }: { returnTo?: string } = {}): Promise<string> {\n const authenticationResponse = await this.authenticate();\n\n if (!authenticationResponse.authenticated) {\n const { reason } = authenticationResponse;\n throw new Error(`Failed to extract session ID for logout URL: ${reason}`);\n }\n\n return this.userManagement.getLogoutUrl({\n sessionId: authenticationResponse.sessionId,\n returnTo,\n });\n }\n\n private async isValidJwt(accessToken: string): Promise<boolean> {\n if (!this.jwks) {\n throw new Error(\n 'Missing client ID. Did you provide it when initializing WorkOS?',\n );\n }\n\n try {\n await jwtVerify(accessToken, this.jwks);\n return true;\n } catch (e) {\n return false;\n }\n }\n}\n"],"mappings":"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","names":[]}
|