@addon-pass/sdk 0.1.3
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/LICENSE +21 -0
- package/README.md +147 -0
- package/dist/contract.d.ts +9 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +111 -0
- package/dist/contract.js.map +1 -0
- package/dist/errors.d.ts +22 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +43 -0
- package/dist/errors.js.map +1 -0
- package/dist/express.d.ts +12 -0
- package/dist/express.d.ts.map +1 -0
- package/dist/express.js +64 -0
- package/dist/express.js.map +1 -0
- package/dist/fastify.d.ts +14 -0
- package/dist/fastify.d.ts.map +1 -0
- package/dist/fastify.js +63 -0
- package/dist/fastify.js.map +1 -0
- package/dist/fetch.d.ts +11 -0
- package/dist/fetch.d.ts.map +1 -0
- package/dist/fetch.js +48 -0
- package/dist/fetch.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/node.d.ts +4 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +59 -0
- package/dist/node.js.map +1 -0
- package/dist/stremio.d.ts +28 -0
- package/dist/stremio.d.ts.map +1 -0
- package/dist/stremio.js +226 -0
- package/dist/stremio.js.map +1 -0
- package/dist/token.d.ts +4 -0
- package/dist/token.d.ts.map +1 -0
- package/dist/token.js +24 -0
- package/dist/token.js.map +1 -0
- package/dist/types.d.ts +32 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +53 -0
- package/dist/types.js.map +1 -0
- package/dist/verifier.d.ts +20 -0
- package/dist/verifier.d.ts.map +1 -0
- package/dist/verifier.js +255 -0
- package/dist/verifier.js.map +1 -0
- package/package.json +72 -0
package/dist/verifier.js
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { AddonPassConfigurationError, AddonPassUnavailableError, EntitlementCredentialRejectedError, EntitlementScopeMismatchError, EntitlementVerificationError, } from "./errors.js";
|
|
2
|
+
import { hashEntitlementToken } from "./token.js";
|
|
3
|
+
import { entitlementResponseSchema, } from "./types.js";
|
|
4
|
+
const CREDENTIAL_PATTERN = /^ap_v[1-9][0-9]*_[a-z0-9]{10,24}\.[A-Za-z0-9_-]{43}$/;
|
|
5
|
+
const DEFAULT_CACHE_TTL_MS = 5_000;
|
|
6
|
+
const DEFAULT_MAX_CACHE_ENTRIES = 1_000;
|
|
7
|
+
const DEFAULT_REQUEST_TIMEOUT_MS = 5_000;
|
|
8
|
+
const MAX_CACHE_TTL_MS = 5_000;
|
|
9
|
+
const MAX_RESPONSE_BYTES = 16_384;
|
|
10
|
+
class ApiUnavailableError extends Error {
|
|
11
|
+
}
|
|
12
|
+
function normalizedApiUrl(value) {
|
|
13
|
+
try {
|
|
14
|
+
const url = new URL(value);
|
|
15
|
+
const localHttp = url.protocol === "http:" &&
|
|
16
|
+
(url.hostname === "localhost" || url.hostname === "127.0.0.1");
|
|
17
|
+
if ((url.protocol !== "https:" && !localHttp) ||
|
|
18
|
+
url.username !== "" ||
|
|
19
|
+
url.password !== "" ||
|
|
20
|
+
url.search !== "" ||
|
|
21
|
+
url.hash !== "") {
|
|
22
|
+
throw new AddonPassConfigurationError();
|
|
23
|
+
}
|
|
24
|
+
if (!url.pathname.endsWith("/"))
|
|
25
|
+
url.pathname += "/";
|
|
26
|
+
return new URL("v1/entitlements/verify", url);
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
if (error instanceof AddonPassConfigurationError)
|
|
30
|
+
throw error;
|
|
31
|
+
throw new AddonPassConfigurationError();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function boundedInteger(value, fallback, minimum, maximum) {
|
|
35
|
+
const selected = value ?? fallback;
|
|
36
|
+
if (!Number.isSafeInteger(selected) ||
|
|
37
|
+
selected < minimum ||
|
|
38
|
+
selected > maximum) {
|
|
39
|
+
throw new AddonPassConfigurationError();
|
|
40
|
+
}
|
|
41
|
+
return selected;
|
|
42
|
+
}
|
|
43
|
+
function cacheControlTtl(value) {
|
|
44
|
+
if (value === null || /(?:^|,)\s*no-store\s*(?:,|$)/i.test(value))
|
|
45
|
+
return 0;
|
|
46
|
+
const match = /(?:^|,)\s*max-age=([0-9]+)\s*(?:,|$)/i.exec(value);
|
|
47
|
+
if (match?.[1] === undefined)
|
|
48
|
+
return 0;
|
|
49
|
+
const seconds = Number(match[1]);
|
|
50
|
+
return Number.isSafeInteger(seconds) ? seconds * 1_000 : 0;
|
|
51
|
+
}
|
|
52
|
+
async function readBoundedBody(response) {
|
|
53
|
+
const contentLength = response.headers.get("content-length");
|
|
54
|
+
if (contentLength !== null && Number(contentLength) > MAX_RESPONSE_BYTES) {
|
|
55
|
+
await response.body?.cancel();
|
|
56
|
+
throw new EntitlementVerificationError();
|
|
57
|
+
}
|
|
58
|
+
if (response.body === null)
|
|
59
|
+
return "";
|
|
60
|
+
const reader = response.body.getReader();
|
|
61
|
+
const decoder = new TextDecoder();
|
|
62
|
+
let bytes = 0;
|
|
63
|
+
let text = "";
|
|
64
|
+
let chunk = await reader.read();
|
|
65
|
+
while (!chunk.done) {
|
|
66
|
+
bytes += chunk.value.byteLength;
|
|
67
|
+
if (bytes > MAX_RESPONSE_BYTES) {
|
|
68
|
+
await reader.cancel();
|
|
69
|
+
throw new EntitlementVerificationError();
|
|
70
|
+
}
|
|
71
|
+
text += decoder.decode(chunk.value, { stream: true });
|
|
72
|
+
chunk = await reader.read();
|
|
73
|
+
}
|
|
74
|
+
return text + decoder.decode();
|
|
75
|
+
}
|
|
76
|
+
function accessDeadlineMs(response) {
|
|
77
|
+
const deadline = response.status === "grace" ? response.graceEnds : response.paidThrough;
|
|
78
|
+
if (!response.entitled || deadline === null)
|
|
79
|
+
return null;
|
|
80
|
+
const parsed = Date.parse(deadline);
|
|
81
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
82
|
+
}
|
|
83
|
+
export class AddonPassVerifier {
|
|
84
|
+
#allowedPlanIds;
|
|
85
|
+
#apiUrl;
|
|
86
|
+
#cache = new Map();
|
|
87
|
+
#cacheTtlMs;
|
|
88
|
+
#fallback;
|
|
89
|
+
#fetch;
|
|
90
|
+
#inFlight = new Map();
|
|
91
|
+
#integrationCredential;
|
|
92
|
+
#maxCacheEntries;
|
|
93
|
+
#now;
|
|
94
|
+
#requestTimeoutMs;
|
|
95
|
+
constructor(options) {
|
|
96
|
+
this.#apiUrl = normalizedApiUrl(options.apiBaseUrl);
|
|
97
|
+
if (!CREDENTIAL_PATTERN.test(options.integrationCredential)) {
|
|
98
|
+
throw new AddonPassConfigurationError();
|
|
99
|
+
}
|
|
100
|
+
const allowedPlanIds = options.allowedPlanIds.map((value) => value.toString());
|
|
101
|
+
if (allowedPlanIds.length === 0 ||
|
|
102
|
+
allowedPlanIds.some((value) => !/^[1-9][0-9]*$/.test(value))) {
|
|
103
|
+
throw new AddonPassConfigurationError();
|
|
104
|
+
}
|
|
105
|
+
this.#allowedPlanIds = new Set(allowedPlanIds);
|
|
106
|
+
this.#cacheTtlMs = boundedInteger(options.cacheTtlMs, DEFAULT_CACHE_TTL_MS, 0, MAX_CACHE_TTL_MS);
|
|
107
|
+
this.#maxCacheEntries = boundedInteger(options.maxCacheEntries, DEFAULT_MAX_CACHE_ENTRIES, 1, 10_000);
|
|
108
|
+
this.#requestTimeoutMs = boundedInteger(options.requestTimeoutMs, DEFAULT_REQUEST_TIMEOUT_MS, 100, 10_000);
|
|
109
|
+
this.#fallback = options.fallback;
|
|
110
|
+
this.#fetch = options.fetch ?? globalThis.fetch;
|
|
111
|
+
this.#integrationCredential = options.integrationCredential;
|
|
112
|
+
this.#now = options.now ?? (() => new Date());
|
|
113
|
+
}
|
|
114
|
+
clear() {
|
|
115
|
+
this.#cache.clear();
|
|
116
|
+
}
|
|
117
|
+
invalidate(rawToken) {
|
|
118
|
+
this.#cache.delete(hashEntitlementToken(rawToken));
|
|
119
|
+
}
|
|
120
|
+
async verifyToken(rawToken) {
|
|
121
|
+
const tokenHash = hashEntitlementToken(rawToken);
|
|
122
|
+
const nowMs = this.#now().getTime();
|
|
123
|
+
const cached = this.#cache.get(tokenHash);
|
|
124
|
+
if (cached !== undefined) {
|
|
125
|
+
if (cached.expiresAtMs > nowMs) {
|
|
126
|
+
this.#cache.delete(tokenHash);
|
|
127
|
+
this.#cache.set(tokenHash, cached);
|
|
128
|
+
return { ...cached.decision, cached: true };
|
|
129
|
+
}
|
|
130
|
+
this.#cache.delete(tokenHash);
|
|
131
|
+
}
|
|
132
|
+
const active = this.#inFlight.get(tokenHash);
|
|
133
|
+
if (active !== undefined)
|
|
134
|
+
return active;
|
|
135
|
+
const verification = this.#verify(tokenHash).finally(() => {
|
|
136
|
+
this.#inFlight.delete(tokenHash);
|
|
137
|
+
});
|
|
138
|
+
this.#inFlight.set(tokenHash, verification);
|
|
139
|
+
return verification;
|
|
140
|
+
}
|
|
141
|
+
async #verify(tokenHash) {
|
|
142
|
+
let verification;
|
|
143
|
+
let source = "api";
|
|
144
|
+
try {
|
|
145
|
+
verification = await this.#verifyViaApi(tokenHash);
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
if (!(error instanceof ApiUnavailableError) ||
|
|
149
|
+
this.#fallback === undefined) {
|
|
150
|
+
throw error instanceof ApiUnavailableError
|
|
151
|
+
? new AddonPassUnavailableError()
|
|
152
|
+
: error;
|
|
153
|
+
}
|
|
154
|
+
let response;
|
|
155
|
+
try {
|
|
156
|
+
response = entitlementResponseSchema.parse(await this.#fallback.verify(tokenHash));
|
|
157
|
+
}
|
|
158
|
+
catch (fallbackError) {
|
|
159
|
+
if (fallbackError instanceof EntitlementScopeMismatchError) {
|
|
160
|
+
throw fallbackError;
|
|
161
|
+
}
|
|
162
|
+
throw new AddonPassUnavailableError();
|
|
163
|
+
}
|
|
164
|
+
verification = { cacheTtlMs: this.#cacheTtlMs, response };
|
|
165
|
+
source = "contract";
|
|
166
|
+
}
|
|
167
|
+
if (verification.response.planId !== null &&
|
|
168
|
+
!this.#allowedPlanIds.has(verification.response.planId)) {
|
|
169
|
+
throw new EntitlementScopeMismatchError();
|
|
170
|
+
}
|
|
171
|
+
const decision = {
|
|
172
|
+
...verification.response,
|
|
173
|
+
cached: false,
|
|
174
|
+
source,
|
|
175
|
+
};
|
|
176
|
+
this.#cacheDecision(tokenHash, decision, verification.cacheTtlMs);
|
|
177
|
+
return decision;
|
|
178
|
+
}
|
|
179
|
+
async #verifyViaApi(tokenHash) {
|
|
180
|
+
const controller = new AbortController();
|
|
181
|
+
const timeout = setTimeout(() => {
|
|
182
|
+
controller.abort();
|
|
183
|
+
}, this.#requestTimeoutMs);
|
|
184
|
+
try {
|
|
185
|
+
let response;
|
|
186
|
+
try {
|
|
187
|
+
response = await this.#fetch(this.#apiUrl, {
|
|
188
|
+
body: JSON.stringify({ tokenHash }),
|
|
189
|
+
headers: {
|
|
190
|
+
accept: "application/json",
|
|
191
|
+
authorization: `Bearer ${this.#integrationCredential}`,
|
|
192
|
+
"content-type": "application/json",
|
|
193
|
+
},
|
|
194
|
+
method: "POST",
|
|
195
|
+
redirect: "error",
|
|
196
|
+
signal: controller.signal,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
throw new ApiUnavailableError();
|
|
201
|
+
}
|
|
202
|
+
if (response.status === 401 || response.status === 403) {
|
|
203
|
+
await response.body?.cancel();
|
|
204
|
+
throw new EntitlementCredentialRejectedError();
|
|
205
|
+
}
|
|
206
|
+
if (response.status >= 500) {
|
|
207
|
+
await response.body?.cancel();
|
|
208
|
+
throw new ApiUnavailableError();
|
|
209
|
+
}
|
|
210
|
+
if (!response.ok) {
|
|
211
|
+
await response.body?.cancel();
|
|
212
|
+
throw new EntitlementVerificationError();
|
|
213
|
+
}
|
|
214
|
+
let parsed;
|
|
215
|
+
try {
|
|
216
|
+
parsed = JSON.parse(await readBoundedBody(response));
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
if (controller.signal.aborted)
|
|
220
|
+
throw new ApiUnavailableError();
|
|
221
|
+
if (error instanceof EntitlementVerificationError)
|
|
222
|
+
throw error;
|
|
223
|
+
throw new EntitlementVerificationError();
|
|
224
|
+
}
|
|
225
|
+
const result = entitlementResponseSchema.safeParse(parsed);
|
|
226
|
+
if (!result.success)
|
|
227
|
+
throw new EntitlementVerificationError();
|
|
228
|
+
return {
|
|
229
|
+
cacheTtlMs: Math.min(this.#cacheTtlMs, cacheControlTtl(response.headers.get("cache-control"))),
|
|
230
|
+
response: result.data,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
finally {
|
|
234
|
+
clearTimeout(timeout);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
#cacheDecision(tokenHash, decision, requestedTtlMs) {
|
|
238
|
+
const nowMs = this.#now().getTime();
|
|
239
|
+
const deadlineMs = accessDeadlineMs(decision);
|
|
240
|
+
const ttlMs = Math.max(0, Math.min(requestedTtlMs, deadlineMs === null ? requestedTtlMs : deadlineMs - nowMs));
|
|
241
|
+
if (ttlMs === 0)
|
|
242
|
+
return;
|
|
243
|
+
while (this.#cache.size >= this.#maxCacheEntries) {
|
|
244
|
+
const oldest = this.#cache.keys().next().value;
|
|
245
|
+
if (oldest === undefined)
|
|
246
|
+
break;
|
|
247
|
+
this.#cache.delete(oldest);
|
|
248
|
+
}
|
|
249
|
+
this.#cache.set(tokenHash, {
|
|
250
|
+
decision,
|
|
251
|
+
expiresAtMs: nowMs + ttlMs,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=verifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifier.js","sourceRoot":"","sources":["../src/verifier.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@addon-pass/sdk",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "Fail-closed entitlement middleware for private Stremio add-ons using AddonPass.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/AddonPass/addonpass-sdk.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/AddonPass/addonpass-sdk/issues"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://github.com/AddonPass/addonpass-sdk#readme",
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=22.14.0"
|
|
18
|
+
},
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"import": "./dist/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./express": {
|
|
25
|
+
"types": "./dist/express.d.ts",
|
|
26
|
+
"import": "./dist/express.js"
|
|
27
|
+
},
|
|
28
|
+
"./fastify": {
|
|
29
|
+
"types": "./dist/fastify.d.ts",
|
|
30
|
+
"import": "./dist/fastify.js"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist",
|
|
35
|
+
"LICENSE",
|
|
36
|
+
"README.md"
|
|
37
|
+
],
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsc -p tsconfig.build.json",
|
|
43
|
+
"check": "npm run typecheck && npm test && npm run build",
|
|
44
|
+
"prepare": "npm run build",
|
|
45
|
+
"test": "vitest run",
|
|
46
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"viem": "2.56.0",
|
|
50
|
+
"zod": "4.5.4"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/express": "5.0.6",
|
|
54
|
+
"@types/node": "24.13.3",
|
|
55
|
+
"express": "5.2.1",
|
|
56
|
+
"fastify": "5.12.1",
|
|
57
|
+
"typescript": "5.9.3",
|
|
58
|
+
"vitest": "4.1.11"
|
|
59
|
+
},
|
|
60
|
+
"peerDependencies": {
|
|
61
|
+
"express": ">=5.2.1 <6",
|
|
62
|
+
"fastify": ">=5.12.1 <6"
|
|
63
|
+
},
|
|
64
|
+
"peerDependenciesMeta": {
|
|
65
|
+
"express": {
|
|
66
|
+
"optional": true
|
|
67
|
+
},
|
|
68
|
+
"fastify": {
|
|
69
|
+
"optional": true
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|