@qyh213/easyauth-client 1.0.0-beta.1 → 1.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -51,6 +51,7 @@ var EasyAuthClient = class {
51
51
  constructor(config, tokenStorage) {
52
52
  this.config = {
53
53
  apiKey: "",
54
+ serviceId: "",
54
55
  defaultTokenExpiry: 24,
55
56
  ...config
56
57
  };
@@ -63,12 +64,12 @@ var EasyAuthClient = class {
63
64
  "Content-Type": "application/json",
64
65
  ...options.headers || {}
65
66
  };
66
- if (this.config.apiKey && !requireAuth) {
67
+ if (this.config.apiKey && !requireAuth && !headers["Authorization"]) {
67
68
  headers["Authorization"] = `Bearer ${this.config.apiKey}`;
68
69
  }
69
70
  if (requireAuth) {
70
71
  const token = this.getAccessToken();
71
- if (token) {
72
+ if (token && !headers["Authorization"]) {
72
73
  headers["Authorization"] = `Bearer ${token}`;
73
74
  }
74
75
  }
@@ -163,10 +164,12 @@ var EasyAuthClient = class {
163
164
  if (!this.config.apiKey) {
164
165
  return { valid: false, error: "Service API key not configured" };
165
166
  }
167
+ if (!this.config.serviceId) {
168
+ return { valid: false, error: "Service ID not configured in EasyAuthConfig" };
169
+ }
166
170
  try {
167
- const serviceId = this.config.apiKey.split(".")[0];
168
171
  const result = await this.introspect({
169
- serviceId,
172
+ serviceId: this.config.serviceId,
170
173
  token,
171
174
  requiredScopes
172
175
  });
@@ -224,6 +227,48 @@ var EasyAuthClient = class {
224
227
  await this.requireScopes(...scopes);
225
228
  return fn();
226
229
  }
230
+ // ============ OAuth ============
231
+ /**
232
+ * Initiate OAuth login flow and return the authorization URL
233
+ */
234
+ async initiateOAuth(provider, redirectUri) {
235
+ if (!this.config.apiKey) {
236
+ throw new EasyAuthError(
237
+ "API key required for OAuth. Configure the client first.",
238
+ "MISSING_API_KEY"
239
+ );
240
+ }
241
+ const response = await this.request(
242
+ "/api/v1/auth/oauth/initiate",
243
+ {
244
+ method: "POST",
245
+ body: JSON.stringify({ provider, redirectUri })
246
+ }
247
+ );
248
+ return response.url;
249
+ }
250
+ /**
251
+ * Handle OAuth callback URL and store the access token
252
+ * Returns null if no OAuth params are present in the URL
253
+ */
254
+ handleOAuthCallback(url) {
255
+ const parsedUrl = typeof url === "string" ? new URL(url) : url;
256
+ const token = parsedUrl.searchParams.get("token");
257
+ const userId = parsedUrl.searchParams.get("user_id");
258
+ const email = parsedUrl.searchParams.get("email");
259
+ if (!token || !userId || !email) {
260
+ return null;
261
+ }
262
+ this.setAccessToken(token);
263
+ return { token, userId, email };
264
+ }
265
+ /**
266
+ * Check if the current URL contains OAuth callback params
267
+ */
268
+ isOAuthCallback(url) {
269
+ const parsedUrl = typeof url === "string" ? new URL(url) : url;
270
+ return parsedUrl.searchParams.has("token") && parsedUrl.searchParams.has("user_id") && parsedUrl.searchParams.has("email");
271
+ }
227
272
  // ============ Authentication ============
228
273
  /**
229
274
  * Login a user and store the access token
@@ -240,6 +285,7 @@ var EasyAuthClient = class {
240
285
  body: JSON.stringify({
241
286
  email: credentials.email,
242
287
  password: credentials.password,
288
+ client_id: this.config.serviceId,
243
289
  expires_in_hours: credentials.expiresInHours || this.config.defaultTokenExpiry,
244
290
  scopes: credentials.scopes
245
291
  })
@@ -265,7 +311,7 @@ var EasyAuthClient = class {
265
311
  try {
266
312
  await this.request("/api/v1/auth/logout", {
267
313
  method: "POST"
268
- });
314
+ }, true);
269
315
  } catch (error) {
270
316
  }
271
317
  }
@@ -317,7 +363,11 @@ var EasyAuthClient = class {
317
363
  */
318
364
  async listUsers() {
319
365
  const response = await this.request("/api/v1/users/list");
320
- return response.users;
366
+ return response.users.map((u) => ({
367
+ userId: u.user_id,
368
+ email: u.email,
369
+ createdAt: u.created_at
370
+ }));
321
371
  }
322
372
  /**
323
373
  * Delete a user
@@ -380,7 +430,16 @@ var EasyAuthClient = class {
380
430
  */
381
431
  async listApiKeys() {
382
432
  const response = await this.request("/api/v1/keys/list");
383
- return response.apiKeys;
433
+ return response.keys.map((k) => ({
434
+ keyId: k.keyId,
435
+ name: k.name,
436
+ scope: k.scope,
437
+ scopes: [],
438
+ keyType: k.keyType,
439
+ revoked: k.revoked,
440
+ createdAt: k.createdAt,
441
+ tpsLimit: k.tpsLimit
442
+ }));
384
443
  }
385
444
  /**
386
445
  * Create a new API key with optional custom scopes
@@ -389,6 +448,7 @@ var EasyAuthClient = class {
389
448
  const response = await this.request("/api/v1/keys/create", {
390
449
  method: "POST",
391
450
  body: JSON.stringify({
451
+ user_id: request.userId,
392
452
  name: request.name,
393
453
  scope: request.scope || "service",
394
454
  scopes: request.scopes,
@@ -6,9 +6,20 @@ interface EasyAuthConfig {
6
6
  baseUrl: string;
7
7
  /** API Key for admin operations (keep secret!) */
8
8
  apiKey?: string;
9
+ /** Service ID - required for token introspection */
10
+ serviceId?: string;
9
11
  /** Default token expiration in hours */
10
12
  defaultTokenExpiry?: number;
11
13
  }
14
+ type OAuthProvider = "google" | "github";
15
+ interface OAuthInitiateResponse {
16
+ url: string;
17
+ }
18
+ interface OAuthCallbackResult {
19
+ token: string;
20
+ userId: string;
21
+ email: string;
22
+ }
12
23
  interface LoginCredentials {
13
24
  email: string;
14
25
  password: string;
@@ -82,6 +93,8 @@ interface ApiKey {
82
93
  }
83
94
  interface CreateApiKeyRequest {
84
95
  name: string;
96
+ /** User ID to associate the key with (required by backend) */
97
+ userId: string;
85
98
  scope?: string;
86
99
  /** Custom granular scopes */
87
100
  scopes?: string[];
@@ -218,6 +231,19 @@ declare class EasyAuthClient {
218
231
  * Execute a function only if the user has the required scopes
219
232
  */
220
233
  withScope<T>(scopes: string[], fn: () => Promise<T>): Promise<T>;
234
+ /**
235
+ * Initiate OAuth login flow and return the authorization URL
236
+ */
237
+ initiateOAuth(provider: OAuthProvider, redirectUri: string): Promise<string>;
238
+ /**
239
+ * Handle OAuth callback URL and store the access token
240
+ * Returns null if no OAuth params are present in the URL
241
+ */
242
+ handleOAuthCallback(url: string | URL): OAuthCallbackResult | null;
243
+ /**
244
+ * Check if the current URL contains OAuth callback params
245
+ */
246
+ isOAuthCallback(url: string | URL): boolean;
221
247
  /**
222
248
  * Login a user and store the access token
223
249
  */
@@ -297,4 +323,4 @@ declare class EasyAuthClient {
297
323
  deleteWebhook(webhookId: string): Promise<void>;
298
324
  }
299
325
 
300
- export { type ApiKey as A, type CreateApiKeyRequest as C, EasyAuthClient as E, type IntrospectRequest as I, LocalStorageTokenStorage as L, MemoryTokenStorage as M, type OnboardRequest as O, type RegisterWebhookRequest as R, type Scope as S, type TokenStorage as T, type User as U, type ValidationResult as V, type Webhook as W, type AuthToken as a, type CreateApiKeyResponse as b, type CreateScopeRequest as c, type CreateUserRequest as d, type EasyAuthConfig as e, EasyAuthError as f, type IntrospectResponse as g, type LoginCredentials as h, type OnboardResponse as i, ScopeError as j, type Service as k, type UserListResponse as l };
326
+ export { type ApiKey as A, type CreateApiKeyRequest as C, EasyAuthClient as E, type IntrospectRequest as I, LocalStorageTokenStorage as L, MemoryTokenStorage as M, type OAuthCallbackResult as O, type RegisterWebhookRequest as R, type Scope as S, type TokenStorage as T, type User as U, type ValidationResult as V, type Webhook as W, type AuthToken as a, type CreateApiKeyResponse as b, type CreateScopeRequest as c, type CreateUserRequest as d, type EasyAuthConfig as e, EasyAuthError as f, type IntrospectResponse as g, type LoginCredentials as h, type OAuthInitiateResponse as i, type OAuthProvider as j, type OnboardRequest as k, type OnboardResponse as l, ScopeError as m, type Service as n, type UserListResponse as o };
@@ -6,9 +6,20 @@ interface EasyAuthConfig {
6
6
  baseUrl: string;
7
7
  /** API Key for admin operations (keep secret!) */
8
8
  apiKey?: string;
9
+ /** Service ID - required for token introspection */
10
+ serviceId?: string;
9
11
  /** Default token expiration in hours */
10
12
  defaultTokenExpiry?: number;
11
13
  }
14
+ type OAuthProvider = "google" | "github";
15
+ interface OAuthInitiateResponse {
16
+ url: string;
17
+ }
18
+ interface OAuthCallbackResult {
19
+ token: string;
20
+ userId: string;
21
+ email: string;
22
+ }
12
23
  interface LoginCredentials {
13
24
  email: string;
14
25
  password: string;
@@ -82,6 +93,8 @@ interface ApiKey {
82
93
  }
83
94
  interface CreateApiKeyRequest {
84
95
  name: string;
96
+ /** User ID to associate the key with (required by backend) */
97
+ userId: string;
85
98
  scope?: string;
86
99
  /** Custom granular scopes */
87
100
  scopes?: string[];
@@ -218,6 +231,19 @@ declare class EasyAuthClient {
218
231
  * Execute a function only if the user has the required scopes
219
232
  */
220
233
  withScope<T>(scopes: string[], fn: () => Promise<T>): Promise<T>;
234
+ /**
235
+ * Initiate OAuth login flow and return the authorization URL
236
+ */
237
+ initiateOAuth(provider: OAuthProvider, redirectUri: string): Promise<string>;
238
+ /**
239
+ * Handle OAuth callback URL and store the access token
240
+ * Returns null if no OAuth params are present in the URL
241
+ */
242
+ handleOAuthCallback(url: string | URL): OAuthCallbackResult | null;
243
+ /**
244
+ * Check if the current URL contains OAuth callback params
245
+ */
246
+ isOAuthCallback(url: string | URL): boolean;
221
247
  /**
222
248
  * Login a user and store the access token
223
249
  */
@@ -297,4 +323,4 @@ declare class EasyAuthClient {
297
323
  deleteWebhook(webhookId: string): Promise<void>;
298
324
  }
299
325
 
300
- export { type ApiKey as A, type CreateApiKeyRequest as C, EasyAuthClient as E, type IntrospectRequest as I, LocalStorageTokenStorage as L, MemoryTokenStorage as M, type OnboardRequest as O, type RegisterWebhookRequest as R, type Scope as S, type TokenStorage as T, type User as U, type ValidationResult as V, type Webhook as W, type AuthToken as a, type CreateApiKeyResponse as b, type CreateScopeRequest as c, type CreateUserRequest as d, type EasyAuthConfig as e, EasyAuthError as f, type IntrospectResponse as g, type LoginCredentials as h, type OnboardResponse as i, ScopeError as j, type Service as k, type UserListResponse as l };
326
+ export { type ApiKey as A, type CreateApiKeyRequest as C, EasyAuthClient as E, type IntrospectRequest as I, LocalStorageTokenStorage as L, MemoryTokenStorage as M, type OAuthCallbackResult as O, type RegisterWebhookRequest as R, type Scope as S, type TokenStorage as T, type User as U, type ValidationResult as V, type Webhook as W, type AuthToken as a, type CreateApiKeyResponse as b, type CreateScopeRequest as c, type CreateUserRequest as d, type EasyAuthConfig as e, EasyAuthError as f, type IntrospectResponse as g, type LoginCredentials as h, type OAuthInitiateResponse as i, type OAuthProvider as j, type OnboardRequest as k, type OnboardResponse as l, ScopeError as m, type Service as n, type UserListResponse as o };
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as ApiKey, a as AuthToken, C as CreateApiKeyRequest, b as CreateApiKeyResponse, c as CreateScopeRequest, d as CreateUserRequest, E as EasyAuthClient, e as EasyAuthConfig, f as EasyAuthError, I as IntrospectRequest, g as IntrospectResponse, L as LocalStorageTokenStorage, h as LoginCredentials, M as MemoryTokenStorage, O as OnboardRequest, i as OnboardResponse, R as RegisterWebhookRequest, S as Scope, j as ScopeError, k as Service, T as TokenStorage, U as User, l as UserListResponse, V as ValidationResult, W as Webhook } from './client-RPDHpVsj.mjs';
1
+ export { A as ApiKey, a as AuthToken, C as CreateApiKeyRequest, b as CreateApiKeyResponse, c as CreateScopeRequest, d as CreateUserRequest, E as EasyAuthClient, e as EasyAuthConfig, f as EasyAuthError, I as IntrospectRequest, g as IntrospectResponse, L as LocalStorageTokenStorage, h as LoginCredentials, M as MemoryTokenStorage, O as OAuthCallbackResult, i as OAuthInitiateResponse, j as OAuthProvider, k as OnboardRequest, l as OnboardResponse, R as RegisterWebhookRequest, S as Scope, m as ScopeError, n as Service, T as TokenStorage, U as User, o as UserListResponse, V as ValidationResult, W as Webhook } from './client-DXVzwi77.mjs';
2
2
 
3
3
  /**
4
4
  * Easy Auth Client
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as ApiKey, a as AuthToken, C as CreateApiKeyRequest, b as CreateApiKeyResponse, c as CreateScopeRequest, d as CreateUserRequest, E as EasyAuthClient, e as EasyAuthConfig, f as EasyAuthError, I as IntrospectRequest, g as IntrospectResponse, L as LocalStorageTokenStorage, h as LoginCredentials, M as MemoryTokenStorage, O as OnboardRequest, i as OnboardResponse, R as RegisterWebhookRequest, S as Scope, j as ScopeError, k as Service, T as TokenStorage, U as User, l as UserListResponse, V as ValidationResult, W as Webhook } from './client-RPDHpVsj.js';
1
+ export { A as ApiKey, a as AuthToken, C as CreateApiKeyRequest, b as CreateApiKeyResponse, c as CreateScopeRequest, d as CreateUserRequest, E as EasyAuthClient, e as EasyAuthConfig, f as EasyAuthError, I as IntrospectRequest, g as IntrospectResponse, L as LocalStorageTokenStorage, h as LoginCredentials, M as MemoryTokenStorage, O as OAuthCallbackResult, i as OAuthInitiateResponse, j as OAuthProvider, k as OnboardRequest, l as OnboardResponse, R as RegisterWebhookRequest, S as Scope, m as ScopeError, n as Service, T as TokenStorage, U as User, o as UserListResponse, V as ValidationResult, W as Webhook } from './client-DXVzwi77.js';
2
2
 
3
3
  /**
4
4
  * Easy Auth Client
package/dist/index.js CHANGED
@@ -82,6 +82,7 @@ var EasyAuthClient = class {
82
82
  constructor(config, tokenStorage) {
83
83
  this.config = {
84
84
  apiKey: "",
85
+ serviceId: "",
85
86
  defaultTokenExpiry: 24,
86
87
  ...config
87
88
  };
@@ -94,12 +95,12 @@ var EasyAuthClient = class {
94
95
  "Content-Type": "application/json",
95
96
  ...options.headers || {}
96
97
  };
97
- if (this.config.apiKey && !requireAuth) {
98
+ if (this.config.apiKey && !requireAuth && !headers["Authorization"]) {
98
99
  headers["Authorization"] = `Bearer ${this.config.apiKey}`;
99
100
  }
100
101
  if (requireAuth) {
101
102
  const token = this.getAccessToken();
102
- if (token) {
103
+ if (token && !headers["Authorization"]) {
103
104
  headers["Authorization"] = `Bearer ${token}`;
104
105
  }
105
106
  }
@@ -194,10 +195,12 @@ var EasyAuthClient = class {
194
195
  if (!this.config.apiKey) {
195
196
  return { valid: false, error: "Service API key not configured" };
196
197
  }
198
+ if (!this.config.serviceId) {
199
+ return { valid: false, error: "Service ID not configured in EasyAuthConfig" };
200
+ }
197
201
  try {
198
- const serviceId = this.config.apiKey.split(".")[0];
199
202
  const result = await this.introspect({
200
- serviceId,
203
+ serviceId: this.config.serviceId,
201
204
  token,
202
205
  requiredScopes
203
206
  });
@@ -255,6 +258,48 @@ var EasyAuthClient = class {
255
258
  await this.requireScopes(...scopes);
256
259
  return fn();
257
260
  }
261
+ // ============ OAuth ============
262
+ /**
263
+ * Initiate OAuth login flow and return the authorization URL
264
+ */
265
+ async initiateOAuth(provider, redirectUri) {
266
+ if (!this.config.apiKey) {
267
+ throw new EasyAuthError(
268
+ "API key required for OAuth. Configure the client first.",
269
+ "MISSING_API_KEY"
270
+ );
271
+ }
272
+ const response = await this.request(
273
+ "/api/v1/auth/oauth/initiate",
274
+ {
275
+ method: "POST",
276
+ body: JSON.stringify({ provider, redirectUri })
277
+ }
278
+ );
279
+ return response.url;
280
+ }
281
+ /**
282
+ * Handle OAuth callback URL and store the access token
283
+ * Returns null if no OAuth params are present in the URL
284
+ */
285
+ handleOAuthCallback(url) {
286
+ const parsedUrl = typeof url === "string" ? new URL(url) : url;
287
+ const token = parsedUrl.searchParams.get("token");
288
+ const userId = parsedUrl.searchParams.get("user_id");
289
+ const email = parsedUrl.searchParams.get("email");
290
+ if (!token || !userId || !email) {
291
+ return null;
292
+ }
293
+ this.setAccessToken(token);
294
+ return { token, userId, email };
295
+ }
296
+ /**
297
+ * Check if the current URL contains OAuth callback params
298
+ */
299
+ isOAuthCallback(url) {
300
+ const parsedUrl = typeof url === "string" ? new URL(url) : url;
301
+ return parsedUrl.searchParams.has("token") && parsedUrl.searchParams.has("user_id") && parsedUrl.searchParams.has("email");
302
+ }
258
303
  // ============ Authentication ============
259
304
  /**
260
305
  * Login a user and store the access token
@@ -271,6 +316,7 @@ var EasyAuthClient = class {
271
316
  body: JSON.stringify({
272
317
  email: credentials.email,
273
318
  password: credentials.password,
319
+ client_id: this.config.serviceId,
274
320
  expires_in_hours: credentials.expiresInHours || this.config.defaultTokenExpiry,
275
321
  scopes: credentials.scopes
276
322
  })
@@ -296,7 +342,7 @@ var EasyAuthClient = class {
296
342
  try {
297
343
  await this.request("/api/v1/auth/logout", {
298
344
  method: "POST"
299
- });
345
+ }, true);
300
346
  } catch (error) {
301
347
  }
302
348
  }
@@ -348,7 +394,11 @@ var EasyAuthClient = class {
348
394
  */
349
395
  async listUsers() {
350
396
  const response = await this.request("/api/v1/users/list");
351
- return response.users;
397
+ return response.users.map((u) => ({
398
+ userId: u.user_id,
399
+ email: u.email,
400
+ createdAt: u.created_at
401
+ }));
352
402
  }
353
403
  /**
354
404
  * Delete a user
@@ -411,7 +461,16 @@ var EasyAuthClient = class {
411
461
  */
412
462
  async listApiKeys() {
413
463
  const response = await this.request("/api/v1/keys/list");
414
- return response.apiKeys;
464
+ return response.keys.map((k) => ({
465
+ keyId: k.keyId,
466
+ name: k.name,
467
+ scope: k.scope,
468
+ scopes: [],
469
+ keyType: k.keyType,
470
+ revoked: k.revoked,
471
+ createdAt: k.createdAt,
472
+ tpsLimit: k.tpsLimit
473
+ }));
415
474
  }
416
475
  /**
417
476
  * Create a new API key with optional custom scopes
@@ -420,6 +479,7 @@ var EasyAuthClient = class {
420
479
  const response = await this.request("/api/v1/keys/create", {
421
480
  method: "POST",
422
481
  body: JSON.stringify({
482
+ user_id: request.userId,
423
483
  name: request.name,
424
484
  scope: request.scope || "service",
425
485
  scopes: request.scopes,
package/dist/index.mjs CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  LocalStorageTokenStorage,
5
5
  MemoryTokenStorage,
6
6
  ScopeError
7
- } from "./chunk-H65ZLXQJ.mjs";
7
+ } from "./chunk-QT5ONI4T.mjs";
8
8
 
9
9
  // src/index.ts
10
10
  var VERSION = "1.0.0";
package/dist/next.d.mts CHANGED
@@ -1,13 +1,15 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { NextRequest, NextResponse } from 'next/server';
3
- import { e as EasyAuthConfig } from './client-RPDHpVsj.mjs';
4
- export { A as ApiKey, a as AuthToken, C as CreateApiKeyRequest, b as CreateApiKeyResponse, c as CreateScopeRequest, d as CreateUserRequest, E as EasyAuthClient, f as EasyAuthError, I as IntrospectRequest, g as IntrospectResponse, L as LocalStorageTokenStorage, h as LoginCredentials, M as MemoryTokenStorage, O as OnboardRequest, i as OnboardResponse, R as RegisterWebhookRequest, S as Scope, j as ScopeError, k as Service, T as TokenStorage, U as User, l as UserListResponse, V as ValidationResult, W as Webhook } from './client-RPDHpVsj.mjs';
3
+ import { e as EasyAuthConfig } from './client-DXVzwi77.mjs';
4
+ export { A as ApiKey, a as AuthToken, C as CreateApiKeyRequest, b as CreateApiKeyResponse, c as CreateScopeRequest, d as CreateUserRequest, E as EasyAuthClient, f as EasyAuthError, I as IntrospectRequest, g as IntrospectResponse, L as LocalStorageTokenStorage, h as LoginCredentials, M as MemoryTokenStorage, O as OAuthCallbackResult, i as OAuthInitiateResponse, j as OAuthProvider, k as OnboardRequest, l as OnboardResponse, R as RegisterWebhookRequest, S as Scope, m as ScopeError, n as Service, T as TokenStorage, U as User, o as UserListResponse, V as ValidationResult, W as Webhook } from './client-DXVzwi77.mjs';
5
5
 
6
6
  interface MiddlewareOptions {
7
7
  /** Base URL of Easy Auth service */
8
8
  baseUrl: string;
9
9
  /** Service API Key */
10
10
  apiKey: string;
11
+ /** Service ID */
12
+ serviceId: string;
11
13
  /** Paths that require authentication */
12
14
  protectedPaths?: string[];
13
15
  /** Paths that require specific scopes: path -> scopes[] */
@@ -91,6 +93,7 @@ declare function withScope<P extends object>(Component: React.ComponentType<P>,
91
93
  declare function validateScopes(request: Request, options: {
92
94
  baseUrl: string;
93
95
  apiKey: string;
96
+ serviceId: string;
94
97
  requiredScopes: string[];
95
98
  }): Promise<{
96
99
  valid: true;
package/dist/next.d.ts CHANGED
@@ -1,13 +1,15 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { NextRequest, NextResponse } from 'next/server';
3
- import { e as EasyAuthConfig } from './client-RPDHpVsj.js';
4
- export { A as ApiKey, a as AuthToken, C as CreateApiKeyRequest, b as CreateApiKeyResponse, c as CreateScopeRequest, d as CreateUserRequest, E as EasyAuthClient, f as EasyAuthError, I as IntrospectRequest, g as IntrospectResponse, L as LocalStorageTokenStorage, h as LoginCredentials, M as MemoryTokenStorage, O as OnboardRequest, i as OnboardResponse, R as RegisterWebhookRequest, S as Scope, j as ScopeError, k as Service, T as TokenStorage, U as User, l as UserListResponse, V as ValidationResult, W as Webhook } from './client-RPDHpVsj.js';
3
+ import { e as EasyAuthConfig } from './client-DXVzwi77.js';
4
+ export { A as ApiKey, a as AuthToken, C as CreateApiKeyRequest, b as CreateApiKeyResponse, c as CreateScopeRequest, d as CreateUserRequest, E as EasyAuthClient, f as EasyAuthError, I as IntrospectRequest, g as IntrospectResponse, L as LocalStorageTokenStorage, h as LoginCredentials, M as MemoryTokenStorage, O as OAuthCallbackResult, i as OAuthInitiateResponse, j as OAuthProvider, k as OnboardRequest, l as OnboardResponse, R as RegisterWebhookRequest, S as Scope, m as ScopeError, n as Service, T as TokenStorage, U as User, o as UserListResponse, V as ValidationResult, W as Webhook } from './client-DXVzwi77.js';
5
5
 
6
6
  interface MiddlewareOptions {
7
7
  /** Base URL of Easy Auth service */
8
8
  baseUrl: string;
9
9
  /** Service API Key */
10
10
  apiKey: string;
11
+ /** Service ID */
12
+ serviceId: string;
11
13
  /** Paths that require authentication */
12
14
  protectedPaths?: string[];
13
15
  /** Paths that require specific scopes: path -> scopes[] */
@@ -91,6 +93,7 @@ declare function withScope<P extends object>(Component: React.ComponentType<P>,
91
93
  declare function validateScopes(request: Request, options: {
92
94
  baseUrl: string;
93
95
  apiKey: string;
96
+ serviceId: string;
94
97
  requiredScopes: string[];
95
98
  }): Promise<{
96
99
  valid: true;
package/dist/next.js CHANGED
@@ -85,6 +85,7 @@ var EasyAuthClient = class {
85
85
  constructor(config, tokenStorage) {
86
86
  this.config = {
87
87
  apiKey: "",
88
+ serviceId: "",
88
89
  defaultTokenExpiry: 24,
89
90
  ...config
90
91
  };
@@ -97,12 +98,12 @@ var EasyAuthClient = class {
97
98
  "Content-Type": "application/json",
98
99
  ...options.headers || {}
99
100
  };
100
- if (this.config.apiKey && !requireAuth) {
101
+ if (this.config.apiKey && !requireAuth && !headers["Authorization"]) {
101
102
  headers["Authorization"] = `Bearer ${this.config.apiKey}`;
102
103
  }
103
104
  if (requireAuth) {
104
105
  const token = this.getAccessToken();
105
- if (token) {
106
+ if (token && !headers["Authorization"]) {
106
107
  headers["Authorization"] = `Bearer ${token}`;
107
108
  }
108
109
  }
@@ -197,10 +198,12 @@ var EasyAuthClient = class {
197
198
  if (!this.config.apiKey) {
198
199
  return { valid: false, error: "Service API key not configured" };
199
200
  }
201
+ if (!this.config.serviceId) {
202
+ return { valid: false, error: "Service ID not configured in EasyAuthConfig" };
203
+ }
200
204
  try {
201
- const serviceId = this.config.apiKey.split(".")[0];
202
205
  const result = await this.introspect({
203
- serviceId,
206
+ serviceId: this.config.serviceId,
204
207
  token,
205
208
  requiredScopes
206
209
  });
@@ -258,6 +261,48 @@ var EasyAuthClient = class {
258
261
  await this.requireScopes(...scopes);
259
262
  return fn();
260
263
  }
264
+ // ============ OAuth ============
265
+ /**
266
+ * Initiate OAuth login flow and return the authorization URL
267
+ */
268
+ async initiateOAuth(provider, redirectUri) {
269
+ if (!this.config.apiKey) {
270
+ throw new EasyAuthError(
271
+ "API key required for OAuth. Configure the client first.",
272
+ "MISSING_API_KEY"
273
+ );
274
+ }
275
+ const response = await this.request(
276
+ "/api/v1/auth/oauth/initiate",
277
+ {
278
+ method: "POST",
279
+ body: JSON.stringify({ provider, redirectUri })
280
+ }
281
+ );
282
+ return response.url;
283
+ }
284
+ /**
285
+ * Handle OAuth callback URL and store the access token
286
+ * Returns null if no OAuth params are present in the URL
287
+ */
288
+ handleOAuthCallback(url) {
289
+ const parsedUrl = typeof url === "string" ? new URL(url) : url;
290
+ const token = parsedUrl.searchParams.get("token");
291
+ const userId = parsedUrl.searchParams.get("user_id");
292
+ const email = parsedUrl.searchParams.get("email");
293
+ if (!token || !userId || !email) {
294
+ return null;
295
+ }
296
+ this.setAccessToken(token);
297
+ return { token, userId, email };
298
+ }
299
+ /**
300
+ * Check if the current URL contains OAuth callback params
301
+ */
302
+ isOAuthCallback(url) {
303
+ const parsedUrl = typeof url === "string" ? new URL(url) : url;
304
+ return parsedUrl.searchParams.has("token") && parsedUrl.searchParams.has("user_id") && parsedUrl.searchParams.has("email");
305
+ }
261
306
  // ============ Authentication ============
262
307
  /**
263
308
  * Login a user and store the access token
@@ -274,6 +319,7 @@ var EasyAuthClient = class {
274
319
  body: JSON.stringify({
275
320
  email: credentials.email,
276
321
  password: credentials.password,
322
+ client_id: this.config.serviceId,
277
323
  expires_in_hours: credentials.expiresInHours || this.config.defaultTokenExpiry,
278
324
  scopes: credentials.scopes
279
325
  })
@@ -299,7 +345,7 @@ var EasyAuthClient = class {
299
345
  try {
300
346
  await this.request("/api/v1/auth/logout", {
301
347
  method: "POST"
302
- });
348
+ }, true);
303
349
  } catch (error) {
304
350
  }
305
351
  }
@@ -351,7 +397,11 @@ var EasyAuthClient = class {
351
397
  */
352
398
  async listUsers() {
353
399
  const response = await this.request("/api/v1/users/list");
354
- return response.users;
400
+ return response.users.map((u) => ({
401
+ userId: u.user_id,
402
+ email: u.email,
403
+ createdAt: u.created_at
404
+ }));
355
405
  }
356
406
  /**
357
407
  * Delete a user
@@ -414,7 +464,16 @@ var EasyAuthClient = class {
414
464
  */
415
465
  async listApiKeys() {
416
466
  const response = await this.request("/api/v1/keys/list");
417
- return response.apiKeys;
467
+ return response.keys.map((k) => ({
468
+ keyId: k.keyId,
469
+ name: k.name,
470
+ scope: k.scope,
471
+ scopes: [],
472
+ keyType: k.keyType,
473
+ revoked: k.revoked,
474
+ createdAt: k.createdAt,
475
+ tpsLimit: k.tpsLimit
476
+ }));
418
477
  }
419
478
  /**
420
479
  * Create a new API key with optional custom scopes
@@ -423,6 +482,7 @@ var EasyAuthClient = class {
423
482
  const response = await this.request("/api/v1/keys/create", {
424
483
  method: "POST",
425
484
  body: JSON.stringify({
485
+ user_id: request.userId,
426
486
  name: request.name,
427
487
  scope: request.scope || "service",
428
488
  scopes: request.scopes,
@@ -548,10 +608,9 @@ function createEasyAuthMiddleware(options) {
548
608
  return import_server.NextResponse.next();
549
609
  }
550
610
  const client = new EasyAuthClient({ baseUrl, apiKey });
551
- const serviceId = apiKey.split(".")[0];
552
611
  try {
553
612
  const introspectResult = await client.introspect({
554
- serviceId,
613
+ serviceId: options.serviceId,
555
614
  token
556
615
  });
557
616
  if (!introspectResult.valid) {
@@ -594,17 +653,19 @@ function withScope(Component, _requiredScopes, _config) {
594
653
  };
595
654
  }
596
655
  async function validateScopes(request, options) {
597
- const { baseUrl, apiKey, requiredScopes } = options;
656
+ const { baseUrl, apiKey, requiredScopes, serviceId } = options;
598
657
  const authHeader = request.headers.get("Authorization");
599
658
  const token = authHeader?.replace("Bearer ", "");
600
659
  if (!token) {
601
660
  return { valid: false, error: "No token provided", status: 401 };
602
661
  }
603
- const client = new EasyAuthClient({ baseUrl, apiKey });
604
- const serviceId = apiKey.split(".")[0];
662
+ const client = new EasyAuthClient({ baseUrl, apiKey, serviceId });
663
+ if (!serviceId) {
664
+ return { valid: false, error: "Service ID not configured", status: 500 };
665
+ }
605
666
  try {
606
667
  const result = await client.introspect({
607
- serviceId,
668
+ serviceId: options.serviceId,
608
669
  token,
609
670
  requiredScopes
610
671
  });
package/dist/next.mjs CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  LocalStorageTokenStorage,
5
5
  MemoryTokenStorage,
6
6
  ScopeError
7
- } from "./chunk-H65ZLXQJ.mjs";
7
+ } from "./chunk-QT5ONI4T.mjs";
8
8
 
9
9
  // src/next.tsx
10
10
  import { NextResponse } from "next/server";
@@ -35,10 +35,9 @@ function createEasyAuthMiddleware(options) {
35
35
  return NextResponse.next();
36
36
  }
37
37
  const client = new EasyAuthClient({ baseUrl, apiKey });
38
- const serviceId = apiKey.split(".")[0];
39
38
  try {
40
39
  const introspectResult = await client.introspect({
41
- serviceId,
40
+ serviceId: options.serviceId,
42
41
  token
43
42
  });
44
43
  if (!introspectResult.valid) {
@@ -81,17 +80,19 @@ function withScope(Component, _requiredScopes, _config) {
81
80
  };
82
81
  }
83
82
  async function validateScopes(request, options) {
84
- const { baseUrl, apiKey, requiredScopes } = options;
83
+ const { baseUrl, apiKey, requiredScopes, serviceId } = options;
85
84
  const authHeader = request.headers.get("Authorization");
86
85
  const token = authHeader?.replace("Bearer ", "");
87
86
  if (!token) {
88
87
  return { valid: false, error: "No token provided", status: 401 };
89
88
  }
90
- const client = new EasyAuthClient({ baseUrl, apiKey });
91
- const serviceId = apiKey.split(".")[0];
89
+ const client = new EasyAuthClient({ baseUrl, apiKey, serviceId });
90
+ if (!serviceId) {
91
+ return { valid: false, error: "Service ID not configured", status: 500 };
92
+ }
92
93
  try {
93
94
  const result = await client.introspect({
94
- serviceId,
95
+ serviceId: options.serviceId,
95
96
  token,
96
97
  requiredScopes
97
98
  });
package/dist/react.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
- import { e as EasyAuthConfig, T as TokenStorage, E as EasyAuthClient, U as User, V as ValidationResult } from './client-RPDHpVsj.mjs';
4
- export { A as ApiKey, a as AuthToken, C as CreateApiKeyRequest, b as CreateApiKeyResponse, c as CreateScopeRequest, d as CreateUserRequest, f as EasyAuthError, I as IntrospectRequest, g as IntrospectResponse, L as LocalStorageTokenStorage, h as LoginCredentials, M as MemoryTokenStorage, O as OnboardRequest, i as OnboardResponse, R as RegisterWebhookRequest, S as Scope, j as ScopeError, k as Service, l as UserListResponse, W as Webhook } from './client-RPDHpVsj.mjs';
3
+ import { e as EasyAuthConfig, T as TokenStorage, E as EasyAuthClient, U as User, V as ValidationResult } from './client-DXVzwi77.mjs';
4
+ export { A as ApiKey, a as AuthToken, C as CreateApiKeyRequest, b as CreateApiKeyResponse, c as CreateScopeRequest, d as CreateUserRequest, f as EasyAuthError, I as IntrospectRequest, g as IntrospectResponse, L as LocalStorageTokenStorage, h as LoginCredentials, M as MemoryTokenStorage, O as OAuthCallbackResult, i as OAuthInitiateResponse, j as OAuthProvider, k as OnboardRequest, l as OnboardResponse, R as RegisterWebhookRequest, S as Scope, m as ScopeError, n as Service, o as UserListResponse, W as Webhook } from './client-DXVzwi77.mjs';
5
5
 
6
6
  interface EasyAuthContextValue {
7
7
  client: EasyAuthClient;
package/dist/react.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
- import { e as EasyAuthConfig, T as TokenStorage, E as EasyAuthClient, U as User, V as ValidationResult } from './client-RPDHpVsj.js';
4
- export { A as ApiKey, a as AuthToken, C as CreateApiKeyRequest, b as CreateApiKeyResponse, c as CreateScopeRequest, d as CreateUserRequest, f as EasyAuthError, I as IntrospectRequest, g as IntrospectResponse, L as LocalStorageTokenStorage, h as LoginCredentials, M as MemoryTokenStorage, O as OnboardRequest, i as OnboardResponse, R as RegisterWebhookRequest, S as Scope, j as ScopeError, k as Service, l as UserListResponse, W as Webhook } from './client-RPDHpVsj.js';
3
+ import { e as EasyAuthConfig, T as TokenStorage, E as EasyAuthClient, U as User, V as ValidationResult } from './client-DXVzwi77.js';
4
+ export { A as ApiKey, a as AuthToken, C as CreateApiKeyRequest, b as CreateApiKeyResponse, c as CreateScopeRequest, d as CreateUserRequest, f as EasyAuthError, I as IntrospectRequest, g as IntrospectResponse, L as LocalStorageTokenStorage, h as LoginCredentials, M as MemoryTokenStorage, O as OAuthCallbackResult, i as OAuthInitiateResponse, j as OAuthProvider, k as OnboardRequest, l as OnboardResponse, R as RegisterWebhookRequest, S as Scope, m as ScopeError, n as Service, o as UserListResponse, W as Webhook } from './client-DXVzwi77.js';
5
5
 
6
6
  interface EasyAuthContextValue {
7
7
  client: EasyAuthClient;
package/dist/react.js CHANGED
@@ -90,6 +90,7 @@ var EasyAuthClient = class {
90
90
  constructor(config, tokenStorage) {
91
91
  this.config = {
92
92
  apiKey: "",
93
+ serviceId: "",
93
94
  defaultTokenExpiry: 24,
94
95
  ...config
95
96
  };
@@ -102,12 +103,12 @@ var EasyAuthClient = class {
102
103
  "Content-Type": "application/json",
103
104
  ...options.headers || {}
104
105
  };
105
- if (this.config.apiKey && !requireAuth) {
106
+ if (this.config.apiKey && !requireAuth && !headers["Authorization"]) {
106
107
  headers["Authorization"] = `Bearer ${this.config.apiKey}`;
107
108
  }
108
109
  if (requireAuth) {
109
110
  const token = this.getAccessToken();
110
- if (token) {
111
+ if (token && !headers["Authorization"]) {
111
112
  headers["Authorization"] = `Bearer ${token}`;
112
113
  }
113
114
  }
@@ -202,10 +203,12 @@ var EasyAuthClient = class {
202
203
  if (!this.config.apiKey) {
203
204
  return { valid: false, error: "Service API key not configured" };
204
205
  }
206
+ if (!this.config.serviceId) {
207
+ return { valid: false, error: "Service ID not configured in EasyAuthConfig" };
208
+ }
205
209
  try {
206
- const serviceId = this.config.apiKey.split(".")[0];
207
210
  const result = await this.introspect({
208
- serviceId,
211
+ serviceId: this.config.serviceId,
209
212
  token,
210
213
  requiredScopes
211
214
  });
@@ -263,6 +266,48 @@ var EasyAuthClient = class {
263
266
  await this.requireScopes(...scopes);
264
267
  return fn();
265
268
  }
269
+ // ============ OAuth ============
270
+ /**
271
+ * Initiate OAuth login flow and return the authorization URL
272
+ */
273
+ async initiateOAuth(provider, redirectUri) {
274
+ if (!this.config.apiKey) {
275
+ throw new EasyAuthError(
276
+ "API key required for OAuth. Configure the client first.",
277
+ "MISSING_API_KEY"
278
+ );
279
+ }
280
+ const response = await this.request(
281
+ "/api/v1/auth/oauth/initiate",
282
+ {
283
+ method: "POST",
284
+ body: JSON.stringify({ provider, redirectUri })
285
+ }
286
+ );
287
+ return response.url;
288
+ }
289
+ /**
290
+ * Handle OAuth callback URL and store the access token
291
+ * Returns null if no OAuth params are present in the URL
292
+ */
293
+ handleOAuthCallback(url) {
294
+ const parsedUrl = typeof url === "string" ? new URL(url) : url;
295
+ const token = parsedUrl.searchParams.get("token");
296
+ const userId = parsedUrl.searchParams.get("user_id");
297
+ const email = parsedUrl.searchParams.get("email");
298
+ if (!token || !userId || !email) {
299
+ return null;
300
+ }
301
+ this.setAccessToken(token);
302
+ return { token, userId, email };
303
+ }
304
+ /**
305
+ * Check if the current URL contains OAuth callback params
306
+ */
307
+ isOAuthCallback(url) {
308
+ const parsedUrl = typeof url === "string" ? new URL(url) : url;
309
+ return parsedUrl.searchParams.has("token") && parsedUrl.searchParams.has("user_id") && parsedUrl.searchParams.has("email");
310
+ }
266
311
  // ============ Authentication ============
267
312
  /**
268
313
  * Login a user and store the access token
@@ -279,6 +324,7 @@ var EasyAuthClient = class {
279
324
  body: JSON.stringify({
280
325
  email: credentials.email,
281
326
  password: credentials.password,
327
+ client_id: this.config.serviceId,
282
328
  expires_in_hours: credentials.expiresInHours || this.config.defaultTokenExpiry,
283
329
  scopes: credentials.scopes
284
330
  })
@@ -304,7 +350,7 @@ var EasyAuthClient = class {
304
350
  try {
305
351
  await this.request("/api/v1/auth/logout", {
306
352
  method: "POST"
307
- });
353
+ }, true);
308
354
  } catch (error) {
309
355
  }
310
356
  }
@@ -356,7 +402,11 @@ var EasyAuthClient = class {
356
402
  */
357
403
  async listUsers() {
358
404
  const response = await this.request("/api/v1/users/list");
359
- return response.users;
405
+ return response.users.map((u) => ({
406
+ userId: u.user_id,
407
+ email: u.email,
408
+ createdAt: u.created_at
409
+ }));
360
410
  }
361
411
  /**
362
412
  * Delete a user
@@ -419,7 +469,16 @@ var EasyAuthClient = class {
419
469
  */
420
470
  async listApiKeys() {
421
471
  const response = await this.request("/api/v1/keys/list");
422
- return response.apiKeys;
472
+ return response.keys.map((k) => ({
473
+ keyId: k.keyId,
474
+ name: k.name,
475
+ scope: k.scope,
476
+ scopes: [],
477
+ keyType: k.keyType,
478
+ revoked: k.revoked,
479
+ createdAt: k.createdAt,
480
+ tpsLimit: k.tpsLimit
481
+ }));
423
482
  }
424
483
  /**
425
484
  * Create a new API key with optional custom scopes
@@ -428,6 +487,7 @@ var EasyAuthClient = class {
428
487
  const response = await this.request("/api/v1/keys/create", {
429
488
  method: "POST",
430
489
  body: JSON.stringify({
490
+ user_id: request.userId,
431
491
  name: request.name,
432
492
  scope: request.scope || "service",
433
493
  scopes: request.scopes,
package/dist/react.mjs CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  LocalStorageTokenStorage,
5
5
  MemoryTokenStorage,
6
6
  ScopeError
7
- } from "./chunk-H65ZLXQJ.mjs";
7
+ } from "./chunk-QT5ONI4T.mjs";
8
8
 
9
9
  // src/react.tsx
10
10
  import {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qyh213/easyauth-client",
3
- "version": "1.0.0-beta.1",
3
+ "version": "1.0.0-beta.2",
4
4
  "description": "Official client library for Easy Auth - Multi-tenant authentication-as-a-service",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -74,7 +74,7 @@
74
74
  "homepage": "https://github.com/yourorg/easy-auth#readme",
75
75
  "peerDependencies": {
76
76
  "react": "^18.0.0 || ^19.0.0",
77
- "next": "^14.0.0 || ^15.0.0"
77
+ "next": "^14.0.0 || ^15.0.0 || ^16.0.0"
78
78
  },
79
79
  "peerDependenciesMeta": {
80
80
  "react": {