@nya-account/node-sdk 2.0.0 → 2.0.1
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/README.md +5 -4
- package/dist/index.d.ts +8 -40
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -73
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @nya-account/node-sdk
|
|
2
2
|
|
|
3
|
-
Official Node.js SDK for [Nya Account](https://
|
|
3
|
+
Official Node.js SDK for [Nya Account](https://account.lolinya.net) SSO system.
|
|
4
4
|
|
|
5
5
|
Provides a complete OAuth 2.1 / OIDC client with PKCE, JWT verification, and Express middleware.
|
|
6
6
|
|
|
@@ -20,7 +20,8 @@ yarn add @nya-account/node-sdk
|
|
|
20
20
|
import { NyaAccountClient } from '@nya-account/node-sdk'
|
|
21
21
|
|
|
22
22
|
const client = new NyaAccountClient({
|
|
23
|
-
|
|
23
|
+
// See https://account.lolinya.net/docs/developer/service-endpoints#integration-endpoints
|
|
24
|
+
issuer: 'https://account-api.edge.lolinya.net',
|
|
24
25
|
clientId: 'my-app',
|
|
25
26
|
clientSecret: 'my-secret',
|
|
26
27
|
})
|
|
@@ -51,7 +52,7 @@ import { getAuth } from '@nya-account/node-sdk/express'
|
|
|
51
52
|
|
|
52
53
|
const app = express()
|
|
53
54
|
const client = new NyaAccountClient({
|
|
54
|
-
issuer: 'https://account.
|
|
55
|
+
issuer: 'https://account-api.edge.lolinya.net',
|
|
55
56
|
clientId: 'my-app',
|
|
56
57
|
clientSecret: 'my-secret',
|
|
57
58
|
})
|
|
@@ -85,7 +86,7 @@ app.post('/api/sensitive',
|
|
|
85
86
|
|
|
86
87
|
| Option | Type | Default | Description |
|
|
87
88
|
|---|---|---|---|
|
|
88
|
-
| `issuer` | `string` |
|
|
89
|
+
| `issuer` | `string` | `'https://account-api.edge.lolinya.net'` | SSO service URL (Issuer URL). See [Service Endpoints](https://account.lolinya.net/docs/developer/service-endpoints#integration-endpoints) for available endpoints. |
|
|
89
90
|
| `clientId` | `string` | *required* | OAuth client ID |
|
|
90
91
|
| `clientSecret` | `string` | *required* | OAuth client secret |
|
|
91
92
|
| `timeout` | `number` | `10000` | HTTP request timeout in milliseconds |
|
package/dist/index.d.ts
CHANGED
|
@@ -3,8 +3,12 @@ import { NextFunction, Request, Response } from "express";
|
|
|
3
3
|
|
|
4
4
|
//#region src/core/types.d.ts
|
|
5
5
|
interface NyaAccountConfig {
|
|
6
|
-
/**
|
|
7
|
-
|
|
6
|
+
/**
|
|
7
|
+
* SSO service URL (Issuer URL), can be the service or daemon address (default: 'https://account-api.edge.lolinya.net')
|
|
8
|
+
*
|
|
9
|
+
* @see https://account.lolinya.net/docs/developer/service-endpoints#integration-endpoints
|
|
10
|
+
*/
|
|
11
|
+
issuer?: string;
|
|
8
12
|
/** OAuth client ID */
|
|
9
13
|
clientId: string;
|
|
10
14
|
/** OAuth client secret */
|
|
@@ -37,6 +41,7 @@ interface UserInfo {
|
|
|
37
41
|
sub: string;
|
|
38
42
|
name?: string;
|
|
39
43
|
preferredUsername?: string;
|
|
44
|
+
picture?: string;
|
|
40
45
|
email?: string;
|
|
41
46
|
emailVerified?: boolean;
|
|
42
47
|
updatedAt?: number;
|
|
@@ -108,43 +113,6 @@ interface PkcePair {
|
|
|
108
113
|
codeChallenge: string;
|
|
109
114
|
} //#endregion
|
|
110
115
|
//#region src/client.d.ts
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Nya Account Node.js SDK client.
|
|
114
|
-
*
|
|
115
|
-
* Provides full OAuth 2.1 / OIDC flow support:
|
|
116
|
-
* - Authorization Code + PKCE
|
|
117
|
-
* - Token exchange / refresh / revocation / introspection
|
|
118
|
-
* - Local JWT verification (via JWKS)
|
|
119
|
-
* - OIDC UserInfo
|
|
120
|
-
* - OIDC Discovery auto-discovery
|
|
121
|
-
* - Express middleware (Bearer Token auth + scope validation)
|
|
122
|
-
*
|
|
123
|
-
* @example
|
|
124
|
-
* ```typescript
|
|
125
|
-
* const client = new NyaAccountClient({
|
|
126
|
-
* issuer: 'https://account.example.com',
|
|
127
|
-
* clientId: 'my-app',
|
|
128
|
-
* clientSecret: 'my-secret',
|
|
129
|
-
* })
|
|
130
|
-
*
|
|
131
|
-
* // Create authorization URL (with PKCE)
|
|
132
|
-
* const { url, codeVerifier, state } = await client.createAuthorizationUrl({
|
|
133
|
-
* redirectUri: 'https://myapp.com/callback',
|
|
134
|
-
* scope: 'openid profile email',
|
|
135
|
-
* })
|
|
136
|
-
*
|
|
137
|
-
* // Exchange code for tokens
|
|
138
|
-
* const tokens = await client.exchangeCode({
|
|
139
|
-
* code: callbackCode,
|
|
140
|
-
* redirectUri: 'https://myapp.com/callback',
|
|
141
|
-
* codeVerifier,
|
|
142
|
-
* })
|
|
143
|
-
*
|
|
144
|
-
* // Get user info
|
|
145
|
-
* const userInfo = await client.getUserInfo(tokens.accessToken)
|
|
146
|
-
* ```
|
|
147
|
-
*/
|
|
148
116
|
declare class NyaAccountClient {
|
|
149
117
|
private httpClient;
|
|
150
118
|
private config;
|
|
@@ -193,7 +161,7 @@ declare class NyaAccountClient {
|
|
|
193
161
|
* Get user info using an Access Token (OIDC UserInfo Endpoint).
|
|
194
162
|
*
|
|
195
163
|
* The returned fields depend on the scopes included in the token:
|
|
196
|
-
* - `profile`: name, preferredUsername, updatedAt
|
|
164
|
+
* - `profile`: name, preferredUsername, picture, updatedAt
|
|
197
165
|
* - `email`: email, emailVerified
|
|
198
166
|
*/
|
|
199
167
|
getUserInfo(accessToken: string): Promise<UserInfo>;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/core/types.d.ts","../src/client.d.ts","../src/core/errors.d.ts","../src/utils/pkce.d.ts"],"sourcesContent":null,"mappings":";;;;AAEA,IAAW,mBAAmB,CAAC,IAAG,MAAA,cAAA;AAClC,IAAW,
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/core/types.d.ts","../src/client.d.ts","../src/core/errors.d.ts","../src/utils/pkce.d.ts"],"sourcesContent":null,"mappings":";;;;AAEA,IAAW,mBAAmB,CAAC,IAAG,MAAA,cAAA;AAClC,IAAM,iBAAA,CAAA,EAAA;AACN,IAAW,gBAAgB,CAAC,EAAG;AAC/B,IAAK,WAAA,CAAA,EAAA;AACL,IAAW,wBAAwB,CAAC,EAAG;AACvC,IAAM,oBAAA,CAAA,EAAA;AACN,IAAW,gCAAQ,CAAA,EAAA;AACnB,IAAW,yBAAc,CAAA,EAAA;AACzB,IAAW,sBAAS,CAAA,EAAA;AACpB,IAAW,sBAAkB,CAAA,EAAA;AAC7B,IAAW,WAAW,CAAC,EAAC;;;;ACTxB,IAAW,mBAAmB;CAAC;CAAG,MAAI;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;CAAA,MAAA;AAAA;;;;;;;ACAtC,IAAW,kBAAkB,CAAC,IAAI,MAAM,KAAM;;;;AAI9C,IAAA,aAAA,CAAA,IAAA,MAAA,eAAA;;;;AAIA,IAAW,yBAAyB,CAAC,IAAI,MAAM,eAAS;;;;AAIxD,IAAW,iBAAc,CAAA,IAAA,MAAA,eAAA;;;;;;;ACXzB,IAAW,uBAAuB,CAAC,EAAG;;;;AAItC,IAAW,wBAAwB,CAAC,EAAG;;;;AAIvC,IAAW,eAAe,CAAC,IAAI,MAAM,QAAS"}
|
package/dist/index.js
CHANGED
|
@@ -34,6 +34,7 @@ const UserInfoSchema = z.object({
|
|
|
34
34
|
sub: z.string(),
|
|
35
35
|
name: z.string().optional(),
|
|
36
36
|
preferred_username: z.string().optional(),
|
|
37
|
+
picture: z.string().optional(),
|
|
37
38
|
email: z.string().optional(),
|
|
38
39
|
email_verified: z.boolean().optional(),
|
|
39
40
|
updated_at: z.number().optional()
|
|
@@ -242,79 +243,10 @@ const DISCOVERY_ENDPOINT_MAP = {
|
|
|
242
243
|
jwks: "jwksUri",
|
|
243
244
|
endSession: "endSessionEndpoint"
|
|
244
245
|
};
|
|
246
|
+
/** Default issuer URL */
|
|
247
|
+
const DEFAULT_ISSUER = "https://account-api.edge.lolinya.net";
|
|
245
248
|
/** Default discovery cache TTL: 1 hour */
|
|
246
249
|
const DEFAULT_DISCOVERY_CACHE_TTL = 36e5;
|
|
247
|
-
/**
|
|
248
|
-
|
|
249
|
-
* Nya Account Node.js SDK client.
|
|
250
|
-
|
|
251
|
-
*
|
|
252
|
-
|
|
253
|
-
* Provides full OAuth 2.1 / OIDC flow support:
|
|
254
|
-
|
|
255
|
-
* - Authorization Code + PKCE
|
|
256
|
-
|
|
257
|
-
* - Token exchange / refresh / revocation / introspection
|
|
258
|
-
|
|
259
|
-
* - Local JWT verification (via JWKS)
|
|
260
|
-
|
|
261
|
-
* - OIDC UserInfo
|
|
262
|
-
|
|
263
|
-
* - OIDC Discovery auto-discovery
|
|
264
|
-
|
|
265
|
-
* - Express middleware (Bearer Token auth + scope validation)
|
|
266
|
-
|
|
267
|
-
*
|
|
268
|
-
|
|
269
|
-
* @example
|
|
270
|
-
|
|
271
|
-
* ```typescript
|
|
272
|
-
|
|
273
|
-
* const client = new NyaAccountClient({
|
|
274
|
-
|
|
275
|
-
* issuer: 'https://account.example.com',
|
|
276
|
-
|
|
277
|
-
* clientId: 'my-app',
|
|
278
|
-
|
|
279
|
-
* clientSecret: 'my-secret',
|
|
280
|
-
|
|
281
|
-
* })
|
|
282
|
-
|
|
283
|
-
*
|
|
284
|
-
|
|
285
|
-
* // Create authorization URL (with PKCE)
|
|
286
|
-
|
|
287
|
-
* const { url, codeVerifier, state } = await client.createAuthorizationUrl({
|
|
288
|
-
|
|
289
|
-
* redirectUri: 'https://myapp.com/callback',
|
|
290
|
-
|
|
291
|
-
* scope: 'openid profile email',
|
|
292
|
-
|
|
293
|
-
* })
|
|
294
|
-
|
|
295
|
-
*
|
|
296
|
-
|
|
297
|
-
* // Exchange code for tokens
|
|
298
|
-
|
|
299
|
-
* const tokens = await client.exchangeCode({
|
|
300
|
-
|
|
301
|
-
* code: callbackCode,
|
|
302
|
-
|
|
303
|
-
* redirectUri: 'https://myapp.com/callback',
|
|
304
|
-
|
|
305
|
-
* codeVerifier,
|
|
306
|
-
|
|
307
|
-
* })
|
|
308
|
-
|
|
309
|
-
*
|
|
310
|
-
|
|
311
|
-
* // Get user info
|
|
312
|
-
|
|
313
|
-
* const userInfo = await client.getUserInfo(tokens.accessToken)
|
|
314
|
-
|
|
315
|
-
* ```
|
|
316
|
-
|
|
317
|
-
*/
|
|
318
250
|
var NyaAccountClient = class {
|
|
319
251
|
constructor(config) {
|
|
320
252
|
this.httpClient = void 0;
|
|
@@ -323,7 +255,10 @@ var NyaAccountClient = class {
|
|
|
323
255
|
this.discoveryCacheTimestamp = 0;
|
|
324
256
|
this.discoveryCacheTtl = void 0;
|
|
325
257
|
this.jwtVerifier = null;
|
|
326
|
-
this.config =
|
|
258
|
+
this.config = {
|
|
259
|
+
...config,
|
|
260
|
+
issuer: config.issuer ?? DEFAULT_ISSUER
|
|
261
|
+
};
|
|
327
262
|
this.discoveryCacheTtl = config.discoveryCacheTtl ?? DEFAULT_DISCOVERY_CACHE_TTL;
|
|
328
263
|
this.httpClient = axios.create({ timeout: config.timeout ?? 1e4 });
|
|
329
264
|
}
|
|
@@ -511,7 +446,7 @@ var NyaAccountClient = class {
|
|
|
511
446
|
|
|
512
447
|
* The returned fields depend on the scopes included in the token:
|
|
513
448
|
|
|
514
|
-
* - `profile`: name, preferredUsername, updatedAt
|
|
449
|
+
* - `profile`: name, preferredUsername, picture, updatedAt
|
|
515
450
|
|
|
516
451
|
* - `email`: email, emailVerified
|
|
517
452
|
|
|
@@ -525,6 +460,7 @@ var NyaAccountClient = class {
|
|
|
525
460
|
sub: raw.sub,
|
|
526
461
|
name: raw.name,
|
|
527
462
|
preferredUsername: raw.preferred_username,
|
|
463
|
+
picture: raw.picture,
|
|
528
464
|
email: raw.email,
|
|
529
465
|
emailVerified: raw.email_verified,
|
|
530
466
|
updatedAt: raw.updated_at
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["code: string","description: string","error: string","errorDescription: string","codeVerifier: string","jwksUri: string","issuer: string","defaultAudience: string","token: string","audience?: string","options?: { audience?: string; nonce?: string }","error: unknown","tokenType: string","DISCOVERY_ENDPOINT_MAP: Record<EndpointName, keyof DiscoveryDocument>","config: NyaAccountConfig","options: CreateAuthorizationUrlOptions","options: ExchangeCodeOptions","refreshToken: string","token: string","accessToken: string","options?: { audience?: string }","options?: { audience?: string; nonce?: string }","options?: AuthenticateOptions","req: Request","res: Response","next: NextFunction","payload: AccessTokenPayload","name: EndpointName","data: unknown","error: unknown"],"sources":["../src/core/schemas.ts","../src/core/errors.ts","../src/utils/pkce.ts","../src/utils/jwt.ts","../src/client.ts"],"sourcesContent":["import { z } from 'zod'\r\n\r\n// ============================================================\r\n// OAuth Token Response\r\n// ============================================================\r\n\r\nexport const TokenResponseSchema = z.object({\r\n access_token: z.string(),\r\n token_type: z.string(),\r\n expires_in: z.number(),\r\n refresh_token: z.string(),\r\n scope: z.string(),\r\n id_token: z.string().optional(),\r\n})\r\n\r\nexport type TokenResponseRaw = z.infer<typeof TokenResponseSchema>\r\n\r\n// ============================================================\r\n// OAuth Error Response\r\n// ============================================================\r\n\r\nexport const OAuthErrorSchema = z.object({\r\n error: z.string(),\r\n error_description: z.string().optional(),\r\n})\r\n\r\nexport type OAuthErrorRaw = z.infer<typeof OAuthErrorSchema>\r\n\r\n// ============================================================\r\n// Token Introspection Response (RFC 7662)\r\n// ============================================================\r\n\r\nexport const IntrospectionResponseSchema = z.object({\r\n active: z.boolean(),\r\n scope: z.string().optional(),\r\n client_id: z.string().optional(),\r\n username: z.string().optional(),\r\n token_type: z.string().optional(),\r\n exp: z.number().optional(),\r\n iat: z.number().optional(),\r\n sub: z.string().optional(),\r\n aud: z.string().optional(),\r\n iss: z.string().optional(),\r\n jti: z.string().optional(),\r\n})\r\n\r\nexport type IntrospectionResponseRaw = z.infer<typeof IntrospectionResponseSchema>\r\n\r\n// ============================================================\r\n// OIDC UserInfo Response\r\n// ============================================================\r\n\r\nexport const UserInfoSchema = z.object({\r\n sub: z.string(),\r\n name: z.string().optional(),\r\n preferred_username: z.string().optional(),\r\n email: z.string().optional(),\r\n email_verified: z.boolean().optional(),\r\n updated_at: z.number().optional(),\r\n})\r\n\r\nexport type UserInfoRaw = z.infer<typeof UserInfoSchema>\r\n\r\n// ============================================================\r\n// OIDC Discovery Document\r\n// ============================================================\r\n\r\nexport const DiscoveryDocumentSchema = z.object({\r\n issuer: z.string(),\r\n authorization_endpoint: z.string(),\r\n token_endpoint: z.string(),\r\n userinfo_endpoint: z.string().optional(),\r\n jwks_uri: z.string(),\r\n revocation_endpoint: z.string().optional(),\r\n introspection_endpoint: z.string().optional(),\r\n pushed_authorization_request_endpoint: z.string().optional(),\r\n end_session_endpoint: z.string().optional(),\r\n response_types_supported: z.array(z.string()),\r\n grant_types_supported: z.array(z.string()),\r\n id_token_signing_alg_values_supported: z.array(z.string()),\r\n scopes_supported: z.array(z.string()),\r\n subject_types_supported: z.array(z.string()),\r\n token_endpoint_auth_methods_supported: z.array(z.string()),\r\n code_challenge_methods_supported: z.array(z.string()).optional(),\r\n claims_supported: z.array(z.string()).optional(),\r\n dpop_signing_alg_values_supported: z.array(z.string()).optional(),\r\n request_parameter_supported: z.boolean().optional(),\r\n request_uri_parameter_supported: z.boolean().optional(),\r\n})\r\n\r\nexport type DiscoveryDocumentRaw = z.infer<typeof DiscoveryDocumentSchema>\r\n\r\n// ============================================================\r\n// JWT Access Token Payload (RFC 9068)\r\n// ============================================================\r\n\r\nexport const AccessTokenPayloadSchema = z.object({\r\n iss: z.string(),\r\n sub: z.string(),\r\n aud: z.string(),\r\n scope: z.string(),\r\n ver: z.string(),\r\n iat: z.number(),\r\n exp: z.number(),\r\n jti: z.string(),\r\n cnf: z.object({ jkt: z.string() }).optional(),\r\n})\r\n\r\nexport type AccessTokenPayload = z.infer<typeof AccessTokenPayloadSchema>\r\n\r\n// ============================================================\r\n// JWT ID Token Payload (OIDC Core)\r\n// ============================================================\r\n\r\nexport const IdTokenPayloadSchema = z.object({\r\n iss: z.string(),\r\n sub: z.string(),\r\n aud: z.string(),\r\n iat: z.number(),\r\n exp: z.number(),\r\n nonce: z.string().optional(),\r\n name: z.string().optional(),\r\n preferred_username: z.string().optional(),\r\n email: z.string().optional(),\r\n email_verified: z.boolean().optional(),\r\n updated_at: z.number().optional(),\r\n})\r\n\r\nexport type IdTokenPayload = z.infer<typeof IdTokenPayloadSchema>\r\n","/**\r\n * Base error class for the SDK.\r\n */\r\nexport class NyaAccountError extends Error {\r\n readonly code: string\r\n readonly description: string\r\n\r\n constructor(code: string, description: string) {\r\n super(`[${code}] ${description}`)\r\n this.name = 'NyaAccountError'\r\n this.code = code\r\n this.description = description\r\n }\r\n}\r\n\r\n/**\r\n * OAuth protocol error (from server error / error_description response).\r\n */\r\nexport class OAuthError extends NyaAccountError {\r\n constructor(error: string, errorDescription: string) {\r\n super(error, errorDescription)\r\n this.name = 'OAuthError'\r\n }\r\n}\r\n\r\n/**\r\n * JWT verification error.\r\n */\r\nexport class TokenVerificationError extends NyaAccountError {\r\n constructor(description: string) {\r\n super('token_verification_failed', description)\r\n this.name = 'TokenVerificationError'\r\n }\r\n}\r\n\r\n/**\r\n * OIDC Discovery error.\r\n */\r\nexport class DiscoveryError extends NyaAccountError {\r\n constructor(description: string) {\r\n super('discovery_error', description)\r\n this.name = 'DiscoveryError'\r\n }\r\n}\r\n","import { randomBytes, createHash } from 'node:crypto'\r\nimport type { PkcePair } from '@/core/types'\r\n\r\n/**\r\n * Generate a PKCE code_verifier (43-128 character random string).\r\n */\r\nexport function generateCodeVerifier(): string {\r\n return randomBytes(32).toString('base64url')\r\n}\r\n\r\n/**\r\n * Generate an S256 code_challenge from a code_verifier.\r\n */\r\nexport function generateCodeChallenge(codeVerifier: string): string {\r\n return createHash('sha256').update(codeVerifier).digest('base64url')\r\n}\r\n\r\n/**\r\n * Generate a PKCE code_verifier and code_challenge pair.\r\n */\r\nexport function generatePkce(): PkcePair {\r\n const codeVerifier = generateCodeVerifier()\r\n const codeChallenge = generateCodeChallenge(codeVerifier)\r\n return { codeVerifier, codeChallenge }\r\n}\r\n","import { createRemoteJWKSet, jwtVerify, errors as joseErrors } from 'jose'\r\nimport {\r\n AccessTokenPayloadSchema,\r\n IdTokenPayloadSchema,\r\n type AccessTokenPayload,\r\n type IdTokenPayload,\r\n} from '@/core/schemas'\r\nimport { TokenVerificationError } from '@/core/errors'\r\n\r\n/**\r\n * JWT verifier using remote JWKS for signature verification.\r\n */\r\nexport class JwtVerifier {\r\n private jwks: ReturnType<typeof createRemoteJWKSet>\r\n private issuer: string\r\n private defaultAudience: string\r\n\r\n constructor(jwksUri: string, issuer: string, defaultAudience: string) {\r\n this.jwks = createRemoteJWKSet(new URL(jwksUri))\r\n this.issuer = issuer\r\n this.defaultAudience = defaultAudience\r\n }\r\n\r\n /**\r\n * Verify an OAuth 2.0 Access Token (JWT, RFC 9068).\r\n */\r\n async verifyAccessToken(token: string, audience?: string): Promise<AccessTokenPayload> {\r\n try {\r\n const { payload } = await jwtVerify(token, this.jwks, {\r\n algorithms: ['RS256'],\r\n issuer: this.issuer,\r\n audience: audience ?? this.defaultAudience,\r\n })\r\n return AccessTokenPayloadSchema.parse(payload)\r\n } catch (error) {\r\n throw this.wrapError(error, 'Access Token')\r\n }\r\n }\r\n\r\n /**\r\n * Verify an OIDC ID Token.\r\n */\r\n async verifyIdToken(token: string, options?: { audience?: string; nonce?: string }): Promise<IdTokenPayload> {\r\n try {\r\n const { payload } = await jwtVerify(token, this.jwks, {\r\n algorithms: ['RS256'],\r\n issuer: this.issuer,\r\n audience: options?.audience ?? this.defaultAudience,\r\n })\r\n\r\n const parsed = IdTokenPayloadSchema.parse(payload)\r\n\r\n if (options?.nonce !== undefined && parsed.nonce !== options.nonce) {\r\n throw new TokenVerificationError('ID Token nonce mismatch')\r\n }\r\n\r\n return parsed\r\n } catch (error) {\r\n if (error instanceof TokenVerificationError) {\r\n throw error\r\n }\r\n throw this.wrapError(error, 'ID Token')\r\n }\r\n }\r\n\r\n private wrapError(error: unknown, tokenType: string): TokenVerificationError {\r\n if (error instanceof TokenVerificationError) {\r\n return error\r\n }\r\n if (error instanceof joseErrors.JWTExpired) {\r\n return new TokenVerificationError(`${tokenType} has expired`)\r\n }\r\n if (error instanceof joseErrors.JWTClaimValidationFailed) {\r\n return new TokenVerificationError(`${tokenType} claim validation failed: ${error.message}`)\r\n }\r\n if (error instanceof joseErrors.JWSSignatureVerificationFailed) {\r\n return new TokenVerificationError(`${tokenType} signature verification failed`)\r\n }\r\n const message = error instanceof Error ? error.message : 'Unknown error'\r\n return new TokenVerificationError(`${tokenType} verification failed: ${message}`)\r\n }\r\n}\r\n","import axios, { AxiosError, type AxiosInstance } from 'axios'\r\nimport type { Request, Response, NextFunction } from 'express'\r\nimport { randomBytes } from 'node:crypto'\r\nimport {\r\n TokenResponseSchema,\r\n OAuthErrorSchema,\r\n IntrospectionResponseSchema,\r\n UserInfoSchema,\r\n DiscoveryDocumentSchema,\r\n type AccessTokenPayload,\r\n type IdTokenPayload,\r\n} from '@/core/schemas'\r\nimport type {\r\n NyaAccountConfig,\r\n TokenResponse,\r\n UserInfo,\r\n IntrospectionResponse,\r\n DiscoveryDocument,\r\n AuthorizationUrlResult,\r\n CreateAuthorizationUrlOptions,\r\n ExchangeCodeOptions,\r\n AuthenticateOptions,\r\n EndpointConfig,\r\n} from '@/core/types'\r\nimport { OAuthError, DiscoveryError, NyaAccountError } from '@/core/errors'\r\nimport { generateCodeVerifier, generateCodeChallenge } from '@/utils/pkce'\r\nimport { JwtVerifier } from '@/utils/jwt'\r\nimport { setAuth, getAuth, extractBearerToken, sendOAuthError } from '@/middleware/express'\r\n\r\ntype EndpointName = keyof EndpointConfig\r\n\r\nconst DISCOVERY_ENDPOINT_MAP: Record<EndpointName, keyof DiscoveryDocument> = {\r\n authorization: 'authorizationEndpoint',\r\n token: 'tokenEndpoint',\r\n userinfo: 'userinfoEndpoint',\r\n revocation: 'revocationEndpoint',\r\n introspection: 'introspectionEndpoint',\r\n jwks: 'jwksUri',\r\n endSession: 'endSessionEndpoint',\r\n}\r\n\r\n/** Default discovery cache TTL: 1 hour */\r\nconst DEFAULT_DISCOVERY_CACHE_TTL = 3600000\r\n\r\n/**\r\n * Nya Account Node.js SDK client.\r\n *\r\n * Provides full OAuth 2.1 / OIDC flow support:\r\n * - Authorization Code + PKCE\r\n * - Token exchange / refresh / revocation / introspection\r\n * - Local JWT verification (via JWKS)\r\n * - OIDC UserInfo\r\n * - OIDC Discovery auto-discovery\r\n * - Express middleware (Bearer Token auth + scope validation)\r\n *\r\n * @example\r\n * ```typescript\r\n * const client = new NyaAccountClient({\r\n * issuer: 'https://account.example.com',\r\n * clientId: 'my-app',\r\n * clientSecret: 'my-secret',\r\n * })\r\n *\r\n * // Create authorization URL (with PKCE)\r\n * const { url, codeVerifier, state } = await client.createAuthorizationUrl({\r\n * redirectUri: 'https://myapp.com/callback',\r\n * scope: 'openid profile email',\r\n * })\r\n *\r\n * // Exchange code for tokens\r\n * const tokens = await client.exchangeCode({\r\n * code: callbackCode,\r\n * redirectUri: 'https://myapp.com/callback',\r\n * codeVerifier,\r\n * })\r\n *\r\n * // Get user info\r\n * const userInfo = await client.getUserInfo(tokens.accessToken)\r\n * ```\r\n */\r\nexport class NyaAccountClient {\r\n private httpClient: AxiosInstance\r\n private config: NyaAccountConfig\r\n private discoveryCache: DiscoveryDocument | null = null\r\n private discoveryCacheTimestamp = 0\r\n private readonly discoveryCacheTtl: number\r\n private jwtVerifier: JwtVerifier | null = null\r\n\r\n constructor(config: NyaAccountConfig) {\r\n this.config = config\r\n this.discoveryCacheTtl = config.discoveryCacheTtl ?? DEFAULT_DISCOVERY_CACHE_TTL\r\n this.httpClient = axios.create({\r\n timeout: config.timeout ?? 10000,\r\n })\r\n }\r\n\r\n // ============================================================\r\n // OIDC Discovery\r\n // ============================================================\r\n\r\n /**\r\n * Fetch the OIDC Discovery document. Results are cached with a configurable TTL.\r\n */\r\n async discover(): Promise<DiscoveryDocument> {\r\n if (this.discoveryCache && Date.now() - this.discoveryCacheTimestamp < this.discoveryCacheTtl) {\r\n return this.discoveryCache\r\n }\r\n\r\n try {\r\n const url = `${this.config.issuer}/.well-known/openid-configuration`\r\n const response = await this.httpClient.get(url)\r\n const raw = DiscoveryDocumentSchema.parse(response.data)\r\n\r\n this.discoveryCache = {\r\n issuer: raw.issuer,\r\n authorizationEndpoint: raw.authorization_endpoint,\r\n tokenEndpoint: raw.token_endpoint,\r\n userinfoEndpoint: raw.userinfo_endpoint,\r\n jwksUri: raw.jwks_uri,\r\n revocationEndpoint: raw.revocation_endpoint,\r\n introspectionEndpoint: raw.introspection_endpoint,\r\n pushedAuthorizationRequestEndpoint: raw.pushed_authorization_request_endpoint,\r\n endSessionEndpoint: raw.end_session_endpoint,\r\n responseTypesSupported: raw.response_types_supported,\r\n grantTypesSupported: raw.grant_types_supported,\r\n idTokenSigningAlgValuesSupported: raw.id_token_signing_alg_values_supported,\r\n scopesSupported: raw.scopes_supported,\r\n subjectTypesSupported: raw.subject_types_supported,\r\n tokenEndpointAuthMethodsSupported: raw.token_endpoint_auth_methods_supported,\r\n codeChallengeMethodsSupported: raw.code_challenge_methods_supported,\r\n claimsSupported: raw.claims_supported,\r\n }\r\n this.discoveryCacheTimestamp = Date.now()\r\n\r\n return this.discoveryCache\r\n } catch (error) {\r\n if (error instanceof DiscoveryError) throw error\r\n const message = error instanceof Error ? error.message : 'Unknown error'\r\n throw new DiscoveryError(`Failed to fetch OIDC Discovery document: ${message}`)\r\n }\r\n }\r\n\r\n /**\r\n * Clear the cached Discovery document and JWT verifier, forcing a re-fetch on next use.\r\n */\r\n clearCache(): void {\r\n this.discoveryCache = null\r\n this.discoveryCacheTimestamp = 0\r\n this.jwtVerifier = null\r\n }\r\n\r\n // ============================================================\r\n // Authorization URL\r\n // ============================================================\r\n\r\n /**\r\n * Create an OAuth authorization URL (automatically includes PKCE).\r\n *\r\n * The returned `codeVerifier` and `state` must be saved to the session\r\n * for later use in token exchange and CSRF validation.\r\n */\r\n async createAuthorizationUrl(options: CreateAuthorizationUrlOptions): Promise<AuthorizationUrlResult> {\r\n const authorizationEndpoint = await this.resolveEndpoint('authorization')\r\n\r\n const codeVerifier = generateCodeVerifier()\r\n const codeChallenge = generateCodeChallenge(codeVerifier)\r\n const state = options.state ?? randomBytes(16).toString('base64url')\r\n\r\n const params = new URLSearchParams({\r\n client_id: this.config.clientId,\r\n redirect_uri: options.redirectUri,\r\n response_type: 'code',\r\n scope: options.scope ?? 'openid',\r\n state,\r\n code_challenge: codeChallenge,\r\n code_challenge_method: 'S256',\r\n })\r\n\r\n if (options.nonce) {\r\n params.set('nonce', options.nonce)\r\n }\r\n\r\n return {\r\n url: `${authorizationEndpoint}?${params.toString()}`,\r\n codeVerifier,\r\n state,\r\n }\r\n }\r\n\r\n // ============================================================\r\n // Token Operations\r\n // ============================================================\r\n\r\n /**\r\n * Exchange an authorization code for tokens (Authorization Code Grant).\r\n */\r\n async exchangeCode(options: ExchangeCodeOptions): Promise<TokenResponse> {\r\n const tokenEndpoint = await this.resolveEndpoint('token')\r\n\r\n try {\r\n const response = await this.httpClient.post(tokenEndpoint, {\r\n grant_type: 'authorization_code',\r\n code: options.code,\r\n redirect_uri: options.redirectUri,\r\n client_id: this.config.clientId,\r\n client_secret: this.config.clientSecret,\r\n code_verifier: options.codeVerifier,\r\n })\r\n\r\n return this.mapTokenResponse(response.data)\r\n } catch (error) {\r\n throw this.handleTokenError(error)\r\n }\r\n }\r\n\r\n /**\r\n * Refresh an Access Token using a Refresh Token.\r\n */\r\n async refreshToken(refreshToken: string): Promise<TokenResponse> {\r\n const tokenEndpoint = await this.resolveEndpoint('token')\r\n\r\n try {\r\n const response = await this.httpClient.post(tokenEndpoint, {\r\n grant_type: 'refresh_token',\r\n refresh_token: refreshToken,\r\n client_id: this.config.clientId,\r\n client_secret: this.config.clientSecret,\r\n })\r\n\r\n return this.mapTokenResponse(response.data)\r\n } catch (error) {\r\n throw this.handleTokenError(error)\r\n }\r\n }\r\n\r\n /**\r\n * Revoke a token (RFC 7009).\r\n *\r\n * Supports revoking Access Tokens or Refresh Tokens.\r\n * Revoking a Refresh Token also revokes its entire token family.\r\n */\r\n async revokeToken(token: string): Promise<void> {\r\n const revocationEndpoint = await this.resolveEndpoint('revocation')\r\n\r\n try {\r\n await this.httpClient.post(revocationEndpoint, {\r\n token,\r\n client_id: this.config.clientId,\r\n client_secret: this.config.clientSecret,\r\n })\r\n } catch {\r\n // RFC 7009: revocation endpoint always returns 200, ignore errors\r\n }\r\n }\r\n\r\n /**\r\n * Token introspection (RFC 7662).\r\n *\r\n * Query the server for the current state of a token (active status, associated user info, etc.).\r\n */\r\n async introspectToken(token: string): Promise<IntrospectionResponse> {\r\n const introspectionEndpoint = await this.resolveEndpoint('introspection')\r\n\r\n try {\r\n const response = await this.httpClient.post(introspectionEndpoint, {\r\n token,\r\n client_id: this.config.clientId,\r\n client_secret: this.config.clientSecret,\r\n })\r\n\r\n const raw = IntrospectionResponseSchema.parse(response.data)\r\n return {\r\n active: raw.active,\r\n scope: raw.scope,\r\n clientId: raw.client_id,\r\n username: raw.username,\r\n tokenType: raw.token_type,\r\n exp: raw.exp,\r\n iat: raw.iat,\r\n sub: raw.sub,\r\n aud: raw.aud,\r\n iss: raw.iss,\r\n jti: raw.jti,\r\n }\r\n } catch (error) {\r\n throw this.handleTokenError(error)\r\n }\r\n }\r\n\r\n // ============================================================\r\n // OIDC UserInfo\r\n // ============================================================\r\n\r\n /**\r\n * Get user info using an Access Token (OIDC UserInfo Endpoint).\r\n *\r\n * The returned fields depend on the scopes included in the token:\r\n * - `profile`: name, preferredUsername, updatedAt\r\n * - `email`: email, emailVerified\r\n */\r\n async getUserInfo(accessToken: string): Promise<UserInfo> {\r\n const userinfoEndpoint = await this.resolveEndpoint('userinfo')\r\n\r\n try {\r\n const response = await this.httpClient.get(userinfoEndpoint, {\r\n headers: { Authorization: `Bearer ${accessToken}` },\r\n })\r\n\r\n const raw = UserInfoSchema.parse(response.data)\r\n return {\r\n sub: raw.sub,\r\n name: raw.name,\r\n preferredUsername: raw.preferred_username,\r\n email: raw.email,\r\n emailVerified: raw.email_verified,\r\n updatedAt: raw.updated_at,\r\n }\r\n } catch (error) {\r\n throw this.handleTokenError(error)\r\n }\r\n }\r\n\r\n // ============================================================\r\n // Local JWT Verification\r\n // ============================================================\r\n\r\n /**\r\n * Locally verify a JWT Access Token (RFC 9068).\r\n *\r\n * Uses remote JWKS for signature verification, and validates issuer, audience, expiry, etc.\r\n *\r\n * @param token JWT Access Token string\r\n * @param options.audience Custom audience validation value (defaults to clientId)\r\n */\r\n async verifyAccessToken(token: string, options?: { audience?: string }): Promise<AccessTokenPayload> {\r\n const verifier = await this.getJwtVerifier()\r\n return verifier.verifyAccessToken(token, options?.audience)\r\n }\r\n\r\n /**\r\n * Locally verify an OIDC ID Token.\r\n *\r\n * @param token JWT ID Token string\r\n * @param options.audience Custom audience validation value (defaults to clientId)\r\n * @param options.nonce Validate the nonce claim (required if nonce was sent during authorization)\r\n */\r\n async verifyIdToken(token: string, options?: { audience?: string; nonce?: string }): Promise<IdTokenPayload> {\r\n const verifier = await this.getJwtVerifier()\r\n return verifier.verifyIdToken(token, options)\r\n }\r\n\r\n // ============================================================\r\n // Express Middleware\r\n // ============================================================\r\n\r\n /**\r\n * Express middleware: verify the Bearer Token in the request.\r\n *\r\n * After successful verification, use `getAuth(req)` to retrieve the token payload.\r\n *\r\n * @param options.strategy Verification strategy: 'local' (default, JWT local verification) or 'introspection' (remote introspection)\r\n *\r\n * @example\r\n * ```typescript\r\n * import { getAuth } from '@nya-account/node-sdk/express'\r\n *\r\n * app.use('/api', client.authenticate())\r\n *\r\n * app.get('/api/me', (req, res) => {\r\n * const auth = getAuth(req)\r\n * res.json({ userId: auth?.sub })\r\n * })\r\n * ```\r\n */\r\n authenticate(options?: AuthenticateOptions): (req: Request, res: Response, next: NextFunction) => void {\r\n const strategy = options?.strategy ?? 'local'\r\n\r\n return (req: Request, res: Response, next: NextFunction) => {\r\n const token = extractBearerToken(req)\r\n if (!token) {\r\n sendOAuthError(res, 401, 'invalid_token', 'Missing Bearer token in Authorization header')\r\n return\r\n }\r\n\r\n const handleVerification = async (): Promise<void> => {\r\n let payload: AccessTokenPayload\r\n\r\n if (strategy === 'introspection') {\r\n const introspection = await this.introspectToken(token)\r\n if (!introspection.active) {\r\n sendOAuthError(res, 401, 'invalid_token', 'Token is not active')\r\n return\r\n }\r\n payload = {\r\n iss: introspection.iss ?? '',\r\n sub: introspection.sub ?? '',\r\n aud: introspection.aud ?? '',\r\n scope: introspection.scope ?? '',\r\n ver: '1',\r\n iat: introspection.iat ?? 0,\r\n exp: introspection.exp ?? 0,\r\n jti: introspection.jti ?? '',\r\n }\r\n } else {\r\n payload = await this.verifyAccessToken(token)\r\n }\r\n\r\n setAuth(req, payload)\r\n next()\r\n }\r\n\r\n handleVerification().catch(() => {\r\n sendOAuthError(res, 401, 'invalid_token', 'Invalid or expired access token')\r\n })\r\n }\r\n }\r\n\r\n /**\r\n * Express middleware: validate that the token in the request contains the specified scopes.\r\n *\r\n * Must be used after the `authenticate()` middleware.\r\n *\r\n * @example\r\n * ```typescript\r\n * app.get('/api/profile',\r\n * client.authenticate(),\r\n * client.requireScopes('profile'),\r\n * (req, res) => { ... }\r\n * )\r\n * ```\r\n */\r\n requireScopes(...scopes: string[]): (req: Request, res: Response, next: NextFunction) => void {\r\n return (req: Request, res: Response, next: NextFunction) => {\r\n const auth = getAuth(req)\r\n if (!auth) {\r\n sendOAuthError(res, 401, 'invalid_token', 'Request not authenticated')\r\n return\r\n }\r\n\r\n const tokenScopes = auth.scope.split(' ')\r\n const missingScopes = scopes.filter(s => !tokenScopes.includes(s))\r\n\r\n if (missingScopes.length > 0) {\r\n sendOAuthError(res, 403, 'insufficient_scope', `Missing required scopes: ${missingScopes.join(' ')}`)\r\n return\r\n }\r\n\r\n next()\r\n }\r\n }\r\n\r\n // ============================================================\r\n // Private Methods\r\n // ============================================================\r\n\r\n private async resolveEndpoint(name: EndpointName): Promise<string> {\r\n const explicit = this.config.endpoints?.[name]\r\n if (explicit) {\r\n return explicit\r\n }\r\n\r\n const discovery = await this.discover()\r\n const discoveryKey = DISCOVERY_ENDPOINT_MAP[name]\r\n const endpoint = discovery[discoveryKey]\r\n\r\n if (!endpoint || typeof endpoint !== 'string') {\r\n throw new NyaAccountError(\r\n 'endpoint_not_found',\r\n `Endpoint '${name}' not found in Discovery document`,\r\n )\r\n }\r\n\r\n return endpoint\r\n }\r\n\r\n private async getJwtVerifier(): Promise<JwtVerifier> {\r\n if (this.jwtVerifier) {\r\n return this.jwtVerifier\r\n }\r\n\r\n const jwksUri = await this.resolveEndpoint('jwks')\r\n const discovery = await this.discover()\r\n\r\n this.jwtVerifier = new JwtVerifier(jwksUri, discovery.issuer, this.config.clientId)\r\n return this.jwtVerifier\r\n }\r\n\r\n private mapTokenResponse(data: unknown): TokenResponse {\r\n const raw = TokenResponseSchema.parse(data)\r\n return {\r\n accessToken: raw.access_token,\r\n tokenType: raw.token_type,\r\n expiresIn: raw.expires_in,\r\n refreshToken: raw.refresh_token,\r\n scope: raw.scope,\r\n idToken: raw.id_token,\r\n }\r\n }\r\n\r\n private handleTokenError(error: unknown): NyaAccountError {\r\n if (error instanceof NyaAccountError) {\r\n return error\r\n }\r\n\r\n if (error instanceof AxiosError && error.response) {\r\n const parsed = OAuthErrorSchema.safeParse(error.response.data)\r\n if (parsed.success) {\r\n return new OAuthError(\r\n parsed.data.error,\r\n parsed.data.error_description ?? 'Unknown error',\r\n )\r\n }\r\n }\r\n\r\n const message = error instanceof Error ? error.message : 'Unknown error'\r\n return new NyaAccountError('request_failed', `Request failed: ${message}`)\r\n }\r\n}\r\n"],"mappings":";;;;;;;AAMA,MAAa,sBAAsB,EAAE,OAAO;CACxC,cAAc,EAAE,QAAQ;CACxB,YAAY,EAAE,QAAQ;CACtB,YAAY,EAAE,QAAQ;CACtB,eAAe,EAAE,QAAQ;CACzB,OAAO,EAAE,QAAQ;CACjB,UAAU,EAAE,QAAQ,CAAC,UAAU;AAClC,EAAC;AAQF,MAAa,mBAAmB,EAAE,OAAO;CACrC,OAAO,EAAE,QAAQ;CACjB,mBAAmB,EAAE,QAAQ,CAAC,UAAU;AAC3C,EAAC;AAQF,MAAa,8BAA8B,EAAE,OAAO;CAChD,QAAQ,EAAE,SAAS;CACnB,OAAO,EAAE,QAAQ,CAAC,UAAU;CAC5B,WAAW,EAAE,QAAQ,CAAC,UAAU;CAChC,UAAU,EAAE,QAAQ,CAAC,UAAU;CAC/B,YAAY,EAAE,QAAQ,CAAC,UAAU;CACjC,KAAK,EAAE,QAAQ,CAAC,UAAU;CAC1B,KAAK,EAAE,QAAQ,CAAC,UAAU;CAC1B,KAAK,EAAE,QAAQ,CAAC,UAAU;CAC1B,KAAK,EAAE,QAAQ,CAAC,UAAU;CAC1B,KAAK,EAAE,QAAQ,CAAC,UAAU;CAC1B,KAAK,EAAE,QAAQ,CAAC,UAAU;AAC7B,EAAC;AAQF,MAAa,iBAAiB,EAAE,OAAO;CACnC,KAAK,EAAE,QAAQ;CACf,MAAM,EAAE,QAAQ,CAAC,UAAU;CAC3B,oBAAoB,EAAE,QAAQ,CAAC,UAAU;CACzC,OAAO,EAAE,QAAQ,CAAC,UAAU;CAC5B,gBAAgB,EAAE,SAAS,CAAC,UAAU;CACtC,YAAY,EAAE,QAAQ,CAAC,UAAU;AACpC,EAAC;AAQF,MAAa,0BAA0B,EAAE,OAAO;CAC5C,QAAQ,EAAE,QAAQ;CAClB,wBAAwB,EAAE,QAAQ;CAClC,gBAAgB,EAAE,QAAQ;CAC1B,mBAAmB,EAAE,QAAQ,CAAC,UAAU;CACxC,UAAU,EAAE,QAAQ;CACpB,qBAAqB,EAAE,QAAQ,CAAC,UAAU;CAC1C,wBAAwB,EAAE,QAAQ,CAAC,UAAU;CAC7C,uCAAuC,EAAE,QAAQ,CAAC,UAAU;CAC5D,sBAAsB,EAAE,QAAQ,CAAC,UAAU;CAC3C,0BAA0B,EAAE,MAAM,EAAE,QAAQ,CAAC;CAC7C,uBAAuB,EAAE,MAAM,EAAE,QAAQ,CAAC;CAC1C,uCAAuC,EAAE,MAAM,EAAE,QAAQ,CAAC;CAC1D,kBAAkB,EAAE,MAAM,EAAE,QAAQ,CAAC;CACrC,yBAAyB,EAAE,MAAM,EAAE,QAAQ,CAAC;CAC5C,uCAAuC,EAAE,MAAM,EAAE,QAAQ,CAAC;CAC1D,kCAAkC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU;CAChE,kBAAkB,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU;CAChD,mCAAmC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU;CACjE,6BAA6B,EAAE,SAAS,CAAC,UAAU;CACnD,iCAAiC,EAAE,SAAS,CAAC,UAAU;AAC1D,EAAC;AAQF,MAAa,2BAA2B,EAAE,OAAO;CAC7C,KAAK,EAAE,QAAQ;CACf,KAAK,EAAE,QAAQ;CACf,KAAK,EAAE,QAAQ;CACf,OAAO,EAAE,QAAQ;CACjB,KAAK,EAAE,QAAQ;CACf,KAAK,EAAE,QAAQ;CACf,KAAK,EAAE,QAAQ;CACf,KAAK,EAAE,QAAQ;CACf,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAE,EAAC,CAAC,UAAU;AAChD,EAAC;AAQF,MAAa,uBAAuB,EAAE,OAAO;CACzC,KAAK,EAAE,QAAQ;CACf,KAAK,EAAE,QAAQ;CACf,KAAK,EAAE,QAAQ;CACf,KAAK,EAAE,QAAQ;CACf,KAAK,EAAE,QAAQ;CACf,OAAO,EAAE,QAAQ,CAAC,UAAU;CAC5B,MAAM,EAAE,QAAQ,CAAC,UAAU;CAC3B,oBAAoB,EAAE,QAAQ,CAAC,UAAU;CACzC,OAAO,EAAE,QAAQ,CAAC,UAAU;CAC5B,gBAAgB,EAAE,SAAS,CAAC,UAAU;CACtC,YAAY,EAAE,QAAQ,CAAC,UAAU;AACpC,EAAC;;;;;;;;;AC3HF,IAAa,kBAAb,cAAqC,MAAM;CAIvC,YAAYA,MAAcC,aAAqB;AAC3C,SAAO,GAAG,KAAK,IAAI,YAAY,EAAE;OAJ5B,YAAA;OACA,mBAAA;AAIL,OAAK,OAAO;AACZ,OAAK,OAAO;AACZ,OAAK,cAAc;CACtB;AACJ;;;;;;AAKD,IAAa,aAAb,cAAgC,gBAAgB;CAC5C,YAAYC,OAAeC,kBAA0B;AACjD,QAAM,OAAO,iBAAiB;AAC9B,OAAK,OAAO;CACf;AACJ;;;;;;AAKD,IAAa,yBAAb,cAA4C,gBAAgB;CACxD,YAAYF,aAAqB;AAC7B,QAAM,6BAA6B,YAAY;AAC/C,OAAK,OAAO;CACf;AACJ;;;;;;AAKD,IAAa,iBAAb,cAAoC,gBAAgB;CAChD,YAAYA,aAAqB;AAC7B,QAAM,mBAAmB,YAAY;AACrC,OAAK,OAAO;CACf;AACJ;;;;;;;;;ACrCD,SAAgB,uBAA+B;AAC3C,QAAO,YAAY,GAAG,CAAC,SAAS,YAAY;AAC/C;;;;;;AAKD,SAAgB,sBAAsBG,cAA8B;AAChE,QAAO,WAAW,SAAS,CAAC,OAAO,aAAa,CAAC,OAAO,YAAY;AACvE;;;;;;AAKD,SAAgB,eAAyB;CACrC,MAAM,eAAe,sBAAsB;CAC3C,MAAM,gBAAgB,sBAAsB,aAAa;AACzD,QAAO;EAAE;EAAc;CAAe;AACzC;;;;;;;;;ACZD,IAAa,cAAb,MAAyB;CAKrB,YAAYC,SAAiBC,QAAgBC,iBAAyB;OAJ9D,YAAA;OACA,cAAA;OACA,uBAAA;AAGJ,OAAK,OAAO,mBAAmB,IAAI,IAAI,SAAS;AAChD,OAAK,SAAS;AACd,OAAK,kBAAkB;CAC1B;;;;;;CAKD,MAAM,kBAAkBC,OAAeC,UAAgD;AACnF,MAAI;GACA,MAAM,EAAE,SAAS,GAAG,MAAM,UAAU,OAAO,KAAK,MAAM;IAClD,YAAY,CAAC,OAAQ;IACrB,QAAQ,KAAK;IACb,UAAU,YAAY,KAAK;GAC9B,EAAC;AACF,UAAO,yBAAyB,MAAM,QAAQ;EACjD,SAAQ,OAAO;AACZ,SAAM,KAAK,UAAU,OAAO,eAAe;EAC9C;CACJ;;;;;;CAKD,MAAM,cAAcD,OAAeE,SAA0E;AACzG,MAAI;GACA,MAAM,EAAE,SAAS,GAAG,MAAM,UAAU,OAAO,KAAK,MAAM;IAClD,YAAY,CAAC,OAAQ;IACrB,QAAQ,KAAK;IACb,UAAU,SAAS,YAAY,KAAK;GACvC,EAAC;GAEF,MAAM,SAAS,qBAAqB,MAAM,QAAQ;AAElD,OAAI,SAAS,oBAAuB,OAAO,UAAU,QAAQ,MACzD,OAAM,IAAI,uBAAuB;AAGrC,UAAO;EACV,SAAQ,OAAO;AACZ,OAAI,iBAAiB,uBACjB,OAAM;AAEV,SAAM,KAAK,UAAU,OAAO,WAAW;EAC1C;CACJ;CAED,UAAkBC,OAAgBC,WAA2C;AACzE,MAAI,iBAAiB,uBACjB,QAAO;AAEX,MAAI,iBAAiB,OAAW,WAC5B,QAAO,IAAI,wBAAwB,EAAE,UAAU;AAEnD,MAAI,iBAAiB,OAAW,yBAC5B,QAAO,IAAI,wBAAwB,EAAE,UAAU,4BAA4B,MAAM,QAAQ;AAE7F,MAAI,iBAAiB,OAAW,+BAC5B,QAAO,IAAI,wBAAwB,EAAE,UAAU;EAEnD,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,SAAO,IAAI,wBAAwB,EAAE,UAAU,wBAAwB,QAAQ;CAClF;AACJ;;;;AClDD,MAAMC,yBAAwE;CAC1E,eAAe;CACf,OAAO;CACP,UAAU;CACV,YAAY;CACZ,eAAe;CACf,MAAM;CACN,YAAY;AACf;;AAGD,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCpC,IAAa,mBAAb,MAA8B;CAQ1B,YAAYC,QAA0B;OAP9B,kBAAA;OACA,cAAA;OACA,iBAA2C;OAC3C,0BAA0B;OACjB,yBAAA;OACT,cAAkC;AAGtC,OAAK,SAAS;AACd,OAAK,oBAAoB,OAAO,qBAAqB;AACrD,OAAK,aAAa,MAAM,OAAO,EAC3B,SAAS,OAAO,WAAW,IAC9B,EAAC;CACL;;;;;;CASD,MAAM,WAAuC;AACzC,MAAI,KAAK,kBAAkB,KAAK,KAAK,GAAG,KAAK,0BAA0B,KAAK,kBACxE,QAAO,KAAK;AAGhB,MAAI;GACA,MAAM,OAAO,EAAE,KAAK,OAAO,OAAO;GAClC,MAAM,WAAW,MAAM,KAAK,WAAW,IAAI,IAAI;GAC/C,MAAM,MAAM,wBAAwB,MAAM,SAAS,KAAK;AAExD,QAAK,iBAAiB;IAClB,QAAQ,IAAI;IACZ,uBAAuB,IAAI;IAC3B,eAAe,IAAI;IACnB,kBAAkB,IAAI;IACtB,SAAS,IAAI;IACb,oBAAoB,IAAI;IACxB,uBAAuB,IAAI;IAC3B,oCAAoC,IAAI;IACxC,oBAAoB,IAAI;IACxB,wBAAwB,IAAI;IAC5B,qBAAqB,IAAI;IACzB,kCAAkC,IAAI;IACtC,iBAAiB,IAAI;IACrB,uBAAuB,IAAI;IAC3B,mCAAmC,IAAI;IACvC,+BAA+B,IAAI;IACnC,iBAAiB,IAAI;GACxB;AACD,QAAK,0BAA0B,KAAK,KAAK;AAEzC,UAAO,KAAK;EACf,SAAQ,OAAO;AACZ,OAAI,iBAAiB,eAAgB,OAAM;GAC3C,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,SAAM,IAAI,gBAAgB,2CAA2C,QAAQ;EAChF;CACJ;;;;;;CAKD,aAAmB;AACf,OAAK,iBAAiB;AACtB,OAAK,0BAA0B;AAC/B,OAAK,cAAc;CACtB;;;;;;;;;;;;CAYD,MAAM,uBAAuBC,SAAyE;EAClG,MAAM,wBAAwB,MAAM,KAAK,gBAAgB,gBAAgB;EAEzE,MAAM,eAAe,sBAAsB;EAC3C,MAAM,gBAAgB,sBAAsB,aAAa;EACzD,MAAM,QAAQ,QAAQ,SAAS,YAAY,GAAG,CAAC,SAAS,YAAY;EAEpE,MAAM,SAAS,IAAI,gBAAgB;GAC/B,WAAW,KAAK,OAAO;GACvB,cAAc,QAAQ;GACtB,eAAe;GACf,OAAO,QAAQ,SAAS;GACxB;GACA,gBAAgB;GAChB,uBAAuB;EAC1B;AAED,MAAI,QAAQ,MACR,QAAO,IAAI,SAAS,QAAQ,MAAM;AAGtC,SAAO;GACH,MAAM,EAAE,sBAAsB,GAAG,OAAO,UAAU,CAAC;GACnD;GACA;EACH;CACJ;;;;;;CASD,MAAM,aAAaC,SAAsD;EACrE,MAAM,gBAAgB,MAAM,KAAK,gBAAgB,QAAQ;AAEzD,MAAI;GACA,MAAM,WAAW,MAAM,KAAK,WAAW,KAAK,eAAe;IACvD,YAAY;IACZ,MAAM,QAAQ;IACd,cAAc,QAAQ;IACtB,WAAW,KAAK,OAAO;IACvB,eAAe,KAAK,OAAO;IAC3B,eAAe,QAAQ;GAC1B,EAAC;AAEF,UAAO,KAAK,iBAAiB,SAAS,KAAK;EAC9C,SAAQ,OAAO;AACZ,SAAM,KAAK,iBAAiB,MAAM;EACrC;CACJ;;;;;;CAKD,MAAM,aAAaC,cAA8C;EAC7D,MAAM,gBAAgB,MAAM,KAAK,gBAAgB,QAAQ;AAEzD,MAAI;GACA,MAAM,WAAW,MAAM,KAAK,WAAW,KAAK,eAAe;IACvD,YAAY;IACZ,eAAe;IACf,WAAW,KAAK,OAAO;IACvB,eAAe,KAAK,OAAO;GAC9B,EAAC;AAEF,UAAO,KAAK,iBAAiB,SAAS,KAAK;EAC9C,SAAQ,OAAO;AACZ,SAAM,KAAK,iBAAiB,MAAM;EACrC;CACJ;;;;;;;;;;;;CAQD,MAAM,YAAYC,OAA8B;EAC5C,MAAM,qBAAqB,MAAM,KAAK,gBAAgB,aAAa;AAEnE,MAAI;AACA,SAAM,KAAK,WAAW,KAAK,oBAAoB;IAC3C;IACA,WAAW,KAAK,OAAO;IACvB,eAAe,KAAK,OAAO;GAC9B,EAAC;EACL,QAAO,CAEP;CACJ;;;;;;;;;;CAOD,MAAM,gBAAgBA,OAA+C;EACjE,MAAM,wBAAwB,MAAM,KAAK,gBAAgB,gBAAgB;AAEzE,MAAI;GACA,MAAM,WAAW,MAAM,KAAK,WAAW,KAAK,uBAAuB;IAC/D;IACA,WAAW,KAAK,OAAO;IACvB,eAAe,KAAK,OAAO;GAC9B,EAAC;GAEF,MAAM,MAAM,4BAA4B,MAAM,SAAS,KAAK;AAC5D,UAAO;IACH,QAAQ,IAAI;IACZ,OAAO,IAAI;IACX,UAAU,IAAI;IACd,UAAU,IAAI;IACd,WAAW,IAAI;IACf,KAAK,IAAI;IACT,KAAK,IAAI;IACT,KAAK,IAAI;IACT,KAAK,IAAI;IACT,KAAK,IAAI;IACT,KAAK,IAAI;GACZ;EACJ,SAAQ,OAAO;AACZ,SAAM,KAAK,iBAAiB,MAAM;EACrC;CACJ;;;;;;;;;;;;;;CAaD,MAAM,YAAYC,aAAwC;EACtD,MAAM,mBAAmB,MAAM,KAAK,gBAAgB,WAAW;AAE/D,MAAI;GACA,MAAM,WAAW,MAAM,KAAK,WAAW,IAAI,kBAAkB,EACzD,SAAS,EAAE,gBAAgB,SAAS,YAAY,EAAG,EACtD,EAAC;GAEF,MAAM,MAAM,eAAe,MAAM,SAAS,KAAK;AAC/C,UAAO;IACH,KAAK,IAAI;IACT,MAAM,IAAI;IACV,mBAAmB,IAAI;IACvB,OAAO,IAAI;IACX,eAAe,IAAI;IACnB,WAAW,IAAI;GAClB;EACJ,SAAQ,OAAO;AACZ,SAAM,KAAK,iBAAiB,MAAM;EACrC;CACJ;;;;;;;;;;;;;;;;CAcD,MAAM,kBAAkBD,OAAeE,SAA8D;EACjG,MAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,SAAO,SAAS,kBAAkB,OAAO,SAAS,SAAS;CAC9D;;;;;;;;;;;;;;CASD,MAAM,cAAcF,OAAeG,SAA0E;EACzG,MAAM,WAAW,MAAM,KAAK,gBAAgB;AAC5C,SAAO,SAAS,cAAc,OAAO,QAAQ;CAChD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyBD,aAAaC,SAA0F;EACnG,MAAM,WAAW,SAAS,YAAY;AAEtC,SAAO,CAACC,KAAcC,KAAeC,SAAuB;GACxD,MAAM,QAAQ,mBAAmB,IAAI;AACrC,QAAK,OAAO;AACR,mBAAe,KAAK,KAAK,iBAAiB,+CAA+C;AACzF;GACH;GAED,MAAM,qBAAqB,YAA2B;IAClD,IAAIC;AAEJ,QAAI,aAAa,iBAAiB;KAC9B,MAAM,gBAAgB,MAAM,KAAK,gBAAgB,MAAM;AACvD,UAAK,cAAc,QAAQ;AACvB,qBAAe,KAAK,KAAK,iBAAiB,sBAAsB;AAChE;KACH;AACD,eAAU;MACN,KAAK,cAAc,OAAO;MAC1B,KAAK,cAAc,OAAO;MAC1B,KAAK,cAAc,OAAO;MAC1B,OAAO,cAAc,SAAS;MAC9B,KAAK;MACL,KAAK,cAAc,OAAO;MAC1B,KAAK,cAAc,OAAO;MAC1B,KAAK,cAAc,OAAO;KAC7B;IACJ,MACG,WAAU,MAAM,KAAK,kBAAkB,MAAM;AAGjD,YAAQ,KAAK,QAAQ;AACrB,UAAM;GACT;AAED,uBAAoB,CAAC,MAAM,MAAM;AAC7B,mBAAe,KAAK,KAAK,iBAAiB,kCAAkC;GAC/E,EAAC;EACL;CACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgBD,cAAc,GAAG,QAA6E;AAC1F,SAAO,CAACH,KAAcC,KAAeC,SAAuB;GACxD,MAAM,OAAO,QAAQ,IAAI;AACzB,QAAK,MAAM;AACP,mBAAe,KAAK,KAAK,iBAAiB,4BAA4B;AACtE;GACH;GAED,MAAM,cAAc,KAAK,MAAM,MAAM,IAAI;GACzC,MAAM,gBAAgB,OAAO,OAAO,CAAA,OAAM,YAAY,SAAS,EAAE,CAAC;AAElE,OAAI,cAAc,SAAS,GAAG;AAC1B,mBAAe,KAAK,KAAK,uBAAuB,2BAA2B,cAAc,KAAK,IAAI,CAAC,EAAE;AACrG;GACH;AAED,SAAM;EACT;CACJ;CAMD,MAAc,gBAAgBE,MAAqC;EAC/D,MAAM,WAAW,KAAK,OAAO,YAAY;AACzC,MAAI,SACA,QAAO;EAGX,MAAM,YAAY,MAAM,KAAK,UAAU;EACvC,MAAM,eAAe,uBAAuB;EAC5C,MAAM,WAAW,UAAU;AAE3B,OAAK,mBAAmB,aAAa,SACjC,OAAM,IAAI,gBACN,uBACC,YAAY,KAAK;AAI1B,SAAO;CACV;CAED,MAAc,iBAAuC;AACjD,MAAI,KAAK,YACL,QAAO,KAAK;EAGhB,MAAM,UAAU,MAAM,KAAK,gBAAgB,OAAO;EAClD,MAAM,YAAY,MAAM,KAAK,UAAU;AAEvC,OAAK,cAAc,IAAI,YAAY,SAAS,UAAU,QAAQ,KAAK,OAAO;AAC1E,SAAO,KAAK;CACf;CAED,iBAAyBC,MAA8B;EACnD,MAAM,MAAM,oBAAoB,MAAM,KAAK;AAC3C,SAAO;GACH,aAAa,IAAI;GACjB,WAAW,IAAI;GACf,WAAW,IAAI;GACf,cAAc,IAAI;GAClB,OAAO,IAAI;GACX,SAAS,IAAI;EAChB;CACJ;CAED,iBAAyBC,OAAiC;AACtD,MAAI,iBAAiB,gBACjB,QAAO;AAGX,MAAI,iBAAiB,cAAc,MAAM,UAAU;GAC/C,MAAM,SAAS,iBAAiB,UAAU,MAAM,SAAS,KAAK;AAC9D,OAAI,OAAO,QACP,QAAO,IAAI,WACP,OAAO,KAAK,OACZ,OAAO,KAAK,qBAAqB;EAG5C;EAED,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,SAAO,IAAI,gBAAgB,mBAAmB,kBAAkB,QAAQ;CAC3E;AACJ"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["code: string","description: string","error: string","errorDescription: string","codeVerifier: string","jwksUri: string","issuer: string","defaultAudience: string","token: string","audience?: string","options?: { audience?: string; nonce?: string }","error: unknown","tokenType: string","DISCOVERY_ENDPOINT_MAP: Record<EndpointName, keyof DiscoveryDocument>","config: NyaAccountConfig","options: CreateAuthorizationUrlOptions","options: ExchangeCodeOptions","refreshToken: string","token: string","accessToken: string","options?: { audience?: string }","options?: { audience?: string; nonce?: string }","options?: AuthenticateOptions","req: Request","res: Response","next: NextFunction","payload: AccessTokenPayload","name: EndpointName","data: unknown","error: unknown"],"sources":["../src/core/schemas.ts","../src/core/errors.ts","../src/utils/pkce.ts","../src/utils/jwt.ts","../src/client.ts"],"sourcesContent":["import { z } from 'zod'\r\n\r\n// ============================================================\r\n// OAuth Token Response\r\n// ============================================================\r\n\r\nexport const TokenResponseSchema = z.object({\r\n access_token: z.string(),\r\n token_type: z.string(),\r\n expires_in: z.number(),\r\n refresh_token: z.string(),\r\n scope: z.string(),\r\n id_token: z.string().optional(),\r\n})\r\n\r\nexport type TokenResponseRaw = z.infer<typeof TokenResponseSchema>\r\n\r\n// ============================================================\r\n// OAuth Error Response\r\n// ============================================================\r\n\r\nexport const OAuthErrorSchema = z.object({\r\n error: z.string(),\r\n error_description: z.string().optional(),\r\n})\r\n\r\nexport type OAuthErrorRaw = z.infer<typeof OAuthErrorSchema>\r\n\r\n// ============================================================\r\n// Token Introspection Response (RFC 7662)\r\n// ============================================================\r\n\r\nexport const IntrospectionResponseSchema = z.object({\r\n active: z.boolean(),\r\n scope: z.string().optional(),\r\n client_id: z.string().optional(),\r\n username: z.string().optional(),\r\n token_type: z.string().optional(),\r\n exp: z.number().optional(),\r\n iat: z.number().optional(),\r\n sub: z.string().optional(),\r\n aud: z.string().optional(),\r\n iss: z.string().optional(),\r\n jti: z.string().optional(),\r\n})\r\n\r\nexport type IntrospectionResponseRaw = z.infer<typeof IntrospectionResponseSchema>\r\n\r\n// ============================================================\r\n// OIDC UserInfo Response\r\n// ============================================================\r\n\r\nexport const UserInfoSchema = z.object({\r\n sub: z.string(),\r\n name: z.string().optional(),\r\n preferred_username: z.string().optional(),\r\n picture: z.string().optional(),\r\n email: z.string().optional(),\r\n email_verified: z.boolean().optional(),\r\n updated_at: z.number().optional(),\r\n})\r\n\r\nexport type UserInfoRaw = z.infer<typeof UserInfoSchema>\r\n\r\n// ============================================================\r\n// OIDC Discovery Document\r\n// ============================================================\r\n\r\nexport const DiscoveryDocumentSchema = z.object({\r\n issuer: z.string(),\r\n authorization_endpoint: z.string(),\r\n token_endpoint: z.string(),\r\n userinfo_endpoint: z.string().optional(),\r\n jwks_uri: z.string(),\r\n revocation_endpoint: z.string().optional(),\r\n introspection_endpoint: z.string().optional(),\r\n pushed_authorization_request_endpoint: z.string().optional(),\r\n end_session_endpoint: z.string().optional(),\r\n response_types_supported: z.array(z.string()),\r\n grant_types_supported: z.array(z.string()),\r\n id_token_signing_alg_values_supported: z.array(z.string()),\r\n scopes_supported: z.array(z.string()),\r\n subject_types_supported: z.array(z.string()),\r\n token_endpoint_auth_methods_supported: z.array(z.string()),\r\n code_challenge_methods_supported: z.array(z.string()).optional(),\r\n claims_supported: z.array(z.string()).optional(),\r\n dpop_signing_alg_values_supported: z.array(z.string()).optional(),\r\n request_parameter_supported: z.boolean().optional(),\r\n request_uri_parameter_supported: z.boolean().optional(),\r\n})\r\n\r\nexport type DiscoveryDocumentRaw = z.infer<typeof DiscoveryDocumentSchema>\r\n\r\n// ============================================================\r\n// JWT Access Token Payload (RFC 9068)\r\n// ============================================================\r\n\r\nexport const AccessTokenPayloadSchema = z.object({\r\n iss: z.string(),\r\n sub: z.string(),\r\n aud: z.string(),\r\n scope: z.string(),\r\n ver: z.string(),\r\n iat: z.number(),\r\n exp: z.number(),\r\n jti: z.string(),\r\n cnf: z.object({ jkt: z.string() }).optional(),\r\n})\r\n\r\nexport type AccessTokenPayload = z.infer<typeof AccessTokenPayloadSchema>\r\n\r\n// ============================================================\r\n// JWT ID Token Payload (OIDC Core)\r\n// ============================================================\r\n\r\nexport const IdTokenPayloadSchema = z.object({\r\n iss: z.string(),\r\n sub: z.string(),\r\n aud: z.string(),\r\n iat: z.number(),\r\n exp: z.number(),\r\n nonce: z.string().optional(),\r\n name: z.string().optional(),\r\n preferred_username: z.string().optional(),\r\n email: z.string().optional(),\r\n email_verified: z.boolean().optional(),\r\n updated_at: z.number().optional(),\r\n})\r\n\r\nexport type IdTokenPayload = z.infer<typeof IdTokenPayloadSchema>\r\n","/**\r\n * Base error class for the SDK.\r\n */\r\nexport class NyaAccountError extends Error {\r\n readonly code: string\r\n readonly description: string\r\n\r\n constructor(code: string, description: string) {\r\n super(`[${code}] ${description}`)\r\n this.name = 'NyaAccountError'\r\n this.code = code\r\n this.description = description\r\n }\r\n}\r\n\r\n/**\r\n * OAuth protocol error (from server error / error_description response).\r\n */\r\nexport class OAuthError extends NyaAccountError {\r\n constructor(error: string, errorDescription: string) {\r\n super(error, errorDescription)\r\n this.name = 'OAuthError'\r\n }\r\n}\r\n\r\n/**\r\n * JWT verification error.\r\n */\r\nexport class TokenVerificationError extends NyaAccountError {\r\n constructor(description: string) {\r\n super('token_verification_failed', description)\r\n this.name = 'TokenVerificationError'\r\n }\r\n}\r\n\r\n/**\r\n * OIDC Discovery error.\r\n */\r\nexport class DiscoveryError extends NyaAccountError {\r\n constructor(description: string) {\r\n super('discovery_error', description)\r\n this.name = 'DiscoveryError'\r\n }\r\n}\r\n","import { randomBytes, createHash } from 'node:crypto'\r\nimport type { PkcePair } from '@/core/types'\r\n\r\n/**\r\n * Generate a PKCE code_verifier (43-128 character random string).\r\n */\r\nexport function generateCodeVerifier(): string {\r\n return randomBytes(32).toString('base64url')\r\n}\r\n\r\n/**\r\n * Generate an S256 code_challenge from a code_verifier.\r\n */\r\nexport function generateCodeChallenge(codeVerifier: string): string {\r\n return createHash('sha256').update(codeVerifier).digest('base64url')\r\n}\r\n\r\n/**\r\n * Generate a PKCE code_verifier and code_challenge pair.\r\n */\r\nexport function generatePkce(): PkcePair {\r\n const codeVerifier = generateCodeVerifier()\r\n const codeChallenge = generateCodeChallenge(codeVerifier)\r\n return { codeVerifier, codeChallenge }\r\n}\r\n","import { createRemoteJWKSet, jwtVerify, errors as joseErrors } from 'jose'\r\nimport {\r\n AccessTokenPayloadSchema,\r\n IdTokenPayloadSchema,\r\n type AccessTokenPayload,\r\n type IdTokenPayload,\r\n} from '@/core/schemas'\r\nimport { TokenVerificationError } from '@/core/errors'\r\n\r\n/**\r\n * JWT verifier using remote JWKS for signature verification.\r\n */\r\nexport class JwtVerifier {\r\n private jwks: ReturnType<typeof createRemoteJWKSet>\r\n private issuer: string\r\n private defaultAudience: string\r\n\r\n constructor(jwksUri: string, issuer: string, defaultAudience: string) {\r\n this.jwks = createRemoteJWKSet(new URL(jwksUri))\r\n this.issuer = issuer\r\n this.defaultAudience = defaultAudience\r\n }\r\n\r\n /**\r\n * Verify an OAuth 2.0 Access Token (JWT, RFC 9068).\r\n */\r\n async verifyAccessToken(token: string, audience?: string): Promise<AccessTokenPayload> {\r\n try {\r\n const { payload } = await jwtVerify(token, this.jwks, {\r\n algorithms: ['RS256'],\r\n issuer: this.issuer,\r\n audience: audience ?? this.defaultAudience,\r\n })\r\n return AccessTokenPayloadSchema.parse(payload)\r\n } catch (error) {\r\n throw this.wrapError(error, 'Access Token')\r\n }\r\n }\r\n\r\n /**\r\n * Verify an OIDC ID Token.\r\n */\r\n async verifyIdToken(token: string, options?: { audience?: string; nonce?: string }): Promise<IdTokenPayload> {\r\n try {\r\n const { payload } = await jwtVerify(token, this.jwks, {\r\n algorithms: ['RS256'],\r\n issuer: this.issuer,\r\n audience: options?.audience ?? this.defaultAudience,\r\n })\r\n\r\n const parsed = IdTokenPayloadSchema.parse(payload)\r\n\r\n if (options?.nonce !== undefined && parsed.nonce !== options.nonce) {\r\n throw new TokenVerificationError('ID Token nonce mismatch')\r\n }\r\n\r\n return parsed\r\n } catch (error) {\r\n if (error instanceof TokenVerificationError) {\r\n throw error\r\n }\r\n throw this.wrapError(error, 'ID Token')\r\n }\r\n }\r\n\r\n private wrapError(error: unknown, tokenType: string): TokenVerificationError {\r\n if (error instanceof TokenVerificationError) {\r\n return error\r\n }\r\n if (error instanceof joseErrors.JWTExpired) {\r\n return new TokenVerificationError(`${tokenType} has expired`)\r\n }\r\n if (error instanceof joseErrors.JWTClaimValidationFailed) {\r\n return new TokenVerificationError(`${tokenType} claim validation failed: ${error.message}`)\r\n }\r\n if (error instanceof joseErrors.JWSSignatureVerificationFailed) {\r\n return new TokenVerificationError(`${tokenType} signature verification failed`)\r\n }\r\n const message = error instanceof Error ? error.message : 'Unknown error'\r\n return new TokenVerificationError(`${tokenType} verification failed: ${message}`)\r\n }\r\n}\r\n","import axios, { AxiosError, type AxiosInstance } from 'axios'\r\nimport type { Request, Response, NextFunction } from 'express'\r\nimport { randomBytes } from 'node:crypto'\r\nimport {\r\n TokenResponseSchema,\r\n OAuthErrorSchema,\r\n IntrospectionResponseSchema,\r\n UserInfoSchema,\r\n DiscoveryDocumentSchema,\r\n type AccessTokenPayload,\r\n type IdTokenPayload,\r\n} from '@/core/schemas'\r\nimport type {\r\n NyaAccountConfig,\r\n TokenResponse,\r\n UserInfo,\r\n IntrospectionResponse,\r\n DiscoveryDocument,\r\n AuthorizationUrlResult,\r\n CreateAuthorizationUrlOptions,\r\n ExchangeCodeOptions,\r\n AuthenticateOptions,\r\n EndpointConfig,\r\n} from '@/core/types'\r\nimport { OAuthError, DiscoveryError, NyaAccountError } from '@/core/errors'\r\nimport { generateCodeVerifier, generateCodeChallenge } from '@/utils/pkce'\r\nimport { JwtVerifier } from '@/utils/jwt'\r\nimport { setAuth, getAuth, extractBearerToken, sendOAuthError } from '@/middleware/express'\r\n\r\ntype EndpointName = keyof EndpointConfig\r\n\r\nconst DISCOVERY_ENDPOINT_MAP: Record<EndpointName, keyof DiscoveryDocument> = {\r\n authorization: 'authorizationEndpoint',\r\n token: 'tokenEndpoint',\r\n userinfo: 'userinfoEndpoint',\r\n revocation: 'revocationEndpoint',\r\n introspection: 'introspectionEndpoint',\r\n jwks: 'jwksUri',\r\n endSession: 'endSessionEndpoint',\r\n}\r\n\r\n/** Default issuer URL */\r\nconst DEFAULT_ISSUER = 'https://account-api.edge.lolinya.net'\r\n\r\n/** Default discovery cache TTL: 1 hour */\r\nconst DEFAULT_DISCOVERY_CACHE_TTL = 3600000\r\n\r\n/**\r\n * Nya Account Node.js SDK client.\r\n *\r\n * Provides full OAuth 2.1 / OIDC flow support:\r\n * - Authorization Code + PKCE\r\n * - Token exchange / refresh / revocation / introspection\r\n * - Local JWT verification (via JWKS)\r\n * - OIDC UserInfo\r\n * - OIDC Discovery auto-discovery\r\n * - Express middleware (Bearer Token auth + scope validation)\r\n *\r\n * @example\r\n * ```typescript\r\n * const client = new NyaAccountClient({\r\n * issuer: 'https://account.example.com',\r\n * clientId: 'my-app',\r\n * clientSecret: 'my-secret',\r\n * })\r\n *\r\n * // Create authorization URL (with PKCE)\r\n * const { url, codeVerifier, state } = await client.createAuthorizationUrl({\r\n * redirectUri: 'https://myapp.com/callback',\r\n * scope: 'openid profile email',\r\n * })\r\n *\r\n * // Exchange code for tokens\r\n * const tokens = await client.exchangeCode({\r\n * code: callbackCode,\r\n * redirectUri: 'https://myapp.com/callback',\r\n * codeVerifier,\r\n * })\r\n *\r\n * // Get user info\r\n * const userInfo = await client.getUserInfo(tokens.accessToken)\r\n * ```\r\n */\r\ntype ResolvedConfig = NyaAccountConfig & { issuer: string }\r\n\r\nexport class NyaAccountClient {\r\n private httpClient: AxiosInstance\r\n private config: ResolvedConfig\r\n private discoveryCache: DiscoveryDocument | null = null\r\n private discoveryCacheTimestamp = 0\r\n private readonly discoveryCacheTtl: number\r\n private jwtVerifier: JwtVerifier | null = null\r\n\r\n constructor(config: NyaAccountConfig) {\r\n this.config = {\r\n ...config,\r\n issuer: config.issuer ?? DEFAULT_ISSUER,\r\n }\r\n this.discoveryCacheTtl = config.discoveryCacheTtl ?? DEFAULT_DISCOVERY_CACHE_TTL\r\n this.httpClient = axios.create({\r\n timeout: config.timeout ?? 10000,\r\n })\r\n }\r\n\r\n // ============================================================\r\n // OIDC Discovery\r\n // ============================================================\r\n\r\n /**\r\n * Fetch the OIDC Discovery document. Results are cached with a configurable TTL.\r\n */\r\n async discover(): Promise<DiscoveryDocument> {\r\n if (this.discoveryCache && Date.now() - this.discoveryCacheTimestamp < this.discoveryCacheTtl) {\r\n return this.discoveryCache\r\n }\r\n\r\n try {\r\n const url = `${this.config.issuer}/.well-known/openid-configuration`\r\n const response = await this.httpClient.get(url)\r\n const raw = DiscoveryDocumentSchema.parse(response.data)\r\n\r\n this.discoveryCache = {\r\n issuer: raw.issuer,\r\n authorizationEndpoint: raw.authorization_endpoint,\r\n tokenEndpoint: raw.token_endpoint,\r\n userinfoEndpoint: raw.userinfo_endpoint,\r\n jwksUri: raw.jwks_uri,\r\n revocationEndpoint: raw.revocation_endpoint,\r\n introspectionEndpoint: raw.introspection_endpoint,\r\n pushedAuthorizationRequestEndpoint: raw.pushed_authorization_request_endpoint,\r\n endSessionEndpoint: raw.end_session_endpoint,\r\n responseTypesSupported: raw.response_types_supported,\r\n grantTypesSupported: raw.grant_types_supported,\r\n idTokenSigningAlgValuesSupported: raw.id_token_signing_alg_values_supported,\r\n scopesSupported: raw.scopes_supported,\r\n subjectTypesSupported: raw.subject_types_supported,\r\n tokenEndpointAuthMethodsSupported: raw.token_endpoint_auth_methods_supported,\r\n codeChallengeMethodsSupported: raw.code_challenge_methods_supported,\r\n claimsSupported: raw.claims_supported,\r\n }\r\n this.discoveryCacheTimestamp = Date.now()\r\n\r\n return this.discoveryCache\r\n } catch (error) {\r\n if (error instanceof DiscoveryError) throw error\r\n const message = error instanceof Error ? error.message : 'Unknown error'\r\n throw new DiscoveryError(`Failed to fetch OIDC Discovery document: ${message}`)\r\n }\r\n }\r\n\r\n /**\r\n * Clear the cached Discovery document and JWT verifier, forcing a re-fetch on next use.\r\n */\r\n clearCache(): void {\r\n this.discoveryCache = null\r\n this.discoveryCacheTimestamp = 0\r\n this.jwtVerifier = null\r\n }\r\n\r\n // ============================================================\r\n // Authorization URL\r\n // ============================================================\r\n\r\n /**\r\n * Create an OAuth authorization URL (automatically includes PKCE).\r\n *\r\n * The returned `codeVerifier` and `state` must be saved to the session\r\n * for later use in token exchange and CSRF validation.\r\n */\r\n async createAuthorizationUrl(options: CreateAuthorizationUrlOptions): Promise<AuthorizationUrlResult> {\r\n const authorizationEndpoint = await this.resolveEndpoint('authorization')\r\n\r\n const codeVerifier = generateCodeVerifier()\r\n const codeChallenge = generateCodeChallenge(codeVerifier)\r\n const state = options.state ?? randomBytes(16).toString('base64url')\r\n\r\n const params = new URLSearchParams({\r\n client_id: this.config.clientId,\r\n redirect_uri: options.redirectUri,\r\n response_type: 'code',\r\n scope: options.scope ?? 'openid',\r\n state,\r\n code_challenge: codeChallenge,\r\n code_challenge_method: 'S256',\r\n })\r\n\r\n if (options.nonce) {\r\n params.set('nonce', options.nonce)\r\n }\r\n\r\n return {\r\n url: `${authorizationEndpoint}?${params.toString()}`,\r\n codeVerifier,\r\n state,\r\n }\r\n }\r\n\r\n // ============================================================\r\n // Token Operations\r\n // ============================================================\r\n\r\n /**\r\n * Exchange an authorization code for tokens (Authorization Code Grant).\r\n */\r\n async exchangeCode(options: ExchangeCodeOptions): Promise<TokenResponse> {\r\n const tokenEndpoint = await this.resolveEndpoint('token')\r\n\r\n try {\r\n const response = await this.httpClient.post(tokenEndpoint, {\r\n grant_type: 'authorization_code',\r\n code: options.code,\r\n redirect_uri: options.redirectUri,\r\n client_id: this.config.clientId,\r\n client_secret: this.config.clientSecret,\r\n code_verifier: options.codeVerifier,\r\n })\r\n\r\n return this.mapTokenResponse(response.data)\r\n } catch (error) {\r\n throw this.handleTokenError(error)\r\n }\r\n }\r\n\r\n /**\r\n * Refresh an Access Token using a Refresh Token.\r\n */\r\n async refreshToken(refreshToken: string): Promise<TokenResponse> {\r\n const tokenEndpoint = await this.resolveEndpoint('token')\r\n\r\n try {\r\n const response = await this.httpClient.post(tokenEndpoint, {\r\n grant_type: 'refresh_token',\r\n refresh_token: refreshToken,\r\n client_id: this.config.clientId,\r\n client_secret: this.config.clientSecret,\r\n })\r\n\r\n return this.mapTokenResponse(response.data)\r\n } catch (error) {\r\n throw this.handleTokenError(error)\r\n }\r\n }\r\n\r\n /**\r\n * Revoke a token (RFC 7009).\r\n *\r\n * Supports revoking Access Tokens or Refresh Tokens.\r\n * Revoking a Refresh Token also revokes its entire token family.\r\n */\r\n async revokeToken(token: string): Promise<void> {\r\n const revocationEndpoint = await this.resolveEndpoint('revocation')\r\n\r\n try {\r\n await this.httpClient.post(revocationEndpoint, {\r\n token,\r\n client_id: this.config.clientId,\r\n client_secret: this.config.clientSecret,\r\n })\r\n } catch {\r\n // RFC 7009: revocation endpoint always returns 200, ignore errors\r\n }\r\n }\r\n\r\n /**\r\n * Token introspection (RFC 7662).\r\n *\r\n * Query the server for the current state of a token (active status, associated user info, etc.).\r\n */\r\n async introspectToken(token: string): Promise<IntrospectionResponse> {\r\n const introspectionEndpoint = await this.resolveEndpoint('introspection')\r\n\r\n try {\r\n const response = await this.httpClient.post(introspectionEndpoint, {\r\n token,\r\n client_id: this.config.clientId,\r\n client_secret: this.config.clientSecret,\r\n })\r\n\r\n const raw = IntrospectionResponseSchema.parse(response.data)\r\n return {\r\n active: raw.active,\r\n scope: raw.scope,\r\n clientId: raw.client_id,\r\n username: raw.username,\r\n tokenType: raw.token_type,\r\n exp: raw.exp,\r\n iat: raw.iat,\r\n sub: raw.sub,\r\n aud: raw.aud,\r\n iss: raw.iss,\r\n jti: raw.jti,\r\n }\r\n } catch (error) {\r\n throw this.handleTokenError(error)\r\n }\r\n }\r\n\r\n // ============================================================\r\n // OIDC UserInfo\r\n // ============================================================\r\n\r\n /**\r\n * Get user info using an Access Token (OIDC UserInfo Endpoint).\r\n *\r\n * The returned fields depend on the scopes included in the token:\r\n * - `profile`: name, preferredUsername, picture, updatedAt\r\n * - `email`: email, emailVerified\r\n */\r\n async getUserInfo(accessToken: string): Promise<UserInfo> {\r\n const userinfoEndpoint = await this.resolveEndpoint('userinfo')\r\n\r\n try {\r\n const response = await this.httpClient.get(userinfoEndpoint, {\r\n headers: { Authorization: `Bearer ${accessToken}` },\r\n })\r\n\r\n const raw = UserInfoSchema.parse(response.data)\r\n return {\r\n sub: raw.sub,\r\n name: raw.name,\r\n preferredUsername: raw.preferred_username,\r\n picture: raw.picture,\r\n email: raw.email,\r\n emailVerified: raw.email_verified,\r\n updatedAt: raw.updated_at,\r\n }\r\n } catch (error) {\r\n throw this.handleTokenError(error)\r\n }\r\n }\r\n\r\n // ============================================================\r\n // Local JWT Verification\r\n // ============================================================\r\n\r\n /**\r\n * Locally verify a JWT Access Token (RFC 9068).\r\n *\r\n * Uses remote JWKS for signature verification, and validates issuer, audience, expiry, etc.\r\n *\r\n * @param token JWT Access Token string\r\n * @param options.audience Custom audience validation value (defaults to clientId)\r\n */\r\n async verifyAccessToken(token: string, options?: { audience?: string }): Promise<AccessTokenPayload> {\r\n const verifier = await this.getJwtVerifier()\r\n return verifier.verifyAccessToken(token, options?.audience)\r\n }\r\n\r\n /**\r\n * Locally verify an OIDC ID Token.\r\n *\r\n * @param token JWT ID Token string\r\n * @param options.audience Custom audience validation value (defaults to clientId)\r\n * @param options.nonce Validate the nonce claim (required if nonce was sent during authorization)\r\n */\r\n async verifyIdToken(token: string, options?: { audience?: string; nonce?: string }): Promise<IdTokenPayload> {\r\n const verifier = await this.getJwtVerifier()\r\n return verifier.verifyIdToken(token, options)\r\n }\r\n\r\n // ============================================================\r\n // Express Middleware\r\n // ============================================================\r\n\r\n /**\r\n * Express middleware: verify the Bearer Token in the request.\r\n *\r\n * After successful verification, use `getAuth(req)` to retrieve the token payload.\r\n *\r\n * @param options.strategy Verification strategy: 'local' (default, JWT local verification) or 'introspection' (remote introspection)\r\n *\r\n * @example\r\n * ```typescript\r\n * import { getAuth } from '@nya-account/node-sdk/express'\r\n *\r\n * app.use('/api', client.authenticate())\r\n *\r\n * app.get('/api/me', (req, res) => {\r\n * const auth = getAuth(req)\r\n * res.json({ userId: auth?.sub })\r\n * })\r\n * ```\r\n */\r\n authenticate(options?: AuthenticateOptions): (req: Request, res: Response, next: NextFunction) => void {\r\n const strategy = options?.strategy ?? 'local'\r\n\r\n return (req: Request, res: Response, next: NextFunction) => {\r\n const token = extractBearerToken(req)\r\n if (!token) {\r\n sendOAuthError(res, 401, 'invalid_token', 'Missing Bearer token in Authorization header')\r\n return\r\n }\r\n\r\n const handleVerification = async (): Promise<void> => {\r\n let payload: AccessTokenPayload\r\n\r\n if (strategy === 'introspection') {\r\n const introspection = await this.introspectToken(token)\r\n if (!introspection.active) {\r\n sendOAuthError(res, 401, 'invalid_token', 'Token is not active')\r\n return\r\n }\r\n payload = {\r\n iss: introspection.iss ?? '',\r\n sub: introspection.sub ?? '',\r\n aud: introspection.aud ?? '',\r\n scope: introspection.scope ?? '',\r\n ver: '1',\r\n iat: introspection.iat ?? 0,\r\n exp: introspection.exp ?? 0,\r\n jti: introspection.jti ?? '',\r\n }\r\n } else {\r\n payload = await this.verifyAccessToken(token)\r\n }\r\n\r\n setAuth(req, payload)\r\n next()\r\n }\r\n\r\n handleVerification().catch(() => {\r\n sendOAuthError(res, 401, 'invalid_token', 'Invalid or expired access token')\r\n })\r\n }\r\n }\r\n\r\n /**\r\n * Express middleware: validate that the token in the request contains the specified scopes.\r\n *\r\n * Must be used after the `authenticate()` middleware.\r\n *\r\n * @example\r\n * ```typescript\r\n * app.get('/api/profile',\r\n * client.authenticate(),\r\n * client.requireScopes('profile'),\r\n * (req, res) => { ... }\r\n * )\r\n * ```\r\n */\r\n requireScopes(...scopes: string[]): (req: Request, res: Response, next: NextFunction) => void {\r\n return (req: Request, res: Response, next: NextFunction) => {\r\n const auth = getAuth(req)\r\n if (!auth) {\r\n sendOAuthError(res, 401, 'invalid_token', 'Request not authenticated')\r\n return\r\n }\r\n\r\n const tokenScopes = auth.scope.split(' ')\r\n const missingScopes = scopes.filter(s => !tokenScopes.includes(s))\r\n\r\n if (missingScopes.length > 0) {\r\n sendOAuthError(res, 403, 'insufficient_scope', `Missing required scopes: ${missingScopes.join(' ')}`)\r\n return\r\n }\r\n\r\n next()\r\n }\r\n }\r\n\r\n // ============================================================\r\n // Private Methods\r\n // ============================================================\r\n\r\n private async resolveEndpoint(name: EndpointName): Promise<string> {\r\n const explicit = this.config.endpoints?.[name]\r\n if (explicit) {\r\n return explicit\r\n }\r\n\r\n const discovery = await this.discover()\r\n const discoveryKey = DISCOVERY_ENDPOINT_MAP[name]\r\n const endpoint = discovery[discoveryKey]\r\n\r\n if (!endpoint || typeof endpoint !== 'string') {\r\n throw new NyaAccountError(\r\n 'endpoint_not_found',\r\n `Endpoint '${name}' not found in Discovery document`,\r\n )\r\n }\r\n\r\n return endpoint\r\n }\r\n\r\n private async getJwtVerifier(): Promise<JwtVerifier> {\r\n if (this.jwtVerifier) {\r\n return this.jwtVerifier\r\n }\r\n\r\n const jwksUri = await this.resolveEndpoint('jwks')\r\n const discovery = await this.discover()\r\n\r\n this.jwtVerifier = new JwtVerifier(jwksUri, discovery.issuer, this.config.clientId)\r\n return this.jwtVerifier\r\n }\r\n\r\n private mapTokenResponse(data: unknown): TokenResponse {\r\n const raw = TokenResponseSchema.parse(data)\r\n return {\r\n accessToken: raw.access_token,\r\n tokenType: raw.token_type,\r\n expiresIn: raw.expires_in,\r\n refreshToken: raw.refresh_token,\r\n scope: raw.scope,\r\n idToken: raw.id_token,\r\n }\r\n }\r\n\r\n private handleTokenError(error: unknown): NyaAccountError {\r\n if (error instanceof NyaAccountError) {\r\n return error\r\n }\r\n\r\n if (error instanceof AxiosError && error.response) {\r\n const parsed = OAuthErrorSchema.safeParse(error.response.data)\r\n if (parsed.success) {\r\n return new OAuthError(\r\n parsed.data.error,\r\n parsed.data.error_description ?? 'Unknown error',\r\n )\r\n }\r\n }\r\n\r\n const message = error instanceof Error ? error.message : 'Unknown error'\r\n return new NyaAccountError('request_failed', `Request failed: ${message}`)\r\n }\r\n}\r\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nya-account/node-sdk",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Official Node.js SDK for Nya Account SSO — OAuth 2.1 / OIDC client with PKCE, JWT verification, and Express middleware",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -76,4 +76,4 @@
|
|
|
76
76
|
"optional": true
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
|
-
}
|
|
79
|
+
}
|