cabalspy-id 0.5.1 → 0.5.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/CHANGELOG.md +146 -112
- package/LICENSE +21 -21
- package/README.md +505 -475
- package/dist/api.cjs +5 -3
- package/dist/api.cjs.map +1 -1
- package/dist/api.d.cts +1 -1
- package/dist/api.d.ts +1 -1
- package/dist/api.js +16 -14
- package/dist/chunk-A2ZAFAWC.cjs.map +1 -1
- package/dist/chunk-ABFIPCBY.cjs +109 -0
- package/dist/chunk-ABFIPCBY.cjs.map +1 -0
- package/dist/{chunk-Z3UPDOBY.js → chunk-DBYCRBVS.js} +9 -7
- package/dist/chunk-DBYCRBVS.js.map +1 -0
- package/dist/{chunk-P3MDLWLN.cjs → chunk-PKFIMBPW.cjs} +113 -54
- package/dist/chunk-PKFIMBPW.cjs.map +1 -0
- package/dist/{chunk-L4RHSWOA.cjs → chunk-ULEBNY2A.cjs} +121 -212
- package/dist/chunk-ULEBNY2A.cjs.map +1 -0
- package/dist/{chunk-X3OFGGSE.cjs → chunk-VDFCMYLR.cjs} +50 -48
- package/dist/chunk-VDFCMYLR.cjs.map +1 -0
- package/dist/chunk-VOTYIQAY.js +109 -0
- package/dist/chunk-VOTYIQAY.js.map +1 -0
- package/dist/{chunk-3LKLY5WQ.js → chunk-XLBO2RSL.js} +15 -106
- package/dist/chunk-XLBO2RSL.js.map +1 -0
- package/dist/{chunk-3P7QK2PG.js → chunk-Z23B5TY6.js} +89 -30
- package/dist/chunk-Z23B5TY6.js.map +1 -0
- package/dist/index.cjs +13 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +25 -17
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +55 -2
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +28 -5
- package/dist/react.d.ts +28 -5
- package/dist/react.js +55 -2
- package/dist/react.js.map +1 -1
- package/dist/thesis.cjs +11 -3
- package/dist/thesis.cjs.map +1 -1
- package/dist/thesis.d.cts +42 -11
- package/dist/thesis.d.ts +42 -11
- package/dist/thesis.js +24 -16
- package/dist/{users-BDLkwW1p.d.cts → users-3DAw88_U.d.cts} +4 -4
- package/dist/{users-CDlDRuyv.d.ts → users-B4r33i4O.d.ts} +4 -4
- package/dist/widget.cjs +28 -12
- package/dist/widget.cjs.map +1 -1
- package/dist/widget.d.cts +37 -6
- package/dist/widget.d.ts +37 -6
- package/dist/widget.js +17 -1
- package/dist/widget.js.map +1 -1
- package/package.json +147 -147
- package/dist/chunk-3LKLY5WQ.js.map +0 -1
- package/dist/chunk-3P7QK2PG.js.map +0 -1
- package/dist/chunk-L4RHSWOA.cjs.map +0 -1
- package/dist/chunk-P3MDLWLN.cjs.map +0 -1
- package/dist/chunk-X3OFGGSE.cjs.map +0 -1
- package/dist/chunk-Z3UPDOBY.js.map +0 -1
package/dist/api.cjs
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
var
|
|
8
|
+
var _chunkVDFCMYLRcjs = require('./chunk-VDFCMYLR.cjs');
|
|
9
9
|
require('./chunk-A2ZAFAWC.cjs');
|
|
10
10
|
|
|
11
11
|
|
|
@@ -21,6 +21,7 @@ require('./chunk-A2ZAFAWC.cjs');
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
|
|
24
|
+
var _chunkULEBNY2Acjs = require('./chunk-ULEBNY2A.cjs');
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
|
|
@@ -34,8 +35,8 @@ require('./chunk-A2ZAFAWC.cjs');
|
|
|
34
35
|
|
|
35
36
|
|
|
36
37
|
|
|
37
|
-
var _chunkL4RHSWOAcjs = require('./chunk-L4RHSWOA.cjs');
|
|
38
38
|
|
|
39
|
+
var _chunkABFIPCBYcjs = require('./chunk-ABFIPCBY.cjs');
|
|
39
40
|
|
|
40
41
|
|
|
41
42
|
|
|
@@ -68,5 +69,6 @@ var _chunkL4RHSWOAcjs = require('./chunk-L4RHSWOA.cjs');
|
|
|
68
69
|
|
|
69
70
|
|
|
70
71
|
|
|
71
|
-
|
|
72
|
+
|
|
73
|
+
exports.AuthenticationError = _chunkABFIPCBYcjs.AuthenticationError; exports.BadRequestError = _chunkABFIPCBYcjs.BadRequestError; exports.CHAINS = _chunkULEBNY2Acjs.CHAINS; exports.CURRENCY_BY_CHAIN = _chunkULEBNY2Acjs.CURRENCY_BY_CHAIN; exports.CabalSpyID = _chunkULEBNY2Acjs.CabalSpyID; exports.CabalSpyIDAuth = _chunkVDFCMYLRcjs.CabalSpyIDAuth; exports.CabalSpyIDError = _chunkABFIPCBYcjs.CabalSpyIDError; exports.CabalSpyIDStream = _chunkULEBNY2Acjs.CabalSpyIDStream; exports.ConnectionError = _chunkABFIPCBYcjs.ConnectionError; exports.DEFAULT_BASE_URL = _chunkULEBNY2Acjs.DEFAULT_BASE_URL; exports.DEFAULT_ISSUER = _chunkVDFCMYLRcjs.DEFAULT_ISSUER; exports.DEFAULT_STREAM_URL = _chunkULEBNY2Acjs.DEFAULT_STREAM_URL; exports.InvalidResponseError = _chunkABFIPCBYcjs.InvalidResponseError; exports.JwksCache = _chunkVDFCMYLRcjs.JwksCache; exports.LEADERBOARD_SORTS = _chunkULEBNY2Acjs.LEADERBOARD_SORTS; exports.NotFoundError = _chunkABFIPCBYcjs.NotFoundError; exports.OAuthError = _chunkABFIPCBYcjs.OAuthError; exports.PERIODS = _chunkULEBNY2Acjs.PERIODS; exports.PermissionError = _chunkABFIPCBYcjs.PermissionError; exports.PlanUserLimitError = _chunkABFIPCBYcjs.PlanUserLimitError; exports.RateLimitError = _chunkABFIPCBYcjs.RateLimitError; exports.SDK_VERSION = _chunkULEBNY2Acjs.SDK_VERSION; exports.ServerError = _chunkABFIPCBYcjs.ServerError; exports.TokenVerificationError = _chunkABFIPCBYcjs.TokenVerificationError; exports.WebhookVerificationError = _chunkABFIPCBYcjs.WebhookVerificationError; exports.decodeJwt = _chunkVDFCMYLRcjs.decodeJwt; exports.generatePkce = _chunkVDFCMYLRcjs.generatePkce; exports.handleKind = _chunkULEBNY2Acjs.handleKind; exports.hasX = _chunkULEBNY2Acjs.hasX; exports.isLimited = _chunkVDFCMYLRcjs.isLimited; exports.signWebhook = _chunkULEBNY2Acjs.signWebhook; exports.verifyWebhook = _chunkULEBNY2Acjs.verifyWebhook;
|
|
72
74
|
//# sourceMappingURL=api.cjs.map
|
package/dist/api.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/cabalspy-id-js/cabalspy-id-js/dist/api.cjs"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B,gCAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,m0DAAC","file":"/home/runner/work/cabalspy-id-js/cabalspy-id-js/dist/api.cjs"}
|
package/dist/api.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as ApiErrorBody, a as AuthenticationError, B as BadRequestError, C as CabalSpyID, b as CabalSpyIDError, c as CabalSpyIDErrorOptions, d as CabalSpyIDOptions, e as CabalSpyIDStream, f as CloseEvent, g as ConnectionError, D as DEFAULT_BASE_URL, h as DEFAULT_STREAM_URL, E as Envelope, H as HandleKind, k as HeaderSource, l as HeartbeatEvent, m as HistoryParams, I as InvalidResponseError, n as LatestTransactionsParams, o as LeaderboardParams, N as NotFoundError, O as OAuthError, P as PermissionError, q as PlanUserLimitError, s as ProfileParams, Q as Query, R as RateLimitError, t as RateLimitInfo, v as ReconnectEvent, S as SDK_VERSION, y as ScopedParams, z as ServerError, F as StreamEvent, G as StreamEventMap, J as StreamOptions, K as StreamTopic, T as SubscribedEvent, a3 as TokenVerificationError, a4 as TrackerParams, a5 as UserLike, a7 as UsersParams, a8 as VerifyWebhookOptions, a9 as WalletParams, aa as WebhookVerificationError, ab as handleKind, ac as hasX, ad as signWebhook, ae as verifyWebhook } from './users-
|
|
1
|
+
export { A as ApiErrorBody, a as AuthenticationError, B as BadRequestError, C as CabalSpyID, b as CabalSpyIDError, c as CabalSpyIDErrorOptions, d as CabalSpyIDOptions, e as CabalSpyIDStream, f as CloseEvent, g as ConnectionError, D as DEFAULT_BASE_URL, h as DEFAULT_STREAM_URL, E as Envelope, H as HandleKind, k as HeaderSource, l as HeartbeatEvent, m as HistoryParams, I as InvalidResponseError, n as LatestTransactionsParams, o as LeaderboardParams, N as NotFoundError, O as OAuthError, P as PermissionError, q as PlanUserLimitError, s as ProfileParams, Q as Query, R as RateLimitError, t as RateLimitInfo, v as ReconnectEvent, S as SDK_VERSION, y as ScopedParams, z as ServerError, F as StreamEvent, G as StreamEventMap, J as StreamOptions, K as StreamTopic, T as SubscribedEvent, a3 as TokenVerificationError, a4 as TrackerParams, a5 as UserLike, a7 as UsersParams, a8 as VerifyWebhookOptions, a9 as WalletParams, aa as WebhookVerificationError, ab as handleKind, ac as hasX, ad as signWebhook, ae as verifyWebhook } from './users-3DAw88_U.cjs';
|
|
2
2
|
import { O as OidcScope, D as DiscoveryDocument, a8 as TokenResponse, c as CabalSpyIDClaims } from './types-UZeY9n1e.cjs';
|
|
3
3
|
export { A as ActiveTokens, a as ApiResponse, C as CHAINS, b as CURRENCY_BY_CHAIN, d as Chain, e as Currency, H as HealthResponse, f as HistoryResponse, g as HistoryToken, h as HistoryTrade, i as HoldingToken, j as HoldingsResponse, L as LEADERBOARD_SORTS, k as LeaderboardEntry, l as LeaderboardResponse, m as LeaderboardSort, n as LifetimeStats, M as MeResponse, P as PERIODS, o as Pagination, p as Period, q as PeriodStats, r as PnlCalendarDay, s as PnlCalendarMonth, t as PnlCalendarResponse, u as PnlChartPoint, v as Profile, R as ResponseMeta, S as Scope, a7 as TokenOverview, a9 as TrackerResponse, aa as TrackerTrade, ab as Trade, ac as TradeOwner, ad as TraderProfile, ae as VerifiedWallet, af as WalletClaim, ag as WalletLookupResponse, ah as WebhookEvent, ai as WebhookEventType, aj as WinRateBuckets, ak as WinRateDistribution, al as XProfileClaim } from './types-UZeY9n1e.cjs';
|
|
4
4
|
|
package/dist/api.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as ApiErrorBody, a as AuthenticationError, B as BadRequestError, C as CabalSpyID, b as CabalSpyIDError, c as CabalSpyIDErrorOptions, d as CabalSpyIDOptions, e as CabalSpyIDStream, f as CloseEvent, g as ConnectionError, D as DEFAULT_BASE_URL, h as DEFAULT_STREAM_URL, E as Envelope, H as HandleKind, k as HeaderSource, l as HeartbeatEvent, m as HistoryParams, I as InvalidResponseError, n as LatestTransactionsParams, o as LeaderboardParams, N as NotFoundError, O as OAuthError, P as PermissionError, q as PlanUserLimitError, s as ProfileParams, Q as Query, R as RateLimitError, t as RateLimitInfo, v as ReconnectEvent, S as SDK_VERSION, y as ScopedParams, z as ServerError, F as StreamEvent, G as StreamEventMap, J as StreamOptions, K as StreamTopic, T as SubscribedEvent, a3 as TokenVerificationError, a4 as TrackerParams, a5 as UserLike, a7 as UsersParams, a8 as VerifyWebhookOptions, a9 as WalletParams, aa as WebhookVerificationError, ab as handleKind, ac as hasX, ad as signWebhook, ae as verifyWebhook } from './users-
|
|
1
|
+
export { A as ApiErrorBody, a as AuthenticationError, B as BadRequestError, C as CabalSpyID, b as CabalSpyIDError, c as CabalSpyIDErrorOptions, d as CabalSpyIDOptions, e as CabalSpyIDStream, f as CloseEvent, g as ConnectionError, D as DEFAULT_BASE_URL, h as DEFAULT_STREAM_URL, E as Envelope, H as HandleKind, k as HeaderSource, l as HeartbeatEvent, m as HistoryParams, I as InvalidResponseError, n as LatestTransactionsParams, o as LeaderboardParams, N as NotFoundError, O as OAuthError, P as PermissionError, q as PlanUserLimitError, s as ProfileParams, Q as Query, R as RateLimitError, t as RateLimitInfo, v as ReconnectEvent, S as SDK_VERSION, y as ScopedParams, z as ServerError, F as StreamEvent, G as StreamEventMap, J as StreamOptions, K as StreamTopic, T as SubscribedEvent, a3 as TokenVerificationError, a4 as TrackerParams, a5 as UserLike, a7 as UsersParams, a8 as VerifyWebhookOptions, a9 as WalletParams, aa as WebhookVerificationError, ab as handleKind, ac as hasX, ad as signWebhook, ae as verifyWebhook } from './users-B4r33i4O.js';
|
|
2
2
|
import { O as OidcScope, D as DiscoveryDocument, a8 as TokenResponse, c as CabalSpyIDClaims } from './types-UZeY9n1e.js';
|
|
3
3
|
export { A as ActiveTokens, a as ApiResponse, C as CHAINS, b as CURRENCY_BY_CHAIN, d as Chain, e as Currency, H as HealthResponse, f as HistoryResponse, g as HistoryToken, h as HistoryTrade, i as HoldingToken, j as HoldingsResponse, L as LEADERBOARD_SORTS, k as LeaderboardEntry, l as LeaderboardResponse, m as LeaderboardSort, n as LifetimeStats, M as MeResponse, P as PERIODS, o as Pagination, p as Period, q as PeriodStats, r as PnlCalendarDay, s as PnlCalendarMonth, t as PnlCalendarResponse, u as PnlChartPoint, v as Profile, R as ResponseMeta, S as Scope, a7 as TokenOverview, a9 as TrackerResponse, aa as TrackerTrade, ab as Trade, ac as TradeOwner, ad as TraderProfile, ae as VerifiedWallet, af as WalletClaim, ag as WalletLookupResponse, ah as WebhookEvent, ai as WebhookEventType, aj as WinRateBuckets, ak as WinRateDistribution, al as XProfileClaim } from './types-UZeY9n1e.js';
|
|
4
4
|
|
package/dist/api.js
CHANGED
|
@@ -5,36 +5,38 @@ import {
|
|
|
5
5
|
decodeJwt,
|
|
6
6
|
generatePkce,
|
|
7
7
|
isLimited
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-DBYCRBVS.js";
|
|
9
9
|
import "./chunk-CJFIOVBA.js";
|
|
10
10
|
import {
|
|
11
|
-
AuthenticationError,
|
|
12
|
-
BadRequestError,
|
|
13
11
|
CHAINS,
|
|
14
12
|
CURRENCY_BY_CHAIN,
|
|
15
13
|
CabalSpyID,
|
|
16
|
-
CabalSpyIDError,
|
|
17
14
|
CabalSpyIDStream,
|
|
18
|
-
ConnectionError,
|
|
19
15
|
DEFAULT_BASE_URL,
|
|
20
16
|
DEFAULT_STREAM_URL,
|
|
21
|
-
InvalidResponseError,
|
|
22
17
|
LEADERBOARD_SORTS,
|
|
18
|
+
PERIODS,
|
|
19
|
+
SDK_VERSION,
|
|
20
|
+
handleKind,
|
|
21
|
+
hasX,
|
|
22
|
+
signWebhook,
|
|
23
|
+
verifyWebhook
|
|
24
|
+
} from "./chunk-XLBO2RSL.js";
|
|
25
|
+
import {
|
|
26
|
+
AuthenticationError,
|
|
27
|
+
BadRequestError,
|
|
28
|
+
CabalSpyIDError,
|
|
29
|
+
ConnectionError,
|
|
30
|
+
InvalidResponseError,
|
|
23
31
|
NotFoundError,
|
|
24
32
|
OAuthError,
|
|
25
|
-
PERIODS,
|
|
26
33
|
PermissionError,
|
|
27
34
|
PlanUserLimitError,
|
|
28
35
|
RateLimitError,
|
|
29
|
-
SDK_VERSION,
|
|
30
36
|
ServerError,
|
|
31
37
|
TokenVerificationError,
|
|
32
|
-
WebhookVerificationError
|
|
33
|
-
|
|
34
|
-
hasX,
|
|
35
|
-
signWebhook,
|
|
36
|
-
verifyWebhook
|
|
37
|
-
} from "./chunk-3LKLY5WQ.js";
|
|
38
|
+
WebhookVerificationError
|
|
39
|
+
} from "./chunk-VOTYIQAY.js";
|
|
38
40
|
export {
|
|
39
41
|
AuthenticationError,
|
|
40
42
|
BadRequestError,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/cabalspy-id-js/cabalspy-id-js/dist/chunk-A2ZAFAWC.cjs"],"names":[],"mappings":"AAAA","file":"/home/runner/work/cabalspy-id-js/cabalspy-id-js/dist/chunk-A2ZAFAWC.cjs"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class;// src/errors.ts
|
|
2
|
+
var EMPTY_RATE_LIMIT = Object.freeze({ limit: null, remaining: null, reset: null });
|
|
3
|
+
var CabalSpyIDError = class extends Error {
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
/** The parsed response body, when there was one. */
|
|
12
|
+
|
|
13
|
+
constructor(message, opts = {}) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = new.target.name;
|
|
16
|
+
this.status = _nullishCoalesce(opts.status, () => ( 0));
|
|
17
|
+
this.code = _nullishCoalesce(opts.code, () => ( "unknown_error"));
|
|
18
|
+
this.requestId = opts.requestId;
|
|
19
|
+
this.docs = opts.docs;
|
|
20
|
+
this.parameter = opts.parameter;
|
|
21
|
+
this.allowed = opts.allowed;
|
|
22
|
+
this.rateLimit = _nullishCoalesce(opts.rateLimit, () => ( { ...EMPTY_RATE_LIMIT }));
|
|
23
|
+
this.body = opts.body;
|
|
24
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
var BadRequestError = class extends CabalSpyIDError {
|
|
28
|
+
};
|
|
29
|
+
var AuthenticationError = class extends CabalSpyIDError {
|
|
30
|
+
};
|
|
31
|
+
var PermissionError = class extends CabalSpyIDError {
|
|
32
|
+
};
|
|
33
|
+
var PlanUserLimitError = (_class = class extends PermissionError {constructor(...args) { super(...args); _class.prototype.__init.call(this); }
|
|
34
|
+
__init() {this.limited = true}
|
|
35
|
+
}, _class);
|
|
36
|
+
var NotFoundError = class extends CabalSpyIDError {
|
|
37
|
+
};
|
|
38
|
+
var RateLimitError = class extends CabalSpyIDError {
|
|
39
|
+
/** Seconds until the next request is allowed, taken from Retry-After. */
|
|
40
|
+
|
|
41
|
+
constructor(message, opts = {}) {
|
|
42
|
+
super(message, opts);
|
|
43
|
+
this.retryAfter = _nullishCoalesce(opts.retryAfter, () => ( null));
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
var ServerError = class extends CabalSpyIDError {
|
|
47
|
+
};
|
|
48
|
+
var ConnectionError = class extends CabalSpyIDError {
|
|
49
|
+
};
|
|
50
|
+
var InvalidResponseError = class extends CabalSpyIDError {
|
|
51
|
+
};
|
|
52
|
+
var OAuthError = class extends CabalSpyIDError {
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
constructor(error, description, opts = {}) {
|
|
56
|
+
super(description ? `${error}: ${description}` : error, { ...opts, code: error });
|
|
57
|
+
this.error = error;
|
|
58
|
+
this.errorDescription = description;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
var TokenVerificationError = class extends CabalSpyIDError {
|
|
62
|
+
};
|
|
63
|
+
var WebhookVerificationError = class extends CabalSpyIDError {
|
|
64
|
+
};
|
|
65
|
+
function errorFromStatus(status, body, rateLimit, retryAfter, fallbackMessage) {
|
|
66
|
+
const opts = {
|
|
67
|
+
status,
|
|
68
|
+
code: _nullishCoalesce(_optionalChain([body, 'optionalAccess', _ => _.code]), () => ( `http_${status}`)),
|
|
69
|
+
requestId: _optionalChain([body, 'optionalAccess', _2 => _2.request_id]),
|
|
70
|
+
docs: _optionalChain([body, 'optionalAccess', _3 => _3.docs]),
|
|
71
|
+
parameter: _optionalChain([body, 'optionalAccess', _4 => _4.parameter]),
|
|
72
|
+
allowed: _optionalChain([body, 'optionalAccess', _5 => _5.allowed]),
|
|
73
|
+
rateLimit,
|
|
74
|
+
body: _nullishCoalesce(body, () => ( void 0))
|
|
75
|
+
};
|
|
76
|
+
const msg = _nullishCoalesce(_optionalChain([body, 'optionalAccess', _6 => _6.message]), () => ( fallbackMessage));
|
|
77
|
+
if (status === 400) return new BadRequestError(msg, opts);
|
|
78
|
+
if (status === 401) return new AuthenticationError(msg, opts);
|
|
79
|
+
if (status === 403) {
|
|
80
|
+
return _optionalChain([body, 'optionalAccess', _7 => _7.code]) === "plan_user_limit" ? new PlanUserLimitError(msg, opts) : new PermissionError(msg, opts);
|
|
81
|
+
}
|
|
82
|
+
if (status === 404) return new NotFoundError(msg, opts);
|
|
83
|
+
if (status === 429) return new RateLimitError(msg, { ...opts, retryAfter });
|
|
84
|
+
if (status >= 500) return new ServerError(msg, opts);
|
|
85
|
+
return new CabalSpyIDError(msg, opts);
|
|
86
|
+
}
|
|
87
|
+
function isRetryable(err) {
|
|
88
|
+
return err instanceof RateLimitError || err instanceof ServerError || err instanceof ConnectionError;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
exports.EMPTY_RATE_LIMIT = EMPTY_RATE_LIMIT; exports.CabalSpyIDError = CabalSpyIDError; exports.BadRequestError = BadRequestError; exports.AuthenticationError = AuthenticationError; exports.PermissionError = PermissionError; exports.PlanUserLimitError = PlanUserLimitError; exports.NotFoundError = NotFoundError; exports.RateLimitError = RateLimitError; exports.ServerError = ServerError; exports.ConnectionError = ConnectionError; exports.InvalidResponseError = InvalidResponseError; exports.OAuthError = OAuthError; exports.TokenVerificationError = TokenVerificationError; exports.WebhookVerificationError = WebhookVerificationError; exports.errorFromStatus = errorFromStatus; exports.isRetryable = isRetryable;
|
|
109
|
+
//# sourceMappingURL=chunk-ABFIPCBY.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/cabalspy-id-js/cabalspy-id-js/dist/chunk-ABFIPCBY.cjs","../src/errors.ts"],"names":[],"mappings":"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","file":"/home/runner/work/cabalspy-id-js/cabalspy-id-js/dist/chunk-ABFIPCBY.cjs","sourcesContent":[null,"// ═══════════════════════════════════════════════════════════════════════════\n// ERRORS\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport interface RateLimitInfo {\n /** Requests per second allowed by the plan. `null` when the header is absent. */\n limit: number | null;\n remaining: number | null;\n /** Seconds until the current one-second window resets. */\n reset: number | null;\n}\n\nexport const EMPTY_RATE_LIMIT: RateLimitInfo = Object.freeze({ limit: null, remaining: null, reset: null });\n\n/** Error body of the Data API: `{\"success\": false, \"error\": {...}}`. */\nexport interface ApiErrorBody {\n code: string;\n message: string;\n request_id: string;\n /** Link to the error's documentation, e.g. https://docs.cabalspy.xyz/cabalspy-id/errors#wallet_not_found */\n docs: string;\n parameter?: string;\n allowed?: unknown[];\n /** Set on `plan_user_limit`. */\n limited?: boolean;\n [key: string]: unknown;\n}\n\nexport interface CabalSpyIDErrorOptions {\n status?: number;\n code?: string;\n requestId?: string;\n docs?: string;\n parameter?: string;\n allowed?: unknown[];\n rateLimit?: RateLimitInfo;\n body?: unknown;\n}\n\n/** Base class for every error thrown by this SDK. */\nexport class CabalSpyIDError extends Error {\n readonly status: number;\n readonly code: string;\n readonly requestId?: string;\n readonly docs?: string;\n readonly parameter?: string;\n readonly allowed?: unknown[];\n readonly rateLimit: RateLimitInfo;\n /** The parsed response body, when there was one. */\n readonly body?: unknown;\n\n constructor(message: string, opts: CabalSpyIDErrorOptions = {}) {\n super(message);\n this.name = new.target.name;\n this.status = opts.status ?? 0;\n this.code = opts.code ?? 'unknown_error';\n this.requestId = opts.requestId;\n this.docs = opts.docs;\n this.parameter = opts.parameter;\n this.allowed = opts.allowed;\n this.rateLimit = opts.rateLimit ?? { ...EMPTY_RATE_LIMIT };\n this.body = opts.body;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** 400 — missing_parameter, invalid_parameter, instance_required */\nexport class BadRequestError extends CabalSpyIDError {}\n/** 401 — missing_api_key; thesis API: client_id_required, invalid_client */\nexport class AuthenticationError extends CabalSpyIDError {}\n/** 403 — invalid_api_key, product_not_enabled, no_instance, scope_not_allowed; thesis API: origin_not_allowed */\nexport class PermissionError extends CabalSpyIDError {}\n/**\n * 403 — plan_user_limit. The person signed in beyond the plan's user limit:\n * the platform receives no data for them until it upgrades.\n */\nexport class PlanUserLimitError extends PermissionError {\n readonly limited = true as const;\n}\n/** 404 — profile_not_found, wallet_not_found, instance_not_found */\nexport class NotFoundError extends CabalSpyIDError {}\n/** 429 — rate_limit_exceeded; thesis API: rate_limited (Retry-After 60) */\nexport class RateLimitError extends CabalSpyIDError {\n /** Seconds until the next request is allowed, taken from Retry-After. */\n readonly retryAfter: number | null;\n constructor(message: string, opts: CabalSpyIDErrorOptions & { retryAfter?: number | null } = {}) {\n super(message, opts);\n this.retryAfter = opts.retryAfter ?? null;\n }\n}\n/** 5xx — internal_error, service_unavailable */\nexport class ServerError extends CabalSpyIDError {}\n/** Network failure, timeout or aborted connection. */\nexport class ConnectionError extends CabalSpyIDError {}\n/** Response was not valid JSON, or did not have the expected envelope. */\nexport class InvalidResponseError extends CabalSpyIDError {}\n\n/**\n * An error from the OpenID Connect endpoints (`/oauth/token`, `/oauth/userinfo`,\n * `/oauth/revoke`) or from the authorization redirect, in OAuth's own format:\n * `code` is the OAuth `error` (invalid_grant, invalid_client, access_denied …).\n */\nexport class OAuthError extends CabalSpyIDError {\n readonly error: string;\n readonly errorDescription?: string;\n constructor(error: string, description?: string, opts: CabalSpyIDErrorOptions = {}) {\n super(description ? `${error}: ${description}` : error, { ...opts, code: error });\n this.error = error;\n this.errorDescription = description;\n }\n}\n\n/** An ID or access token failed verification (signature, iss, aud, exp, nonce …). */\nexport class TokenVerificationError extends CabalSpyIDError {}\n\n/** A webhook failed signature or timestamp verification. */\nexport class WebhookVerificationError extends CabalSpyIDError {}\n\n/** Maps an HTTP status and Data API error body onto the right error class. */\nexport function errorFromStatus(\n status: number,\n body: ApiErrorBody | null,\n rateLimit: RateLimitInfo,\n retryAfter: number | null,\n fallbackMessage: string,\n): CabalSpyIDError {\n const opts: CabalSpyIDErrorOptions = {\n status,\n code: body?.code ?? `http_${status}`,\n requestId: body?.request_id,\n docs: body?.docs,\n parameter: body?.parameter,\n allowed: body?.allowed,\n rateLimit,\n body: body ?? undefined,\n };\n const msg = body?.message ?? fallbackMessage;\n\n if (status === 400) return new BadRequestError(msg, opts);\n if (status === 401) return new AuthenticationError(msg, opts);\n if (status === 403) {\n return body?.code === 'plan_user_limit' ? new PlanUserLimitError(msg, opts) : new PermissionError(msg, opts);\n }\n if (status === 404) return new NotFoundError(msg, opts);\n if (status === 429) return new RateLimitError(msg, { ...opts, retryAfter });\n if (status >= 500) return new ServerError(msg, opts);\n return new CabalSpyIDError(msg, opts);\n}\n\nexport function isRetryable(err: unknown): boolean {\n return err instanceof RateLimitError || err instanceof ServerError || err instanceof ConnectionError;\n}\n"]}
|
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
CabalSpyIDError,
|
|
3
|
-
ConnectionError,
|
|
4
|
-
InvalidResponseError,
|
|
5
|
-
OAuthError,
|
|
6
|
-
TokenVerificationError,
|
|
7
2
|
USER_AGENT,
|
|
8
3
|
base64UrlDecode,
|
|
9
4
|
env,
|
|
@@ -13,7 +8,14 @@ import {
|
|
|
13
8
|
sha256Base64Url,
|
|
14
9
|
timingSafeEqual,
|
|
15
10
|
utf8
|
|
16
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-XLBO2RSL.js";
|
|
12
|
+
import {
|
|
13
|
+
CabalSpyIDError,
|
|
14
|
+
ConnectionError,
|
|
15
|
+
InvalidResponseError,
|
|
16
|
+
OAuthError,
|
|
17
|
+
TokenVerificationError
|
|
18
|
+
} from "./chunk-VOTYIQAY.js";
|
|
17
19
|
|
|
18
20
|
// src/jwt.ts
|
|
19
21
|
function decodeJwt(token) {
|
|
@@ -395,4 +397,4 @@ export {
|
|
|
395
397
|
isLimited,
|
|
396
398
|
CabalSpyIDAuth
|
|
397
399
|
};
|
|
398
|
-
//# sourceMappingURL=chunk-
|
|
400
|
+
//# sourceMappingURL=chunk-DBYCRBVS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/jwt.ts","../src/oidc.ts"],"sourcesContent":["/** ES256 JWT verification against a JWKS, with WebCrypto only (no dependencies). */\n\nimport { TokenVerificationError } from './errors';\nimport { base64UrlDecode, fromUtf8, getCrypto, utf8 } from './util';\n\nexport interface EcJwk {\n kty: 'EC';\n crv: 'P-256';\n x: string;\n y: string;\n kid?: string;\n alg?: string;\n use?: string;\n}\n\nexport interface Jwks {\n keys: EcJwk[];\n}\n\nexport interface JwtHeader {\n alg: string;\n kid?: string;\n typ?: string;\n [key: string]: unknown;\n}\n\nexport interface DecodedJwt<P = Record<string, unknown>> {\n header: JwtHeader;\n payload: P;\n}\n\n/** Decodes a JWT without verifying it. Never trust the result. */\nexport function decodeJwt<P = Record<string, unknown>>(token: string): DecodedJwt<P> {\n const parts = token.split('.');\n if (parts.length !== 3) throw new TokenVerificationError('Malformed JWT', { code: 'malformed_token' });\n try {\n return {\n header: JSON.parse(fromUtf8(base64UrlDecode(parts[0]!))) as JwtHeader,\n payload: JSON.parse(fromUtf8(base64UrlDecode(parts[1]!))) as P,\n };\n } catch {\n throw new TokenVerificationError('Malformed JWT', { code: 'malformed_token' });\n }\n}\n\n/**\n * Caches the provider's public keys. An unknown `kid` triggers one refetch\n * (key rotation), at most once per `cooldownMs`.\n */\nexport class JwksCache {\n private keys = new Map<string, CryptoKey>();\n private loaded = 0;\n private inflight: Promise<void> | null = null;\n\n constructor(\n private readonly load: () => Promise<Jwks>,\n private readonly cooldownMs = 60_000,\n ) {}\n\n private refresh(): Promise<void> {\n if (!this.inflight) {\n this.inflight = (async () => {\n const jwks = await this.load();\n const c = await getCrypto();\n const next = new Map<string, CryptoKey>();\n for (const jwk of jwks.keys ?? []) {\n if (jwk.kty !== 'EC' || jwk.crv !== 'P-256' || (jwk.alg && jwk.alg !== 'ES256')) continue;\n const key = await c.subtle.importKey(\n 'jwk',\n { kty: 'EC', crv: 'P-256', x: jwk.x, y: jwk.y, ext: true },\n { name: 'ECDSA', namedCurve: 'P-256' },\n false,\n ['verify'],\n );\n next.set(jwk.kid ?? '', key);\n }\n this.keys = next;\n this.loaded = Date.now();\n })().finally(() => {\n this.inflight = null;\n });\n }\n return this.inflight;\n }\n\n async getKey(kid: string | undefined): Promise<CryptoKey> {\n const id = kid ?? '';\n if (!this.loaded) await this.refresh();\n let key = this.keys.get(id) ?? (kid === undefined && this.keys.size === 1 ? [...this.keys.values()][0] : undefined);\n if (!key && Date.now() - this.loaded > this.cooldownMs) {\n await this.refresh();\n key = this.keys.get(id);\n }\n if (!key) throw new TokenVerificationError(`No signing key with kid '${id}' in the JWKS`, { code: 'unknown_kid' });\n return key;\n }\n}\n\nexport interface VerifyOptions {\n issuer: string;\n audience: string;\n /** Required `typ` header, e.g. 'at+jwt'. */\n typ?: string;\n /** Rejected `typ` header, e.g. 'at+jwt' for ID tokens. */\n rejectTyp?: string;\n /** Seconds of clock skew to accept. Default: 60 */\n clockTolerance?: number;\n /** Current time in seconds; for tests. */\n now?: number;\n}\n\n/** Verifies an ES256 JWT's signature and its iss, aud, exp, nbf and iat claims. */\nexport async function verifyJwt<P extends Record<string, unknown>>(\n token: string,\n jwks: JwksCache,\n opts: VerifyOptions,\n): Promise<DecodedJwt<P>> {\n const decoded = decodeJwt<P>(token);\n const { header, payload } = decoded;\n if (header.alg !== 'ES256') {\n throw new TokenVerificationError(`Unexpected alg '${header.alg}', expected ES256`, { code: 'invalid_alg' });\n }\n if (opts.typ && header.typ !== opts.typ) {\n throw new TokenVerificationError(`Unexpected token type '${header.typ}', expected '${opts.typ}'`, { code: 'invalid_typ' });\n }\n if (opts.rejectTyp && header.typ === opts.rejectTyp) {\n throw new TokenVerificationError(`A '${header.typ}' token is not accepted here`, { code: 'invalid_typ' });\n }\n\n const key = await jwks.getKey(header.kid);\n const [h, p, s] = token.split('.') as [string, string, string];\n const signature = base64UrlDecode(s);\n if (signature.length !== 64) throw new TokenVerificationError('Invalid ES256 signature length', { code: 'invalid_signature' });\n const c = await getCrypto();\n const ok = await c.subtle.verify({ name: 'ECDSA', hash: 'SHA-256' }, key, signature, utf8(`${h}.${p}`));\n if (!ok) throw new TokenVerificationError('Invalid token signature', { code: 'invalid_signature' });\n\n const now = opts.now ?? Math.floor(Date.now() / 1000);\n const tol = opts.clockTolerance ?? 60;\n if (payload.iss !== opts.issuer) {\n throw new TokenVerificationError(`Unexpected issuer '${String(payload.iss)}'`, { code: 'invalid_issuer' });\n }\n const aud = payload.aud;\n const audOk = Array.isArray(aud) ? aud.includes(opts.audience) : aud === opts.audience;\n if (!audOk) throw new TokenVerificationError('Token was issued for another client (aud)', { code: 'invalid_audience' });\n if (typeof payload.exp !== 'number') throw new TokenVerificationError('Token has no exp', { code: 'missing_exp' });\n if (payload.exp + tol < now) throw new TokenVerificationError('Token has expired', { code: 'token_expired' });\n if (typeof payload.nbf === 'number' && payload.nbf - tol > now) {\n throw new TokenVerificationError('Token is not valid yet (nbf)', { code: 'token_not_yet_valid' });\n }\n if (typeof payload.iat === 'number' && payload.iat - tol > now) {\n throw new TokenVerificationError('Token was issued in the future (iat)', { code: 'invalid_iat' });\n }\n return decoded;\n}\n","// ═══════════════════════════════════════════════════════════════════════════\n// LOGIN WITH CABALSPY ID — OpenID Connect helpers for servers\n// ═══════════════════════════════════════════════════════════════════════════\n\nimport { CabalSpyIDError, ConnectionError, InvalidResponseError, OAuthError, TokenVerificationError } from './errors';\nimport { type Jwks, JwksCache, verifyJwt } from './jwt';\nimport type { CabalSpyIDClaims, DiscoveryDocument, OidcScope, TokenResponse } from './types';\nimport { USER_AGENT, env, randomToken, sha256Base64Url, timingSafeEqual } from './util';\n\nexport const DEFAULT_ISSUER = 'https://id.cabalspy.xyz';\n\nexport type TokenEndpointAuthMethod = 'client_secret_basic' | 'client_secret_post' | 'none';\n\nexport interface CabalSpyIDAuthOptions {\n /** Your instance's client_id (`csid_…`). */\n clientId: string;\n /** Client secret (`csid_sk_…`) of a server-side app. Omit for public clients. */\n clientSecret?: string;\n /** Default redirect URI. Must exactly match one registered in the dashboard. */\n redirectUri?: string;\n /** Default: https://id.cabalspy.xyz (env CABALSPY_ID_ISSUER) */\n issuer?: string;\n /** Default: client_secret_basic with a secret, else none. */\n tokenEndpointAuthMethod?: TokenEndpointAuthMethod;\n /** Accepted clock skew in seconds when checking tokens. Default: 60 */\n clockTolerance?: number;\n /** Per-request timeout in milliseconds. Default: 15_000 */\n timeout?: number;\n fetch?: typeof globalThis.fetch;\n}\n\nexport interface PkcePair {\n codeVerifier: string;\n codeChallenge: string;\n}\n\n/** A fresh PKCE verifier (64 chars) and its S256 challenge. */\nexport async function generatePkce(): Promise<PkcePair> {\n const codeVerifier = await randomToken(48);\n return { codeVerifier, codeChallenge: await sha256Base64Url(codeVerifier) };\n}\n\nexport interface AuthorizationUrlParams {\n /** Default: ['openid', 'profile']. `openid` is added when missing. */\n scope?: OidcScope[] | string;\n redirectUri?: string;\n /** 'none' (silent, live apps only) or 'consent'. */\n prompt?: 'none' | 'consent';\n /** Your own state value; generated when omitted. */\n state?: string;\n /** Your own nonce; generated when omitted. */\n nonce?: string;\n /** Additional query parameters. */\n extraParams?: Record<string, string>;\n}\n\n/**\n * What you must keep (e.g. in a signed, http-only cookie or the server\n * session) until the user comes back to your redirect URI.\n */\nexport interface AuthorizationRequest {\n url: string;\n state: string;\n nonce: string;\n codeVerifier: string;\n redirectUri: string;\n}\n\nexport interface CallbackChecks {\n state: string;\n nonce: string;\n codeVerifier: string;\n redirectUri?: string;\n}\n\nexport interface VerifyIdTokenOptions {\n /** The nonce you sent; required after an authorization request. */\n nonce?: string;\n /** Maximum seconds since the user authenticated (checks auth_time). */\n maxAge?: number;\n}\n\nexport interface LoginResult {\n tokens: TokenResponse;\n /** Verified ID token claims. Check `claims.limited` before using profile data. */\n claims: CabalSpyIDClaims;\n}\n\n/** True when the platform is over its plan's user limit: anonymous sub, no profile data. */\nexport function isLimited(claims: Pick<CabalSpyIDClaims, 'limited' | 'sub'>): boolean {\n return claims.limited === true || claims.sub.startsWith('anon_');\n}\n\n/**\n * OpenID Connect client for \"Login with CabalSpy ID\".\n *\n * const auth = new CabalSpyIDAuth({ clientId, clientSecret, redirectUri });\n * const req = await auth.createAuthorizationUrl({ scope: ['openid', 'profile', 'wallets'] });\n * // store req.state, req.nonce, req.codeVerifier; redirect to req.url\n * const { tokens, claims } = await auth.handleCallback(callbackUrl, stored);\n */\nexport class CabalSpyIDAuth {\n readonly clientId: string;\n readonly issuer: string;\n readonly redirectUri?: string;\n readonly authMethod: TokenEndpointAuthMethod;\n\n private readonly clientSecret?: string;\n private readonly clockTolerance: number;\n private readonly timeout: number;\n private readonly fetchImpl: typeof globalThis.fetch;\n private discovery: Promise<DiscoveryDocument> | null = null;\n private readonly jwks: JwksCache;\n\n constructor(options: CabalSpyIDAuthOptions) {\n if (!options?.clientId) {\n throw new CabalSpyIDError('clientId is required', { code: 'missing_client_id' });\n }\n this.clientId = options.clientId;\n this.clientSecret = options.clientSecret;\n this.redirectUri = options.redirectUri;\n this.issuer = (options.issuer ?? (env('CABALSPY_ID_ISSUER') || DEFAULT_ISSUER)).replace(/\\/+$/, '');\n this.authMethod = options.tokenEndpointAuthMethod ?? (options.clientSecret ? 'client_secret_basic' : 'none');\n if (this.authMethod !== 'none' && !this.clientSecret) {\n throw new CabalSpyIDError(`${this.authMethod} needs clientSecret`, { code: 'missing_client_secret' });\n }\n this.clockTolerance = options.clockTolerance ?? 60;\n this.timeout = options.timeout ?? 15_000;\n this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);\n this.jwks = new JwksCache(async () => {\n const d = await this.discover();\n return this.fetchJson<Jwks>(d.jwks_uri, { headers: { Accept: 'application/json' } });\n });\n }\n\n // ── plumbing ──────────────────────────────────────────────────────────────\n\n private async send(url: string, init: RequestInit): Promise<{ res: Response; body: unknown }> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n try {\n const res = await this.fetchImpl(url, {\n ...init,\n signal: controller.signal,\n headers: { 'User-Agent': USER_AGENT, ...(init.headers as Record<string, string>) },\n });\n const text = await res.text();\n let body: unknown = null;\n if (text) {\n try {\n body = JSON.parse(text);\n } catch {\n body = null;\n }\n }\n return { res, body };\n } catch (err) {\n const aborted = (err as Error)?.name === 'AbortError';\n throw new ConnectionError(aborted ? `Request timed out after ${this.timeout} ms: ${url}` : `Network error: ${(err as Error)?.message}`, {\n code: aborted ? 'timeout' : 'connection_error',\n });\n } finally {\n clearTimeout(timer);\n }\n }\n\n private async fetchJson<T>(url: string, init: RequestInit = {}): Promise<T> {\n const { res, body } = await this.send(url, init);\n if (!res.ok) throw oauthError(res, body);\n if (body == null || typeof body !== 'object') {\n throw new InvalidResponseError(`Expected JSON from ${url}`, { status: res.status, code: 'invalid_response' });\n }\n return body as T;\n }\n\n private clientAuth(form: URLSearchParams): Record<string, string> {\n form.set('client_id', this.clientId);\n if (this.authMethod === 'client_secret_basic') {\n form.delete('client_id');\n // RFC 6749 2.3.1: form-encode id and secret before base64.\n const raw = `${encodeURIComponent(this.clientId)}:${encodeURIComponent(this.clientSecret!)}`;\n return { Authorization: `Basic ${btoa(raw)}` };\n }\n if (this.authMethod === 'client_secret_post') form.set('client_secret', this.clientSecret!);\n return {};\n }\n\n private async postForm<T>(url: string, params: Record<string, string>): Promise<T> {\n const form = new URLSearchParams(params);\n const headers = this.clientAuth(form);\n return this.fetchJson<T>(url, {\n method: 'POST',\n headers: { ...headers, 'Content-Type': 'application/x-www-form-urlencoded', Accept: 'application/json' },\n body: form.toString(),\n });\n }\n\n // ── discovery ─────────────────────────────────────────────────────────────\n\n /** The provider's discovery document (cached for the life of this object). */\n discover(): Promise<DiscoveryDocument> {\n if (!this.discovery) {\n this.discovery = this.fetchJson<DiscoveryDocument>(`${this.issuer}/.well-known/openid-configuration`, {\n headers: { Accept: 'application/json' },\n }).then((d) => {\n if (d.issuer !== this.issuer) {\n throw new TokenVerificationError(`Discovery issuer '${d.issuer}' does not match '${this.issuer}'`, {\n code: 'invalid_issuer',\n });\n }\n return d;\n });\n this.discovery.catch(() => {\n this.discovery = null; // retry next time\n });\n }\n return this.discovery;\n }\n\n /** The provider's public signing keys. */\n async getJwks(): Promise<Jwks> {\n const d = await this.discover();\n return this.fetchJson<Jwks>(d.jwks_uri, { headers: { Accept: 'application/json' } });\n }\n\n // ── authorization ─────────────────────────────────────────────────────────\n\n /**\n * Builds the authorization URL with PKCE (S256), state and nonce.\n * Store `state`, `nonce` and `codeVerifier` until the callback.\n */\n async createAuthorizationUrl(params: AuthorizationUrlParams = {}): Promise<AuthorizationRequest> {\n const d = await this.discover();\n const redirectUri = params.redirectUri ?? this.redirectUri;\n if (!redirectUri) throw new CabalSpyIDError('redirectUri is required', { code: 'missing_redirect_uri' });\n const scopes = typeof params.scope === 'string' ? params.scope.split(/\\s+/).filter(Boolean) : (params.scope ?? ['openid', 'profile']);\n if (!scopes.includes('openid')) scopes.unshift('openid');\n const { codeVerifier, codeChallenge } = await generatePkce();\n const state = params.state ?? (await randomToken(24));\n const nonce = params.nonce ?? (await randomToken(24));\n const q = new URLSearchParams({\n response_type: 'code',\n client_id: this.clientId,\n redirect_uri: redirectUri,\n scope: [...new Set(scopes)].join(' '),\n state,\n nonce,\n code_challenge: codeChallenge,\n code_challenge_method: 'S256',\n ...(params.prompt ? { prompt: params.prompt } : {}),\n ...(params.extraParams ?? {}),\n });\n return { url: `${d.authorization_endpoint}?${q.toString()}`, state, nonce, codeVerifier, redirectUri };\n }\n\n /**\n * Completes the login on your redirect URI: checks `error`, `state` and\n * `iss`, exchanges the code and verifies the ID token (signature, iss, aud,\n * exp, nonce).\n *\n * @param callback the full callback URL, its query string or URLSearchParams\n */\n async handleCallback(callback: string | URL | URLSearchParams, checks: CallbackChecks): Promise<LoginResult> {\n const params = toParams(callback);\n const error = params.get('error');\n if (error) throw new OAuthError(error, params.get('error_description') ?? undefined, { status: 400 });\n const state = params.get('state') ?? '';\n if (!checks.state || !timingSafeEqual(state, checks.state)) {\n throw new OAuthError('invalid_state', 'The state parameter does not match (possible CSRF).', { status: 400 });\n }\n const iss = params.get('iss');\n if (iss !== null && iss !== this.issuer) {\n throw new OAuthError('invalid_issuer', `Unexpected iss '${iss}' in the authorization response.`, { status: 400 });\n }\n const code = params.get('code');\n if (!code) throw new OAuthError('invalid_request', 'The callback has no code.', { status: 400 });\n const tokens = await this.exchangeCode({ code, codeVerifier: checks.codeVerifier, redirectUri: checks.redirectUri });\n const claims = await this.verifyIdToken(tokens.id_token, { nonce: checks.nonce });\n return { tokens, claims };\n }\n\n /** POST /oauth/token with grant_type=authorization_code. */\n async exchangeCode(params: { code: string; codeVerifier: string; redirectUri?: string }): Promise<TokenResponse> {\n const d = await this.discover();\n const redirectUri = params.redirectUri ?? this.redirectUri;\n if (!redirectUri) throw new CabalSpyIDError('redirectUri is required', { code: 'missing_redirect_uri' });\n return this.postForm<TokenResponse>(d.token_endpoint, {\n grant_type: 'authorization_code',\n code: params.code,\n redirect_uri: redirectUri,\n code_verifier: params.codeVerifier,\n });\n }\n\n /**\n * POST /oauth/token with grant_type=refresh_token. Refresh tokens rotate:\n * always store the new `refresh_token`. Reusing an old one revokes the whole\n * chain.\n */\n async refresh(refreshToken: string): Promise<TokenResponse> {\n const d = await this.discover();\n return this.postForm<TokenResponse>(d.token_endpoint, { grant_type: 'refresh_token', refresh_token: refreshToken });\n }\n\n /** POST /oauth/revoke (RFC 7009). Revoking a refresh token ends its whole chain. */\n async revoke(token: string): Promise<void> {\n const d = await this.discover();\n await this.postForm<Record<string, never>>(d.revocation_endpoint, { token });\n }\n\n /** GET /oauth/userinfo — full claims for the access token's scopes (x, wallets, onchain …). */\n async userinfo(accessToken: string): Promise<CabalSpyIDClaims> {\n const d = await this.discover();\n return this.fetchJson<CabalSpyIDClaims>(d.userinfo_endpoint, {\n headers: { Authorization: `Bearer ${accessToken}`, Accept: 'application/json' },\n });\n }\n\n // ── token verification ────────────────────────────────────────────────────\n\n /**\n * Verifies an ID token: ES256 signature (JWKS), iss, aud, azp, exp, nonce.\n * Use it for tokens from your own callback and for `idToken` sent from the\n * browser widget's `csid:login` event.\n *\n * When the platform is over its plan's user limit, `sub` is `anon_…` and\n * `limited` is true; see isLimited().\n */\n async verifyIdToken(idToken: string, options: VerifyIdTokenOptions = {}): Promise<CabalSpyIDClaims> {\n const { payload } = await verifyJwt<CabalSpyIDClaims>(idToken, this.jwks, {\n issuer: this.issuer,\n audience: this.clientId,\n rejectTyp: 'at+jwt',\n clockTolerance: this.clockTolerance,\n });\n if (typeof payload.sub !== 'string' || !payload.sub) {\n throw new TokenVerificationError('ID token has no sub', { code: 'missing_sub' });\n }\n if (payload.azp !== undefined && payload.azp !== this.clientId) {\n throw new TokenVerificationError('ID token azp does not match the client', { code: 'invalid_azp' });\n }\n if (options.nonce !== undefined && (typeof payload.nonce !== 'string' || !timingSafeEqual(payload.nonce, options.nonce))) {\n throw new TokenVerificationError('ID token nonce does not match', { code: 'invalid_nonce' });\n }\n if (options.maxAge !== undefined) {\n const now = Math.floor(Date.now() / 1000);\n if (typeof payload.auth_time !== 'number' || payload.auth_time + options.maxAge + this.clockTolerance < now) {\n throw new TokenVerificationError('The user authenticated too long ago (max_age)', { code: 'auth_time_too_old' });\n }\n }\n return payload;\n }\n\n /**\n * Verifies a CabalSpy ID access token (typ at+jwt) issued to this client,\n * e.g. one your frontend sends to your API. Returns its claims\n * (sub, scope, client_id, exp, jti).\n */\n async verifyAccessToken(accessToken: string): Promise<{ sub: string; scope: string; client_id: string; exp: number; jti: string } & Record<string, unknown>> {\n const { payload } = await verifyJwt<{ sub: string; scope: string; client_id: string; exp: number; jti: string }>(\n accessToken,\n this.jwks,\n { issuer: this.issuer, audience: this.clientId, typ: 'at+jwt', clockTolerance: this.clockTolerance },\n );\n if (payload.client_id !== this.clientId) {\n throw new TokenVerificationError('Access token was issued to another client', { code: 'invalid_audience' });\n }\n return payload;\n }\n}\n\nfunction toParams(callback: string | URL | URLSearchParams): URLSearchParams {\n if (callback instanceof URLSearchParams) return callback;\n if (callback instanceof URL) return callback.searchParams;\n const s = String(callback);\n const i = s.indexOf('?');\n if (/^[a-z][a-z0-9+.-]*:/i.test(s) || s.startsWith('/')) return new URLSearchParams(i === -1 ? '' : s.slice(i + 1));\n return new URLSearchParams(s.startsWith('?') ? s.slice(1) : s);\n}\n\nfunction oauthError(res: Response, body: unknown): OAuthError {\n const b = (body ?? {}) as { error?: unknown; error_description?: string };\n if (typeof b.error === 'string') return new OAuthError(b.error, b.error_description, { status: res.status, body });\n return new OAuthError(`http_${res.status}`, `HTTP ${res.status} from ${res.url || 'the identity provider'}`, {\n status: res.status,\n body,\n });\n}\n"],"mappings":"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","names":[]}
|