@xemahq/identity-client 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +313 -0
- package/dist/client.d.ts +22 -0
- package/dist/client.js +111 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/nestjs/identity-bootstrap.module.d.ts +13 -0
- package/dist/nestjs/identity-bootstrap.module.js +45 -0
- package/dist/nestjs/identity-bootstrap.module.js.map +1 -0
- package/dist/nestjs/identity-bootstrap.service.d.ts +76 -0
- package/dist/nestjs/identity-bootstrap.service.js +474 -0
- package/dist/nestjs/identity-bootstrap.service.js.map +1 -0
- package/dist/nestjs/index.d.ts +3 -0
- package/dist/nestjs/index.js +13 -0
- package/dist/nestjs/index.js.map +1 -0
- package/dist/nestjs/org-auth/index.d.ts +3 -0
- package/dist/nestjs/org-auth/index.js +10 -0
- package/dist/nestjs/org-auth/index.js.map +1 -0
- package/dist/nestjs/org-auth/org-admin.guard.d.ts +13 -0
- package/dist/nestjs/org-auth/org-admin.guard.js +103 -0
- package/dist/nestjs/org-auth/org-admin.guard.js.map +1 -0
- package/dist/nestjs/org-auth/org-auth.module.d.ts +6 -0
- package/dist/nestjs/org-auth/org-auth.module.js +46 -0
- package/dist/nestjs/org-auth/org-auth.module.js.map +1 -0
- package/dist/nestjs/org-auth/org-auth.types.d.ts +14 -0
- package/dist/nestjs/org-auth/org-auth.types.js +5 -0
- package/dist/nestjs/org-auth/org-auth.types.js.map +1 -0
- package/dist/types.d.ts +85 -0
- package/dist/types.js +20 -0
- package/dist/types.js.map +1 -0
- package/package.json +53 -0
package/README.md
ADDED
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
# @xemahq/identity-client
|
|
2
|
+
|
|
3
|
+
TypeScript client library and NestJS module for integrating microservices with Identity API. Handles service registration, credential management, and JWT token lifecycle automatically.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Automatic Service Registration** — Background registration with identity-api on startup
|
|
8
|
+
- **Token Management** — Automatic caching, refresh at 90% lifetime, concurrent request deduplication
|
|
9
|
+
- **NestJS Module** — Drop-in `IdentityBootstrapModule` with async configuration
|
|
10
|
+
- **Standalone Client** — `IdentityApiClient` for direct API calls outside NestJS
|
|
11
|
+
- **Non-Blocking Startup** — Services start immediately; registration happens in the background
|
|
12
|
+
- **Exponential Backoff** — Resilient retry logic (5s → 5min cap) if identity-api is unavailable
|
|
13
|
+
- **Pre-configured Credentials** — Optional bypass for registration when credentials are provided via env vars
|
|
14
|
+
- **Zero Dependencies** — Uses native `fetch` (no axios)
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @xemahq/identity-client
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Requires `.npmrc` with GitHub Packages registry:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
@xemahq:registry=https://npm.pkg.github.com
|
|
26
|
+
//npm.pkg.github.com/:_authToken=${NPM_TOKEN}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick Start (NestJS)
|
|
30
|
+
|
|
31
|
+
### 1. Import the Module
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import { Module } from '@nestjs/common';
|
|
35
|
+
import { ConfigModule, ConfigService } from '@nestjs/config';
|
|
36
|
+
import { IdentityBootstrapModule } from '@xemahq/identity-client';
|
|
37
|
+
|
|
38
|
+
@Module({
|
|
39
|
+
imports: [
|
|
40
|
+
ConfigModule.forRoot({ isGlobal: true }),
|
|
41
|
+
IdentityBootstrapModule.forRootAsync({
|
|
42
|
+
imports: [ConfigModule],
|
|
43
|
+
useFactory: (config: ConfigService) => ({
|
|
44
|
+
identityApiUrl: config.getOrThrow('IDENTITY_API_URL'),
|
|
45
|
+
identityApiInternalToken: config.getOrThrow('IDENTITY_API_INTERNAL_TOKEN'),
|
|
46
|
+
serviceName: 'my-service',
|
|
47
|
+
serviceDisplayName: 'My Service',
|
|
48
|
+
}),
|
|
49
|
+
inject: [ConfigService],
|
|
50
|
+
}),
|
|
51
|
+
],
|
|
52
|
+
})
|
|
53
|
+
export class AppModule {}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 2. Environment Variables
|
|
57
|
+
|
|
58
|
+
```env
|
|
59
|
+
IDENTITY_API_URL=http://identity-api:3053
|
|
60
|
+
IDENTITY_API_INTERNAL_TOKEN=your-identity-api-token
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 3. Use the Service
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import { Injectable } from '@nestjs/common';
|
|
67
|
+
import { IdentityBootstrapService } from '@xemahq/identity-client';
|
|
68
|
+
import { HttpService } from '@nestjs/axios';
|
|
69
|
+
import { firstValueFrom } from 'rxjs';
|
|
70
|
+
|
|
71
|
+
@Injectable()
|
|
72
|
+
export class MyService {
|
|
73
|
+
constructor(
|
|
74
|
+
private readonly identityBootstrap: IdentityBootstrapService,
|
|
75
|
+
private readonly httpService: HttpService,
|
|
76
|
+
) {}
|
|
77
|
+
|
|
78
|
+
async callOtherService() {
|
|
79
|
+
// Get a valid JWT access token (cached, auto-refreshed)
|
|
80
|
+
const token = await this.identityBootstrap.getAccessToken();
|
|
81
|
+
|
|
82
|
+
const response = await firstValueFrom(
|
|
83
|
+
this.httpService.get('http://other-service/resource', {
|
|
84
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
85
|
+
}),
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
return response.data;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Integration with Event Hub
|
|
94
|
+
|
|
95
|
+
The primary use case is providing JWT tokens to `@xemahq/event-hub-client` via the `tokenProvider` option:
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
import { IdentityBootstrapModule, IdentityBootstrapService } from '@xemahq/identity-client';
|
|
99
|
+
import { EventHubModule } from '@xemahq/event-hub-client';
|
|
100
|
+
|
|
101
|
+
@Module({
|
|
102
|
+
imports: [
|
|
103
|
+
ConfigModule.forRoot({ isGlobal: true }),
|
|
104
|
+
|
|
105
|
+
// 1. Register with identity-api
|
|
106
|
+
IdentityBootstrapModule.forRootAsync({
|
|
107
|
+
imports: [ConfigModule],
|
|
108
|
+
useFactory: (config: ConfigService) => ({
|
|
109
|
+
identityApiUrl: config.getOrThrow('IDENTITY_API_URL'),
|
|
110
|
+
identityApiInternalToken: config.getOrThrow('IDENTITY_API_INTERNAL_TOKEN'),
|
|
111
|
+
serviceName: 'my-service',
|
|
112
|
+
serviceDisplayName: 'My Service',
|
|
113
|
+
}),
|
|
114
|
+
inject: [ConfigService],
|
|
115
|
+
}),
|
|
116
|
+
|
|
117
|
+
// 2. Register with event-hub, using identity-api for tokens
|
|
118
|
+
EventHubModule.forRootAsync({
|
|
119
|
+
imports: [ConfigModule],
|
|
120
|
+
useFactory: (config: ConfigService, identityBootstrap: IdentityBootstrapService) => ({
|
|
121
|
+
eventHubUrl: config.getOrThrow('EVENT_HUB_URL'),
|
|
122
|
+
eventHubInternalToken: config.getOrThrow('EVENT_HUB_INTERNAL_TOKEN'),
|
|
123
|
+
serviceId: 'my-service',
|
|
124
|
+
serviceName: 'My Service',
|
|
125
|
+
schemaVersion: '1.0.0',
|
|
126
|
+
dataTypes: ['order'],
|
|
127
|
+
tokenProvider: () => identityBootstrap.getAccessToken(),
|
|
128
|
+
}),
|
|
129
|
+
inject: [ConfigService, IdentityBootstrapService],
|
|
130
|
+
}),
|
|
131
|
+
],
|
|
132
|
+
})
|
|
133
|
+
export class AppModule {}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## API Reference
|
|
137
|
+
|
|
138
|
+
### IdentityBootstrapModule
|
|
139
|
+
|
|
140
|
+
NestJS module for automatic service registration and token management.
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
IdentityBootstrapModule.forRootAsync({
|
|
144
|
+
imports: [ConfigModule],
|
|
145
|
+
useFactory: (config: ConfigService) => ({
|
|
146
|
+
// Required
|
|
147
|
+
identityApiUrl: string; // Base URL of identity-api
|
|
148
|
+
identityApiInternalToken: string; // Internal bearer token for registration
|
|
149
|
+
serviceName: string; // Service ID (becomes OAuth2 client_id)
|
|
150
|
+
serviceDisplayName: string; // Human-readable name
|
|
151
|
+
|
|
152
|
+
// Optional
|
|
153
|
+
serviceDescription?: string; // Service description
|
|
154
|
+
maxRegistrationAttempts?: number; // Max retries (default: Infinity)
|
|
155
|
+
baseRetryDelay?: number; // Backoff base delay in ms (default: 5000)
|
|
156
|
+
maxRetryDelay?: number; // Backoff cap in ms (default: 300000)
|
|
157
|
+
|
|
158
|
+
// Pre-configured credentials (skip auto-registration)
|
|
159
|
+
clientId?: string; // OAuth2 client_id
|
|
160
|
+
clientSecret?: string; // OAuth2 client_secret
|
|
161
|
+
tokenEndpoint?: string; // Keycloak token endpoint URL
|
|
162
|
+
}),
|
|
163
|
+
inject: [ConfigService],
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
The module registers globally and exports `IdentityBootstrapService`.
|
|
168
|
+
|
|
169
|
+
### IdentityBootstrapService
|
|
170
|
+
|
|
171
|
+
Manages service account lifecycle. Injected automatically when using `IdentityBootstrapModule`.
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
class IdentityBootstrapService {
|
|
175
|
+
// Get a valid JWT access token (cached, auto-refreshed)
|
|
176
|
+
getAccessToken(): Promise<string>;
|
|
177
|
+
|
|
178
|
+
// Wait for registration to complete (with optional timeout)
|
|
179
|
+
waitForReady(timeoutMs?: number): Promise<boolean>;
|
|
180
|
+
|
|
181
|
+
// Check if credentials are available
|
|
182
|
+
hasCredentials(): boolean;
|
|
183
|
+
|
|
184
|
+
// Get the service's OAuth2 client_id
|
|
185
|
+
getClientId(): string | null;
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Startup behavior:**
|
|
190
|
+
1. If `clientId`, `clientSecret`, and `tokenEndpoint` are provided → uses them directly (no registration)
|
|
191
|
+
2. Otherwise, starts background registration with identity-api:
|
|
192
|
+
- Calls `POST /internal/services/register` with `regenerateSecret: false`
|
|
193
|
+
- If the service already exists and no secret is returned, retries with `regenerateSecret: true`
|
|
194
|
+
- Verifies credentials by obtaining an initial token
|
|
195
|
+
- Retries with exponential backoff on failure
|
|
196
|
+
|
|
197
|
+
### IdentityApiClient
|
|
198
|
+
|
|
199
|
+
Standalone HTTP client for direct identity-api calls. Does not require NestJS.
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
import { IdentityApiClient } from '@xemahq/identity-client';
|
|
203
|
+
|
|
204
|
+
const client = new IdentityApiClient({
|
|
205
|
+
baseUrl: 'http://identity-api:3053',
|
|
206
|
+
internalToken: 'your-token',
|
|
207
|
+
timeoutMs: 10000, // optional, default: 10000
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
// Register a service and get credentials
|
|
211
|
+
const credentials = await client.registerService({
|
|
212
|
+
name: 'my-service',
|
|
213
|
+
displayName: 'My Service',
|
|
214
|
+
serviceType: 'BACKEND',
|
|
215
|
+
regenerateSecret: false,
|
|
216
|
+
});
|
|
217
|
+
// → { clientId, clientSecret, tokenEndpoint, roles }
|
|
218
|
+
|
|
219
|
+
// Full response with metadata
|
|
220
|
+
const response = await client.registerServiceFull({
|
|
221
|
+
name: 'my-service',
|
|
222
|
+
displayName: 'My Service',
|
|
223
|
+
serviceType: 'BACKEND',
|
|
224
|
+
regenerateSecret: false,
|
|
225
|
+
});
|
|
226
|
+
// → { id, clientSecret, tokenEndpoint, roles, alreadyExisted, secretRegenerated }
|
|
227
|
+
|
|
228
|
+
// Verify organization membership
|
|
229
|
+
const membership = await client.verifyMembership(userId, orgId);
|
|
230
|
+
// → { isMember, role }
|
|
231
|
+
|
|
232
|
+
// Create system organization (idempotent)
|
|
233
|
+
const org = await client.ensureSystemOrg({
|
|
234
|
+
name: 'system',
|
|
235
|
+
displayName: 'System Organization',
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
// Get system organization by name
|
|
239
|
+
const systemOrg = await client.getSystemOrg('system');
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Error Handling
|
|
243
|
+
|
|
244
|
+
All client methods throw `IdentityApiError` on failure:
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
import { IdentityApiError } from '@xemahq/identity-client';
|
|
248
|
+
|
|
249
|
+
try {
|
|
250
|
+
await client.registerService({ ... });
|
|
251
|
+
} catch (error) {
|
|
252
|
+
if (error instanceof IdentityApiError) {
|
|
253
|
+
console.error(error.statusCode); // HTTP status
|
|
254
|
+
console.error(error.message); // Error message
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Pre-configured Credentials
|
|
260
|
+
|
|
261
|
+
For production multi-replica deployments, you can skip auto-registration by providing credentials via environment variables. This avoids the secret regeneration race condition when multiple pods start simultaneously.
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
IdentityBootstrapModule.forRootAsync({
|
|
265
|
+
imports: [ConfigModule],
|
|
266
|
+
useFactory: (config: ConfigService) => ({
|
|
267
|
+
identityApiUrl: config.getOrThrow('IDENTITY_API_URL'),
|
|
268
|
+
identityApiInternalToken: config.getOrThrow('IDENTITY_API_INTERNAL_TOKEN'),
|
|
269
|
+
serviceName: 'my-service',
|
|
270
|
+
serviceDisplayName: 'My Service',
|
|
271
|
+
// Pre-configured credentials — skip registration entirely
|
|
272
|
+
clientId: config.get('SERVICE_CLIENT_ID'),
|
|
273
|
+
clientSecret: config.get('SERVICE_CLIENT_SECRET'),
|
|
274
|
+
tokenEndpoint: config.get('SERVICE_TOKEN_ENDPOINT'),
|
|
275
|
+
}),
|
|
276
|
+
inject: [ConfigService],
|
|
277
|
+
});
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
When all three (`clientId`, `clientSecret`, `tokenEndpoint`) are provided, `IdentityBootstrapService` validates them on startup and enters ready state immediately. If validation fails, the module throws (hard fail).
|
|
281
|
+
|
|
282
|
+
## Exports
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
// Classes
|
|
286
|
+
export { IdentityApiClient } from './client';
|
|
287
|
+
export { IdentityApiError } from './client';
|
|
288
|
+
|
|
289
|
+
// NestJS module
|
|
290
|
+
export { IdentityBootstrapModule } from './nestjs';
|
|
291
|
+
export { IdentityBootstrapService } from './nestjs';
|
|
292
|
+
export { IDENTITY_BOOTSTRAP_CONFIG } from './nestjs';
|
|
293
|
+
|
|
294
|
+
// Types
|
|
295
|
+
export type {
|
|
296
|
+
IdentityApiClientOptions,
|
|
297
|
+
IdentityBootstrapConfig,
|
|
298
|
+
IdentityBootstrapModuleAsyncOptions,
|
|
299
|
+
RegisterServiceRequest,
|
|
300
|
+
RegisterServiceResponse,
|
|
301
|
+
ServiceCredentials,
|
|
302
|
+
ServiceType,
|
|
303
|
+
VerifyMembershipParams,
|
|
304
|
+
VerifyMembershipResponse,
|
|
305
|
+
EnsureSystemOrgRequest,
|
|
306
|
+
Organization,
|
|
307
|
+
ApiEnvelope,
|
|
308
|
+
} from './types';
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
## License
|
|
312
|
+
|
|
313
|
+
MIT
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { EnsureSystemOrgRequest, IdentityApiClientOptions, OnBehalfOfTokenRequest, OnBehalfOfTokenResponse, Organization, RegisterServiceRequest, RegisterServiceResponse, ServiceCredentials, VerifyMembershipResponse } from './types';
|
|
2
|
+
export declare class IdentityApiClient {
|
|
3
|
+
private readonly baseUrl;
|
|
4
|
+
private readonly internalToken;
|
|
5
|
+
private readonly timeoutMs;
|
|
6
|
+
constructor(options: IdentityApiClientOptions);
|
|
7
|
+
registerService(request: RegisterServiceRequest): Promise<ServiceCredentials>;
|
|
8
|
+
registerServiceFull(request: RegisterServiceRequest): Promise<RegisterServiceResponse>;
|
|
9
|
+
verifyMembership(userId: string, orgId: string, realm?: string): Promise<VerifyMembershipResponse>;
|
|
10
|
+
ensureSystemOrg(request: EnsureSystemOrgRequest): Promise<Organization>;
|
|
11
|
+
getSystemOrg(name: string): Promise<Organization>;
|
|
12
|
+
listOrgIds(realm: string): Promise<string[]>;
|
|
13
|
+
mintOnBehalfOfToken(request: OnBehalfOfTokenRequest): Promise<OnBehalfOfTokenResponse>;
|
|
14
|
+
private get;
|
|
15
|
+
private post;
|
|
16
|
+
private request;
|
|
17
|
+
}
|
|
18
|
+
export declare class IdentityApiError extends Error {
|
|
19
|
+
readonly statusCode: number;
|
|
20
|
+
readonly responseBody?: string | undefined;
|
|
21
|
+
constructor(message: string, statusCode: number, responseBody?: string | undefined);
|
|
22
|
+
}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IdentityApiError = exports.IdentityApiClient = void 0;
|
|
4
|
+
class IdentityApiClient {
|
|
5
|
+
baseUrl;
|
|
6
|
+
internalToken;
|
|
7
|
+
timeoutMs;
|
|
8
|
+
constructor(options) {
|
|
9
|
+
this.baseUrl = options.baseUrl.replace(/\/$/, '');
|
|
10
|
+
this.internalToken = options.internalToken;
|
|
11
|
+
this.timeoutMs = options.timeoutMs ?? 10_000;
|
|
12
|
+
}
|
|
13
|
+
async registerService(request) {
|
|
14
|
+
const body = {
|
|
15
|
+
serviceType: 'BACKEND',
|
|
16
|
+
...request,
|
|
17
|
+
};
|
|
18
|
+
const response = await this.post('/internal/services/register', body);
|
|
19
|
+
return {
|
|
20
|
+
clientId: response.id,
|
|
21
|
+
clientSecret: response.clientSecret,
|
|
22
|
+
tokenEndpoint: response.tokenEndpoint,
|
|
23
|
+
roles: response.roles,
|
|
24
|
+
keycloakBaseUrl: response.keycloakBaseUrl,
|
|
25
|
+
allowedRealms: response.allowedRealms,
|
|
26
|
+
primaryRealm: response.primaryRealm,
|
|
27
|
+
internalTokenScope: response.internalTokenScope,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
async registerServiceFull(request) {
|
|
31
|
+
const body = {
|
|
32
|
+
serviceType: 'BACKEND',
|
|
33
|
+
...request,
|
|
34
|
+
};
|
|
35
|
+
return this.post('/internal/services/register', body);
|
|
36
|
+
}
|
|
37
|
+
async verifyMembership(userId, orgId, realm) {
|
|
38
|
+
const params = new URLSearchParams({ userId, orgId });
|
|
39
|
+
if (realm) {
|
|
40
|
+
params.set('realm', realm);
|
|
41
|
+
}
|
|
42
|
+
return this.get(`/internal/verify-membership?${params.toString()}`);
|
|
43
|
+
}
|
|
44
|
+
async ensureSystemOrg(request) {
|
|
45
|
+
return this.post('/internal/organizations/ensure-system', request);
|
|
46
|
+
}
|
|
47
|
+
async getSystemOrg(name) {
|
|
48
|
+
return this.get(`/internal/organizations/system?name=${encodeURIComponent(name)}`);
|
|
49
|
+
}
|
|
50
|
+
async listOrgIds(realm) {
|
|
51
|
+
return this.get(`/internal/organizations/all-ids?realm=${encodeURIComponent(realm)}`);
|
|
52
|
+
}
|
|
53
|
+
async mintOnBehalfOfToken(request) {
|
|
54
|
+
return this.post('/internal/tokens/on-behalf-of', request);
|
|
55
|
+
}
|
|
56
|
+
async get(path) {
|
|
57
|
+
const response = await this.request('GET', path);
|
|
58
|
+
const envelope = (await response.json());
|
|
59
|
+
return envelope.data;
|
|
60
|
+
}
|
|
61
|
+
async post(path, body) {
|
|
62
|
+
const response = await this.request('POST', path, body);
|
|
63
|
+
const envelope = (await response.json());
|
|
64
|
+
return envelope.data;
|
|
65
|
+
}
|
|
66
|
+
async request(method, path, body) {
|
|
67
|
+
const url = `${this.baseUrl}${path}`;
|
|
68
|
+
const controller = new AbortController();
|
|
69
|
+
const timeout = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
70
|
+
try {
|
|
71
|
+
const response = await fetch(url, {
|
|
72
|
+
method,
|
|
73
|
+
headers: {
|
|
74
|
+
'Content-Type': 'application/json',
|
|
75
|
+
Authorization: `Bearer ${this.internalToken}`,
|
|
76
|
+
},
|
|
77
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
78
|
+
signal: controller.signal,
|
|
79
|
+
});
|
|
80
|
+
if (!response.ok) {
|
|
81
|
+
const text = await response.text().catch(() => '');
|
|
82
|
+
throw new IdentityApiError(`identity-api ${method} ${path} failed: ${response.status} ${response.statusText}`, response.status, text);
|
|
83
|
+
}
|
|
84
|
+
return response;
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
if (error instanceof IdentityApiError)
|
|
88
|
+
throw error;
|
|
89
|
+
if (error.name === 'AbortError') {
|
|
90
|
+
throw new IdentityApiError(`identity-api ${method} ${path} timed out after ${this.timeoutMs}ms`, 0);
|
|
91
|
+
}
|
|
92
|
+
throw new IdentityApiError(`identity-api ${method} ${path} failed: ${error instanceof Error ? error.message : String(error)}`, 0);
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
clearTimeout(timeout);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
exports.IdentityApiClient = IdentityApiClient;
|
|
100
|
+
class IdentityApiError extends Error {
|
|
101
|
+
statusCode;
|
|
102
|
+
responseBody;
|
|
103
|
+
constructor(message, statusCode, responseBody) {
|
|
104
|
+
super(message);
|
|
105
|
+
this.statusCode = statusCode;
|
|
106
|
+
this.responseBody = responseBody;
|
|
107
|
+
this.name = 'IdentityApiError';
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
exports.IdentityApiError = IdentityApiError;
|
|
111
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { IdentityApiClient, IdentityApiError } from './client';
|
|
2
|
+
export { OrgRole, ORG_ADMIN_ROLES, } from './types';
|
|
3
|
+
export type { ApiEnvelope, EnsureSystemOrgRequest, IdentityApiClientOptions, Organization, RegisterServiceRequest, RegisterServiceResponse, ServiceCredentials, ServiceType, VerifyMembershipParams, VerifyMembershipResponse, } from './types';
|
|
4
|
+
export { IdentityBootstrapModule, IdentityBootstrapModuleAsyncOptions, IdentityBootstrapService, IdentityBootstrapConfig, IDENTITY_BOOTSTRAP_CONFIG, } from './nestjs';
|
|
5
|
+
export { OrgAuthModule, OrgAdminGuard, ORG_AUTH_CONFIG, type OrgAuthConfig, type OrgAuthModuleAsyncOptions, } from './nestjs';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ORG_AUTH_CONFIG = exports.OrgAdminGuard = exports.OrgAuthModule = exports.IDENTITY_BOOTSTRAP_CONFIG = exports.IdentityBootstrapService = exports.IdentityBootstrapModule = exports.ORG_ADMIN_ROLES = exports.OrgRole = exports.IdentityApiError = exports.IdentityApiClient = void 0;
|
|
4
|
+
var client_1 = require("./client");
|
|
5
|
+
Object.defineProperty(exports, "IdentityApiClient", { enumerable: true, get: function () { return client_1.IdentityApiClient; } });
|
|
6
|
+
Object.defineProperty(exports, "IdentityApiError", { enumerable: true, get: function () { return client_1.IdentityApiError; } });
|
|
7
|
+
var types_1 = require("./types");
|
|
8
|
+
Object.defineProperty(exports, "OrgRole", { enumerable: true, get: function () { return types_1.OrgRole; } });
|
|
9
|
+
Object.defineProperty(exports, "ORG_ADMIN_ROLES", { enumerable: true, get: function () { return types_1.ORG_ADMIN_ROLES; } });
|
|
10
|
+
var nestjs_1 = require("./nestjs");
|
|
11
|
+
Object.defineProperty(exports, "IdentityBootstrapModule", { enumerable: true, get: function () { return nestjs_1.IdentityBootstrapModule; } });
|
|
12
|
+
Object.defineProperty(exports, "IdentityBootstrapService", { enumerable: true, get: function () { return nestjs_1.IdentityBootstrapService; } });
|
|
13
|
+
Object.defineProperty(exports, "IDENTITY_BOOTSTRAP_CONFIG", { enumerable: true, get: function () { return nestjs_1.IDENTITY_BOOTSTRAP_CONFIG; } });
|
|
14
|
+
var nestjs_2 = require("./nestjs");
|
|
15
|
+
Object.defineProperty(exports, "OrgAuthModule", { enumerable: true, get: function () { return nestjs_2.OrgAuthModule; } });
|
|
16
|
+
Object.defineProperty(exports, "OrgAdminGuard", { enumerable: true, get: function () { return nestjs_2.OrgAdminGuard; } });
|
|
17
|
+
Object.defineProperty(exports, "ORG_AUTH_CONFIG", { enumerable: true, get: function () { return nestjs_2.ORG_AUTH_CONFIG; } });
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAA+D;AAAtD,2GAAA,iBAAiB,OAAA;AAAE,0GAAA,gBAAgB,OAAA;AAC5C,iCAGiB;AAFf,gGAAA,OAAO,OAAA;AACP,wGAAA,eAAe,OAAA;AAgBjB,mCAMkB;AALhB,iHAAA,uBAAuB,OAAA;AAEvB,kHAAA,wBAAwB,OAAA;AAExB,mHAAA,yBAAyB,OAAA;AAI3B,mCAMkB;AALhB,uGAAA,aAAa,OAAA;AACb,uGAAA,aAAa,OAAA;AACb,yGAAA,eAAe,OAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { DynamicModule, Type, ForwardReference, InjectionToken } from '@nestjs/common';
|
|
2
|
+
import { IdentityBootstrapConfig } from './identity-bootstrap.service';
|
|
3
|
+
type ModuleImport = Type<unknown> | ForwardReference<unknown> | DynamicModule | Promise<DynamicModule>;
|
|
4
|
+
export interface IdentityBootstrapModuleAsyncOptions {
|
|
5
|
+
imports?: ModuleImport[];
|
|
6
|
+
useFactory: (...args: any[]) => Promise<IdentityBootstrapConfig> | IdentityBootstrapConfig;
|
|
7
|
+
inject?: InjectionToken[];
|
|
8
|
+
}
|
|
9
|
+
export declare class IdentityBootstrapModule {
|
|
10
|
+
static forRoot(config: IdentityBootstrapConfig): DynamicModule;
|
|
11
|
+
static forRootAsync(options: IdentityBootstrapModuleAsyncOptions): DynamicModule;
|
|
12
|
+
}
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var IdentityBootstrapModule_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.IdentityBootstrapModule = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const identity_bootstrap_service_1 = require("./identity-bootstrap.service");
|
|
13
|
+
let IdentityBootstrapModule = IdentityBootstrapModule_1 = class IdentityBootstrapModule {
|
|
14
|
+
static forRoot(config) {
|
|
15
|
+
const configProvider = {
|
|
16
|
+
provide: identity_bootstrap_service_1.IDENTITY_BOOTSTRAP_CONFIG,
|
|
17
|
+
useValue: config,
|
|
18
|
+
};
|
|
19
|
+
return {
|
|
20
|
+
module: IdentityBootstrapModule_1,
|
|
21
|
+
global: true,
|
|
22
|
+
providers: [configProvider, identity_bootstrap_service_1.IdentityBootstrapService],
|
|
23
|
+
exports: [identity_bootstrap_service_1.IdentityBootstrapService],
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
static forRootAsync(options) {
|
|
27
|
+
const configProvider = {
|
|
28
|
+
provide: identity_bootstrap_service_1.IDENTITY_BOOTSTRAP_CONFIG,
|
|
29
|
+
useFactory: options.useFactory,
|
|
30
|
+
inject: options.inject || [],
|
|
31
|
+
};
|
|
32
|
+
return {
|
|
33
|
+
module: IdentityBootstrapModule_1,
|
|
34
|
+
global: true,
|
|
35
|
+
imports: options.imports || [],
|
|
36
|
+
providers: [configProvider, identity_bootstrap_service_1.IdentityBootstrapService],
|
|
37
|
+
exports: [identity_bootstrap_service_1.IdentityBootstrapService],
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
exports.IdentityBootstrapModule = IdentityBootstrapModule;
|
|
42
|
+
exports.IdentityBootstrapModule = IdentityBootstrapModule = IdentityBootstrapModule_1 = __decorate([
|
|
43
|
+
(0, common_1.Module)({})
|
|
44
|
+
], IdentityBootstrapModule);
|
|
45
|
+
//# sourceMappingURL=identity-bootstrap.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity-bootstrap.module.js","sourceRoot":"","sources":["../../src/nestjs/identity-bootstrap.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAOwB;AACxB,6EAIsC;AA+D/B,IAAM,uBAAuB,+BAA7B,MAAM,uBAAuB;IAIlC,MAAM,CAAC,OAAO,CAAC,MAA+B;QAC5C,MAAM,cAAc,GAAa;YAC/B,OAAO,EAAE,sDAAyB;YAClC,QAAQ,EAAE,MAAM;SACjB,CAAC;QAEF,OAAO;YACL,MAAM,EAAE,yBAAuB;YAC/B,MAAM,EAAE,IAAI;YACZ,SAAS,EAAE,CAAC,cAAc,EAAE,qDAAwB,CAAC;YACrD,OAAO,EAAE,CAAC,qDAAwB,CAAC;SACpC,CAAC;IACJ,CAAC;IAKD,MAAM,CAAC,YAAY,CACjB,OAA4C;QAE5C,MAAM,cAAc,GAAa;YAC/B,OAAO,EAAE,sDAAyB;YAClC,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;SAC7B,CAAC;QAEF,OAAO;YACL,MAAM,EAAE,yBAAuB;YAC/B,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;YAC9B,SAAS,EAAE,CAAC,cAAc,EAAE,qDAAwB,CAAC;YACrD,OAAO,EAAE,CAAC,qDAAwB,CAAC;SACpC,CAAC;IACJ,CAAC;CACF,CAAA;AAtCY,0DAAuB;kCAAvB,uBAAuB;IADnC,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,uBAAuB,CAsCnC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { OnModuleInit, OnModuleDestroy } from '@nestjs/common';
|
|
2
|
+
export declare const IDENTITY_BOOTSTRAP_CONFIG: unique symbol;
|
|
3
|
+
export interface IdentityBootstrapConfig {
|
|
4
|
+
identityApiUrl: string;
|
|
5
|
+
identityApiInternalToken: string;
|
|
6
|
+
serviceName: string;
|
|
7
|
+
serviceDisplayName: string;
|
|
8
|
+
serviceDescription?: string;
|
|
9
|
+
keycloakUrl?: string;
|
|
10
|
+
keycloakRealm?: string;
|
|
11
|
+
clientId?: string;
|
|
12
|
+
clientSecret?: string;
|
|
13
|
+
tokenEndpoint?: string;
|
|
14
|
+
maxRegistrationAttempts?: number;
|
|
15
|
+
baseRetryDelay?: number;
|
|
16
|
+
maxRetryDelay?: number;
|
|
17
|
+
}
|
|
18
|
+
export declare class IdentityBootstrapService implements OnModuleInit, OnModuleDestroy {
|
|
19
|
+
private readonly config;
|
|
20
|
+
private readonly logger;
|
|
21
|
+
private readonly client;
|
|
22
|
+
private clientId;
|
|
23
|
+
private clientSecret;
|
|
24
|
+
private tokenEndpoint;
|
|
25
|
+
private keycloakBaseUrl;
|
|
26
|
+
private allowedRealms;
|
|
27
|
+
private primaryRealm;
|
|
28
|
+
private registrationTokenScope;
|
|
29
|
+
private accessToken;
|
|
30
|
+
private tokenExpiresAt;
|
|
31
|
+
private tokenRefreshPromise;
|
|
32
|
+
private lastCredentialFetchAt;
|
|
33
|
+
private static readonly RECOVERY_DEBOUNCE_MS;
|
|
34
|
+
private static readonly DISTRIBUTED_RECOVERY_DEBOUNCE_MS;
|
|
35
|
+
private readonly userTokenCache;
|
|
36
|
+
private readonly userTokenInflight;
|
|
37
|
+
private registrationStarted;
|
|
38
|
+
private registrationAttempts;
|
|
39
|
+
private registrationTimer;
|
|
40
|
+
private readonly maxRegistrationAttempts;
|
|
41
|
+
private readonly baseRetryDelay;
|
|
42
|
+
private readonly maxRetryDelay;
|
|
43
|
+
private readyResolve;
|
|
44
|
+
private readonly readyPromise;
|
|
45
|
+
private isReady;
|
|
46
|
+
constructor(config: IdentityBootstrapConfig);
|
|
47
|
+
onModuleInit(): Promise<void>;
|
|
48
|
+
onModuleDestroy(): void;
|
|
49
|
+
getAccessToken(): Promise<string>;
|
|
50
|
+
getUserAccessToken(params: {
|
|
51
|
+
userId: string;
|
|
52
|
+
orgId: string;
|
|
53
|
+
realm?: string;
|
|
54
|
+
audience?: string;
|
|
55
|
+
}): Promise<string>;
|
|
56
|
+
private mintUserAccessToken;
|
|
57
|
+
waitForReady(timeoutMs?: number): Promise<boolean>;
|
|
58
|
+
hasCredentials(): boolean;
|
|
59
|
+
getClientId(): string | null;
|
|
60
|
+
getKeycloakBaseUrl(): string | null;
|
|
61
|
+
getAllowedRealms(): string[];
|
|
62
|
+
isMember(orgId: string, userId: string, realm?: string): Promise<boolean>;
|
|
63
|
+
listOrgIds(): Promise<string[]>;
|
|
64
|
+
private startBackgroundRegistration;
|
|
65
|
+
private attemptRegistration;
|
|
66
|
+
private requireRegistrationMetadata;
|
|
67
|
+
private resolveUserTokenRealm;
|
|
68
|
+
private scheduleRetry;
|
|
69
|
+
private clientSecretWasSelfRegistered;
|
|
70
|
+
private refreshToken;
|
|
71
|
+
private refreshTokenWithRecovery;
|
|
72
|
+
private fetchCurrentCredentials;
|
|
73
|
+
private checkCredentialRecoveryState;
|
|
74
|
+
private recordCredentialRecovery;
|
|
75
|
+
private resolveReady;
|
|
76
|
+
}
|