@atxp/common 0.2.5

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.
Files changed (66) hide show
  1. package/README.md +176 -0
  2. package/dist/commonTestHelpers.d.ts +83 -0
  3. package/dist/commonTestHelpers.d.ts.map +1 -0
  4. package/dist/commonTestHelpers.js +115 -0
  5. package/dist/commonTestHelpers.js.map +1 -0
  6. package/dist/index.d.ts +15 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +15 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/jwt.d.ts +9 -0
  11. package/dist/jwt.d.ts.map +1 -0
  12. package/dist/jwt.js +29 -0
  13. package/dist/jwt.js.map +1 -0
  14. package/dist/logger.d.ts +18 -0
  15. package/dist/logger.d.ts.map +1 -0
  16. package/dist/logger.js +43 -0
  17. package/dist/logger.js.map +1 -0
  18. package/dist/mcpJson.d.ts +9 -0
  19. package/dist/mcpJson.d.ts.map +1 -0
  20. package/dist/mcpJson.js +127 -0
  21. package/dist/mcpJson.js.map +1 -0
  22. package/dist/memoryOAuthDb.d.ts +25 -0
  23. package/dist/memoryOAuthDb.d.ts.map +1 -0
  24. package/dist/memoryOAuthDb.js +97 -0
  25. package/dist/memoryOAuthDb.js.map +1 -0
  26. package/dist/oAuthDb.d.ts +26 -0
  27. package/dist/oAuthDb.d.ts.map +1 -0
  28. package/dist/oAuthDb.js +145 -0
  29. package/dist/oAuthDb.js.map +1 -0
  30. package/dist/oAuthDbFactory.d.ts +30 -0
  31. package/dist/oAuthDbFactory.d.ts.map +1 -0
  32. package/dist/oAuthDbFactory.js +37 -0
  33. package/dist/oAuthDbFactory.js.map +1 -0
  34. package/dist/oAuthResource.d.ts +35 -0
  35. package/dist/oAuthResource.d.ts.map +1 -0
  36. package/dist/oAuthResource.js +241 -0
  37. package/dist/oAuthResource.js.map +1 -0
  38. package/dist/paymentRequiredError.d.ts +6 -0
  39. package/dist/paymentRequiredError.d.ts.map +1 -0
  40. package/dist/paymentRequiredError.js +14 -0
  41. package/dist/paymentRequiredError.js.map +1 -0
  42. package/dist/platform/index.d.ts +27 -0
  43. package/dist/platform/index.d.ts.map +1 -0
  44. package/dist/platform/index.js +204 -0
  45. package/dist/platform/index.js.map +1 -0
  46. package/dist/redisOAuthDb.d.ts +36 -0
  47. package/dist/redisOAuthDb.d.ts.map +1 -0
  48. package/dist/redisOAuthDb.js +160 -0
  49. package/dist/redisOAuthDb.js.map +1 -0
  50. package/dist/servers.d.ts +14 -0
  51. package/dist/servers.d.ts.map +1 -0
  52. package/dist/servers.js +14 -0
  53. package/dist/servers.js.map +1 -0
  54. package/dist/sseParser.d.ts +27 -0
  55. package/dist/sseParser.d.ts.map +1 -0
  56. package/dist/sseParser.js +100 -0
  57. package/dist/sseParser.js.map +1 -0
  58. package/dist/types.d.ts +71 -0
  59. package/dist/types.d.ts.map +1 -0
  60. package/dist/types.js +9 -0
  61. package/dist/types.js.map +1 -0
  62. package/dist/utils.d.ts +19 -0
  63. package/dist/utils.d.ts.map +1 -0
  64. package/dist/utils.js +24 -0
  65. package/dist/utils.js.map +1 -0
  66. package/package.json +43 -0
@@ -0,0 +1,241 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import * as oauth from 'oauth4webapi';
3
+ import { ConsoleLogger } from './logger.js';
4
+ export class OAuthResourceClient {
5
+ constructor({ db, callbackUrl = 'http://localhost:3000/unused-dummy-global-callback', isPublic = false, sideChannelFetch = fetch, strict = false, allowInsecureRequests = process.env.NODE_ENV === 'development', clientName = 'Token Introspection Client', logger = new ConsoleLogger() }) {
6
+ // In-memory lock to prevent concurrent client registrations
7
+ this.registrationLocks = new Map();
8
+ this.introspectToken = async (authorizationServerUrl, token, additionalParameters) => {
9
+ // Don't use getAuthorizationServer here, because we're not using the resource server url
10
+ const authorizationServer = await this.authorizationServerFromUrl(new URL(authorizationServerUrl));
11
+ // When introspecting a token, the "resource" server that we want credentials for is the auth server
12
+ let clientCredentials = await this.getClientCredentials(authorizationServer);
13
+ // Create a client for token introspection
14
+ let client = {
15
+ client_id: clientCredentials.clientId,
16
+ token_endpoint_auth_method: 'client_secret_basic'
17
+ };
18
+ // Create client authentication method
19
+ let clientAuth = oauth.ClientSecretBasic(clientCredentials.clientSecret);
20
+ // Use oauth4webapi's built-in token introspection
21
+ let introspectionResponse = await oauth.introspectionRequest(authorizationServer, client, clientAuth, token, {
22
+ additionalParameters,
23
+ [oauth.customFetch]: this.sideChannelFetch,
24
+ [oauth.allowInsecureRequests]: this.allowInsecureRequests
25
+ });
26
+ if (introspectionResponse.status === 403 || introspectionResponse.status === 401) {
27
+ this.logger.info(`Bad response status doing token introspection: ${introspectionResponse.statusText}. Could be due to bad client credentials - trying to re-register`);
28
+ clientCredentials = await this.registerClient(authorizationServer);
29
+ client = {
30
+ client_id: clientCredentials.clientId,
31
+ token_endpoint_auth_method: 'client_secret_basic'
32
+ };
33
+ clientAuth = oauth.ClientSecretBasic(clientCredentials.clientSecret);
34
+ introspectionResponse = await oauth.introspectionRequest(authorizationServer, client, clientAuth, token, {
35
+ additionalParameters,
36
+ [oauth.customFetch]: this.sideChannelFetch,
37
+ [oauth.allowInsecureRequests]: this.allowInsecureRequests
38
+ });
39
+ }
40
+ if (introspectionResponse.status !== 200) {
41
+ throw new Error(`Token introspection failed with status ${introspectionResponse.status}: ${introspectionResponse.statusText}`);
42
+ }
43
+ // Process the introspection response
44
+ const tokenData = await oauth.processIntrospectionResponse(authorizationServer, client, introspectionResponse);
45
+ return {
46
+ active: tokenData.active,
47
+ scope: tokenData.scope,
48
+ sub: tokenData.sub,
49
+ aud: tokenData.aud
50
+ };
51
+ };
52
+ this.getAuthorizationServer = async (resourceServerUrl) => {
53
+ resourceServerUrl = this.normalizeResourceServerUrl(resourceServerUrl);
54
+ try {
55
+ const resourceUrl = new URL(resourceServerUrl);
56
+ const prmResponse = await oauth.resourceDiscoveryRequest(resourceUrl, {
57
+ [oauth.customFetch]: this.sideChannelFetch,
58
+ [oauth.allowInsecureRequests]: this.allowInsecureRequests
59
+ });
60
+ const fallbackToRsAs = !this.strict && prmResponse.status === 404;
61
+ let authServer = undefined;
62
+ if (!fallbackToRsAs) {
63
+ const resourceServer = await oauth.processResourceDiscoveryResponse(resourceUrl, prmResponse);
64
+ authServer = resourceServer.authorization_servers?.[0];
65
+ }
66
+ else {
67
+ // Some older servers serve OAuth metadata from the MCP server instead of PRM data,
68
+ // so if the PRM data isn't found, we'll try to get the AS metadata from the MCP server
69
+ this.logger.info('Protected Resource Metadata document not found, looking for OAuth metadata on resource server');
70
+ // Trim off the path - OAuth metadata is also singular for a server and served from the root
71
+ const rsUrl = new URL(resourceServerUrl);
72
+ const rsAsUrl = rsUrl.protocol + '//' + rsUrl.host + '/.well-known/oauth-authorization-server';
73
+ // Don't use oauth4webapi for this, because these servers might be specifiying an issuer that is not
74
+ // themselves (in order to use a separate AS by just hosting the OAuth metadata on the MCP server)
75
+ // This is against the OAuth spec, but some servers do it anyway
76
+ const rsAsResponse = await this.sideChannelFetch(rsAsUrl);
77
+ if (rsAsResponse.status === 200) {
78
+ const rsAsBody = await rsAsResponse.json();
79
+ authServer = rsAsBody.issuer;
80
+ }
81
+ }
82
+ if (!authServer) {
83
+ throw new Error('No authorization_servers found in protected resource metadata');
84
+ }
85
+ const authServerUrl = new URL(authServer);
86
+ const res = await this.authorizationServerFromUrl(authServerUrl);
87
+ return res;
88
+ }
89
+ catch (error) {
90
+ this.logger.warn(`Error fetching authorization server configuration: ${error}`);
91
+ this.logger.warn(error.stack || '');
92
+ throw error;
93
+ }
94
+ };
95
+ this.authorizationServerFromUrl = async (authServerUrl) => {
96
+ try {
97
+ // Explicitly throw for a tricky edge case to trigger tests
98
+ if (authServerUrl.toString().includes('/.well-known/oauth-protected-resource')) {
99
+ throw new Error('Authorization server URL is a PRM URL, which is not supported. It must be an AS URL.');
100
+ }
101
+ // Now, get the authorization server metadata
102
+ const response = await oauth.discoveryRequest(authServerUrl, {
103
+ algorithm: 'oauth2',
104
+ [oauth.customFetch]: this.sideChannelFetch,
105
+ [oauth.allowInsecureRequests]: this.allowInsecureRequests
106
+ });
107
+ const authorizationServer = await oauth.processDiscoveryResponse(authServerUrl, response);
108
+ return authorizationServer;
109
+ }
110
+ catch (error) {
111
+ this.logger.warn(`Error fetching authorization server configuration: ${error}`);
112
+ throw error;
113
+ }
114
+ };
115
+ this.normalizeResourceServerUrl = (resourceServerUrl) => {
116
+ // the url might be EITHER:
117
+ // 1. the PRM URL (when it's received from the www-authenticate header or a PRM response conforming to RFC 9728)
118
+ // 2. the resource url itself (when we're using the resource url itself)
119
+ // We standardize on the resource url itself, so that we can store it in the DB and all the rest of the plumbing
120
+ // doesn't have to worry about the difference between the two.
121
+ const res = resourceServerUrl.replace('/.well-known/oauth-protected-resource', '');
122
+ return res;
123
+ };
124
+ this.getRegistrationMetadata = async () => {
125
+ // Create client metadata for registration
126
+ const clientMetadata = {
127
+ redirect_uris: [this.callbackUrl],
128
+ // We shouldn't actually need any response_types for this client either, but
129
+ // the OAuth spec requires us to provide a response_type
130
+ response_types: ['code'],
131
+ grant_types: ['authorization_code', 'client_credentials'],
132
+ token_endpoint_auth_method: 'client_secret_basic',
133
+ client_name: this.clientName,
134
+ };
135
+ return clientMetadata;
136
+ };
137
+ this.registerClient = async (authorizationServer) => {
138
+ this.logger.info(`Registering client with authorization server for ${this.callbackUrl}`);
139
+ if (!authorizationServer.registration_endpoint) {
140
+ throw new Error('Authorization server does not support dynamic client registration');
141
+ }
142
+ const clientMetadata = await this.getRegistrationMetadata();
143
+ let registeredClient;
144
+ try {
145
+ // Make the registration request
146
+ const response = await oauth.dynamicClientRegistrationRequest(authorizationServer, clientMetadata, {
147
+ [oauth.customFetch]: this.sideChannelFetch,
148
+ [oauth.allowInsecureRequests]: this.allowInsecureRequests
149
+ });
150
+ // Process the registration response
151
+ registeredClient = await oauth.processDynamicClientRegistrationResponse(response);
152
+ }
153
+ catch (error) {
154
+ this.logger.warn(`Client registration failure error_details: ${JSON.stringify(error.cause?.error_details)}`);
155
+ throw error;
156
+ }
157
+ this.logger.info(`Successfully registered client with ID: ${registeredClient.client_id}`);
158
+ // Create client credentials from the registration response
159
+ const credentials = {
160
+ clientId: registeredClient.client_id,
161
+ clientSecret: registeredClient.client_secret?.toString() || '', // Public client has no secret
162
+ redirectUri: this.callbackUrl
163
+ };
164
+ // Save the credentials in the database
165
+ await this.db.saveClientCredentials(authorizationServer.issuer, credentials);
166
+ return credentials;
167
+ };
168
+ this.getClientCredentials = async (authorizationServer) => {
169
+ let credentials = await this.db.getClientCredentials(authorizationServer.issuer);
170
+ // If no credentials found, register a new client
171
+ if (!credentials) {
172
+ // Check if there's already a registration in progress for this issuer
173
+ const lockKey = authorizationServer.issuer;
174
+ const existingLock = this.registrationLocks.get(lockKey);
175
+ if (existingLock) {
176
+ this.logger.debug(`Waiting for existing client registration for issuer: ${lockKey}`);
177
+ return await existingLock;
178
+ }
179
+ // Create a new registration promise and store it as a lock
180
+ try {
181
+ const registrationPromise = this.registerClient(authorizationServer);
182
+ this.registrationLocks.set(lockKey, registrationPromise);
183
+ credentials = await registrationPromise;
184
+ return credentials;
185
+ }
186
+ finally {
187
+ // Always clean up the lock when done
188
+ this.registrationLocks.delete(lockKey);
189
+ }
190
+ }
191
+ return credentials;
192
+ };
193
+ this.makeOAuthClientAndAuth = (credentials) => {
194
+ // Create the client configuration
195
+ const client = {
196
+ client_id: credentials.clientId,
197
+ token_endpoint_auth_method: 'none'
198
+ };
199
+ let clientAuth = oauth.None();
200
+ // If the client has a secret, that means it was registered as a confidential client
201
+ // In that case, we should auth to the token endpoint using the client secret as well.
202
+ // In either case (public or confidential), we're also using PKCE
203
+ if (credentials.clientSecret) {
204
+ client.token_endpoint_auth_method = 'client_secret_post';
205
+ // Create the client authentication method
206
+ clientAuth = oauth.ClientSecretPost(credentials.clientSecret);
207
+ }
208
+ return [client, clientAuth];
209
+ };
210
+ // Default values above are appropriate for a global client used directly. Subclasses should override these,
211
+ // because things like the callbackUrl will actually be important for them
212
+ this.db = db;
213
+ this.callbackUrl = callbackUrl;
214
+ this.isPublic = isPublic;
215
+ this.sideChannelFetch = sideChannelFetch;
216
+ this.strict = strict;
217
+ this.allowInsecureRequests = allowInsecureRequests;
218
+ this.clientName = clientName;
219
+ this.logger = logger;
220
+ }
221
+ }
222
+ OAuthResourceClient.trimToPath = (url) => {
223
+ try {
224
+ const urlObj = new URL(url);
225
+ return `${urlObj.origin}${urlObj.pathname}`;
226
+ }
227
+ catch (error) {
228
+ // If the URL is invalid, try to construct a valid one
229
+ if (!url.startsWith('http://') && !url.startsWith('https://')) {
230
+ return `https://${url}`;
231
+ }
232
+ throw error;
233
+ }
234
+ };
235
+ OAuthResourceClient.getParentPath = (url) => {
236
+ const urlObj = new URL(url);
237
+ urlObj.pathname = urlObj.pathname.replace(/\/[^/]+$/, '');
238
+ const res = urlObj.toString();
239
+ return res === url ? null : res;
240
+ };
241
+ //# sourceMappingURL=oAuthResource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oAuthResource.js","sourceRoot":"","sources":["../src/oAuthResource.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { McpError } from "@modelcontextprotocol/sdk/types.js";
2
+ import { AuthorizationServerUrl } from "./types.js";
3
+ export declare const PAYMENT_REQUIRED_ERROR_CODE = -30402;
4
+ export declare const PAYMENT_REQUIRED_PREAMBLE = "Payment via ATXP is required. ";
5
+ export declare function paymentRequiredError(server: AuthorizationServerUrl, paymentRequestId: string, chargeAmount?: BigNumber): McpError;
6
+ //# sourceMappingURL=paymentRequiredError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paymentRequiredError.d.ts","sourceRoot":"","sources":["../src/paymentRequiredError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAGpD,eAAO,MAAM,2BAA2B,SAAS,CAAC;AAGlD,eAAO,MAAM,yBAAyB,mCAAmC,CAAC;AAE1E,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,SAAS,GAAG,QAAQ,CAQjI"}
@@ -0,0 +1,14 @@
1
+ import { McpError } from "@modelcontextprotocol/sdk/types.js";
2
+ export const PAYMENT_REQUIRED_ERROR_CODE = -30402; // Payment required
3
+ // Do NOT modify this message. It is used by clients to identify an ATXP payment required error
4
+ // in an MCP response. Changing it will break back-compatability.
5
+ export const PAYMENT_REQUIRED_PREAMBLE = 'Payment via ATXP is required. ';
6
+ export function paymentRequiredError(server, paymentRequestId, chargeAmount) {
7
+ const serverUrl = new URL(server);
8
+ server = serverUrl.origin;
9
+ const paymentRequestUrl = `${server}/payment-request/${paymentRequestId}`;
10
+ const data = { paymentRequestId, paymentRequestUrl, chargeAmount };
11
+ const amountText = chargeAmount ? ` You will be charged ${chargeAmount.toString()}.` : '';
12
+ return new McpError(PAYMENT_REQUIRED_ERROR_CODE, `${PAYMENT_REQUIRED_PREAMBLE}${amountText} Please pay at: ${paymentRequestUrl}`, data);
13
+ }
14
+ //# sourceMappingURL=paymentRequiredError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paymentRequiredError.js","sourceRoot":"","sources":["../src/paymentRequiredError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AAI9D,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,KAAK,CAAC,CAAC,mBAAmB;AACtE,+FAA+F;AAC/F,iEAAiE;AACjE,MAAM,CAAC,MAAM,yBAAyB,GAAG,gCAAgC,CAAC;AAE1E,MAAM,UAAU,oBAAoB,CAAC,MAA8B,EAAE,gBAAwB,EAAE,YAAwB;IACrH,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IAClC,MAAM,GAAG,SAAS,CAAC,MAAgC,CAAC;IAEpD,MAAM,iBAAiB,GAAG,GAAG,MAAM,oBAAoB,gBAAgB,EAAE,CAAC;IAC1E,MAAM,IAAI,GAAG,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,YAAY,EAAE,CAAC;IACnE,MAAM,UAAU,GAAG,YAAY,CAAC,CAAC,CAAC,wBAAwB,YAAY,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1F,OAAO,IAAI,QAAQ,CAAC,2BAA2B,EAAE,GAAG,yBAAyB,GAAG,UAAU,mBAAmB,iBAAiB,EAAE,EAAE,IAAI,CAAC,CAAC;AAC1I,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { FetchLike } from '../types.js';
2
+ export interface PlatformCrypto {
3
+ digest: (data: Uint8Array) => Promise<Uint8Array>;
4
+ randomUUID: () => string;
5
+ toHex: (data: Uint8Array) => string;
6
+ }
7
+ export interface PlatformSQLite {
8
+ openDatabase: (name: string) => SQLiteDatabase;
9
+ }
10
+ export interface SQLiteDatabase {
11
+ execAsync: (sql: string) => Promise<void>;
12
+ prepareAsync: (sql: string) => Promise<SQLiteStatement>;
13
+ closeAsync: () => Promise<void>;
14
+ }
15
+ export interface SQLiteStatement {
16
+ executeAsync: <T = any>(...params: any[]) => Promise<SQLiteResult<T>>;
17
+ finalizeAsync: () => Promise<void>;
18
+ }
19
+ export interface SQLiteResult<T> {
20
+ getFirstAsync: () => Promise<T | null>;
21
+ }
22
+ export declare function getIsReactNative(): boolean;
23
+ export declare const isNode: string | false;
24
+ export declare const createReactNativeSafeFetch: (originalFetch: FetchLike) => FetchLike;
25
+ export declare let crypto: PlatformCrypto;
26
+ export declare let sqlite: PlatformSQLite;
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/platform/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG7C,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAClD,UAAU,EAAE,MAAM,MAAM,CAAC;IACzB,KAAK,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,cAAc,CAAC;CAChD;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IACxD,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,MAAM,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,aAAa,EAAE,MAAM,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;CACxC;AAGD,wBAAgB,gBAAgB,YAG/B;AACD,eAAO,MAAM,MAAM,gBAA2D,CAAC;AAkC/E,eAAO,MAAM,0BAA0B,GAAI,eAAe,SAAS,KAAG,SA4BrE,CAAC;AA4IF,eAAO,IAAI,MAAM,EAAE,cAAc,CAAC;AAClC,eAAO,IAAI,MAAM,EAAE,cAAc,CAAC"}
@@ -0,0 +1,204 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ // Platform detection - supports both Expo and bare React Native
3
+ export function getIsReactNative() {
4
+ const nav = (typeof navigator !== 'undefined' ? navigator : (typeof global !== 'undefined' ? global.navigator : undefined));
5
+ return !!nav && nav.product === 'ReactNative';
6
+ }
7
+ export const isNode = typeof process !== 'undefined' && process.versions?.node;
8
+ // Helper to load modules in both CommonJS and ESM environments
9
+ function loadModule(moduleId) {
10
+ try {
11
+ // Try to use eval('require') to prevent bundler static analysis
12
+ const requireFunc = (0, eval)('require');
13
+ return requireFunc(moduleId);
14
+ }
15
+ catch {
16
+ throw new Error(`Failed to load module "${moduleId}" synchronously. In ESM environments, please ensure the module is pre-loaded or use MemoryOAuthDb instead.`);
17
+ }
18
+ }
19
+ // Async version for cases where we can fall back to dynamic import
20
+ async function loadModuleAsync(moduleId) {
21
+ try {
22
+ // Try synchronous loading first
23
+ return loadModule(moduleId);
24
+ }
25
+ catch {
26
+ // Fall back to dynamic import for ESM
27
+ try {
28
+ return await import(moduleId);
29
+ }
30
+ catch (e) {
31
+ throw new Error(`Failed to load module "${moduleId}": ${e instanceof Error ? e.message : 'Module loading not available in this environment'}`);
32
+ }
33
+ }
34
+ }
35
+ // Apply URL polyfill for React Native/Expo
36
+ if (getIsReactNative()) {
37
+ loadModule('react-native-url-polyfill/auto');
38
+ }
39
+ // React Native safe fetch that prevents body consumption issues
40
+ export const createReactNativeSafeFetch = (originalFetch) => {
41
+ return async (url, init) => {
42
+ const response = await originalFetch(url, init);
43
+ // For non-2xx responses or responses we know won't have JSON bodies, return as-is
44
+ if (!response.ok || response.status === 204) {
45
+ return response;
46
+ }
47
+ // Pre-read the body to avoid consumption issues
48
+ const contentType = response.headers.get('content-type');
49
+ if (contentType && contentType.includes('application/json')) {
50
+ try {
51
+ const bodyText = await response.text();
52
+ // Create a new Response with the pre-read body
53
+ return new Response(bodyText, {
54
+ status: response.status,
55
+ statusText: response.statusText,
56
+ headers: response.headers
57
+ });
58
+ }
59
+ catch {
60
+ // If reading fails, return original response
61
+ return response;
62
+ }
63
+ }
64
+ return response;
65
+ };
66
+ };
67
+ // Platform factory functions
68
+ function createReactNativeCrypto() {
69
+ let expoCrypto;
70
+ try {
71
+ expoCrypto = loadModule('expo-crypto');
72
+ }
73
+ catch {
74
+ throw new Error('React Native detected but expo-crypto package is required. ' +
75
+ 'Please install it: npm install expo-crypto');
76
+ }
77
+ return {
78
+ digest: async (data) => {
79
+ const hash = await expoCrypto.digestStringAsync(expoCrypto.CryptoDigestAlgorithm.SHA256, new TextDecoder().decode(data));
80
+ return new Uint8Array(Buffer.from(hash, 'hex'));
81
+ },
82
+ randomUUID: () => expoCrypto.randomUUID(),
83
+ toHex: (data) => Array.from(data).map(b => b.toString(16).padStart(2, '0')).join(''),
84
+ };
85
+ }
86
+ function createReactNativeSQLite() {
87
+ let expoSqlite;
88
+ try {
89
+ expoSqlite = loadModule('expo-sqlite');
90
+ }
91
+ catch {
92
+ throw new Error('React Native detected but expo-sqlite package is required. ' +
93
+ 'Please install it: npm install expo-sqlite');
94
+ }
95
+ return {
96
+ openDatabase: (name) => expoSqlite.openDatabaseSync(name),
97
+ };
98
+ }
99
+ function createNodeCrypto() {
100
+ let cryptoModule = null;
101
+ return {
102
+ digest: async (data) => {
103
+ if (!cryptoModule) {
104
+ cryptoModule = await loadModuleAsync('crypto');
105
+ }
106
+ return new Uint8Array(cryptoModule.createHash('sha256').update(data).digest());
107
+ },
108
+ randomUUID: () => {
109
+ // randomUUID is synchronous, so we need sync loading
110
+ try {
111
+ const crypto = loadModule('crypto');
112
+ return crypto.randomUUID();
113
+ }
114
+ catch {
115
+ throw new Error('randomUUID requires synchronous module loading (CommonJS)');
116
+ }
117
+ },
118
+ toHex: (data) => Buffer.from(data).toString('hex'),
119
+ };
120
+ }
121
+ function createNodeSQLite() {
122
+ return {
123
+ openDatabase: (name) => {
124
+ let db = null;
125
+ let dbPromise = null;
126
+ const getDbAsync = async () => {
127
+ if (db)
128
+ return db;
129
+ if (!dbPromise) {
130
+ dbPromise = (async () => {
131
+ try {
132
+ // Try synchronous loading first (works in CJS)
133
+ const Database = loadModule('better-sqlite3');
134
+ db = new Database(name);
135
+ }
136
+ catch {
137
+ // Fall back to async loading for ESM
138
+ const module = await import('better-sqlite3');
139
+ const Database = module.default || module;
140
+ db = new Database(name);
141
+ }
142
+ return db;
143
+ })();
144
+ }
145
+ return dbPromise;
146
+ };
147
+ return {
148
+ execAsync: async (sql) => {
149
+ const database = await getDbAsync();
150
+ database.exec(sql);
151
+ },
152
+ prepareAsync: async (sql) => {
153
+ const database = await getDbAsync();
154
+ const stmt = database.prepare(sql);
155
+ return {
156
+ executeAsync: async (...params) => {
157
+ // Use .all() for SELECT, .run() for others
158
+ const isSelect = /^\s*select/i.test(sql);
159
+ let resultRows = [];
160
+ if (isSelect) {
161
+ resultRows = stmt.all(...params);
162
+ }
163
+ else {
164
+ stmt.run(...params);
165
+ }
166
+ return {
167
+ getFirstAsync: async () => {
168
+ if (isSelect) {
169
+ return resultRows[0] || null;
170
+ }
171
+ else {
172
+ return null;
173
+ }
174
+ },
175
+ // Optionally, you could expose runResult for non-SELECTs if needed
176
+ };
177
+ },
178
+ finalizeAsync: async () => {
179
+ // better-sqlite3 statements are automatically finalized when they go out of scope
180
+ },
181
+ };
182
+ },
183
+ closeAsync: async () => {
184
+ if (db) {
185
+ db.close();
186
+ db = null;
187
+ }
188
+ },
189
+ };
190
+ },
191
+ };
192
+ }
193
+ // Export platform-specific implementations
194
+ export let crypto;
195
+ export let sqlite;
196
+ if (getIsReactNative()) {
197
+ crypto = createReactNativeCrypto();
198
+ sqlite = createReactNativeSQLite();
199
+ }
200
+ else {
201
+ crypto = createNodeCrypto();
202
+ sqlite = createNodeSQLite();
203
+ }
204
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/platform/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { AccessToken, ClientCredentials, Logger, OAuthDb, PKCEValues } from './types.js';
2
+ export interface RedisClient {
3
+ get(key: string): Promise<string | null>;
4
+ set(key: string, value: string): Promise<unknown>;
5
+ setex(key: string, seconds: number, value: string): Promise<unknown>;
6
+ del(key: string): Promise<number>;
7
+ quit(): Promise<unknown>;
8
+ }
9
+ export interface RedisOAuthDbConfig {
10
+ redis: RedisClient | string;
11
+ encrypt?: (data: string) => string;
12
+ decrypt?: (data: string) => string;
13
+ logger?: Logger;
14
+ keyPrefix?: string;
15
+ ttl?: number;
16
+ }
17
+ export declare class RedisOAuthDb implements OAuthDb {
18
+ private redis;
19
+ private encrypt;
20
+ private decrypt;
21
+ private logger;
22
+ private keyPrefix;
23
+ private ttl?;
24
+ constructor({ redis, encrypt, decrypt, logger, keyPrefix, ttl }: RedisOAuthDbConfig);
25
+ private createRedisClient;
26
+ private getRedisClient;
27
+ private getKey;
28
+ getClientCredentials(resourceUrl: string): Promise<ClientCredentials | null>;
29
+ saveClientCredentials(resourceUrl: string, credentials: ClientCredentials): Promise<void>;
30
+ getPKCEValues(userId: string, state: string): Promise<PKCEValues | null>;
31
+ savePKCEValues(userId: string, state: string, values: PKCEValues): Promise<void>;
32
+ getAccessToken(userId: string, url: string): Promise<AccessToken | null>;
33
+ saveAccessToken(userId: string, url: string, token: AccessToken): Promise<void>;
34
+ close(): Promise<void>;
35
+ }
36
+ //# sourceMappingURL=redisOAuthDb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redisOAuthDb.d.ts","sourceRoot":"","sources":["../src/redisOAuthDb.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE9F,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,WAAW,GAAG,MAAM,CAAC;IAC5B,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACnC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,YAAa,YAAW,OAAO;IAC1C,OAAO,CAAC,KAAK,CAAqC;IAClD,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,GAAG,CAAC,CAAS;gBAET,EACV,KAAK,EACL,OAAgC,EAChC,OAAgC,EAChC,MAA4B,EAC5B,SAAoB,EACpB,GAAG,EACJ,EAAE,kBAAkB;YAeP,iBAAiB;YAUjB,cAAc;IAO5B,OAAO,CAAC,MAAM;IAIR,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAoB5E,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAYzF,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAqBxE,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAehF,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAgCxE,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAuB/E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ7B"}