Package not found. Please check the package name and try again.
@owox/idp-owox 0.0.0
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 +93 -0
- package/dist/auth/AuthorizationStore.d.ts +37 -0
- package/dist/auth/AuthorizationStore.d.ts.map +1 -0
- package/dist/auth/AuthorizationStore.js +2 -0
- package/dist/auth/AuthorizationStoreFactory.d.ts +7 -0
- package/dist/auth/AuthorizationStoreFactory.d.ts.map +1 -0
- package/dist/auth/AuthorizationStoreFactory.js +18 -0
- package/dist/auth/MysqlAuthorizationStore.d.ts +19 -0
- package/dist/auth/MysqlAuthorizationStore.d.ts.map +1 -0
- package/dist/auth/MysqlAuthorizationStore.js +84 -0
- package/dist/auth/SqliteAuthorizationStore.d.ts +20 -0
- package/dist/auth/SqliteAuthorizationStore.d.ts.map +1 -0
- package/dist/auth/SqliteAuthorizationStore.js +87 -0
- package/dist/client/IdentityOwoxClient.d.ts +27 -0
- package/dist/client/IdentityOwoxClient.d.ts.map +1 -0
- package/dist/client/IdentityOwoxClient.js +59 -0
- package/dist/client/dto/idpOwoxPayloadDto.d.ts +28 -0
- package/dist/client/dto/idpOwoxPayloadDto.d.ts.map +1 -0
- package/dist/client/dto/idpOwoxPayloadDto.js +30 -0
- package/dist/client/dto/index.d.ts +7 -0
- package/dist/client/dto/index.d.ts.map +1 -0
- package/dist/client/dto/index.js +22 -0
- package/dist/client/dto/introspectionDto.d.ts +68 -0
- package/dist/client/dto/introspectionDto.d.ts.map +1 -0
- package/dist/client/dto/introspectionDto.js +17 -0
- package/dist/client/dto/jwksDto.d.ts +100 -0
- package/dist/client/dto/jwksDto.d.ts.map +1 -0
- package/dist/client/dto/jwksDto.js +19 -0
- package/dist/client/dto/revocationDto.d.ts +9 -0
- package/dist/client/dto/revocationDto.d.ts.map +1 -0
- package/dist/client/dto/revocationDto.js +2 -0
- package/dist/client/dto/tokenDto.d.ts +30 -0
- package/dist/client/dto/tokenDto.d.ts.map +1 -0
- package/dist/client/dto/tokenDto.js +11 -0
- package/dist/client/dto/tokenType.d.ts +2 -0
- package/dist/client/dto/tokenType.d.ts.map +1 -0
- package/dist/client/dto/tokenType.js +2 -0
- package/dist/client/index.d.ts +3 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +18 -0
- package/dist/config.d.ts +192 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +174 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/mappers/idpOwoxPayloadToPayloadMapper.d.ts +3 -0
- package/dist/mappers/idpOwoxPayloadToPayloadMapper.d.ts.map +1 -0
- package/dist/mappers/idpOwoxPayloadToPayloadMapper.js +17 -0
- package/dist/owoxIdp.d.ts +25 -0
- package/dist/owoxIdp.d.ts.map +1 -0
- package/dist/owoxIdp.js +172 -0
- package/dist/pkce.d.ts +21 -0
- package/dist/pkce.d.ts.map +1 -0
- package/dist/pkce.js +34 -0
- package/dist/token/jwksCache.d.ts +19 -0
- package/dist/token/jwksCache.d.ts.map +1 -0
- package/dist/token/jwksCache.js +41 -0
- package/dist/token/parseToken.d.ts +11 -0
- package/dist/token/parseToken.d.ts.map +1 -0
- package/dist/token/parseToken.js +29 -0
- package/dist/token/verifyJwt.d.ts +9 -0
- package/dist/token/verifyJwt.d.ts.map +1 -0
- package/dist/token/verifyJwt.js +23 -0
- package/package.json +62 -0
package/README.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# @owox/idp-owox
|
|
2
|
+
|
|
3
|
+
OWOX Identity Provider implementation for OWOX Data Marts authentication.
|
|
4
|
+
This package provides the **IdP integration with OWOX Identity Platform**, handling tokens, introspection, and persistence (SQLite/MySQL).
|
|
5
|
+
|
|
6
|
+
## Setup
|
|
7
|
+
|
|
8
|
+
### 1. Environment Configuration
|
|
9
|
+
|
|
10
|
+
Create or update your `.env` file with the required settings:
|
|
11
|
+
|
|
12
|
+
```env
|
|
13
|
+
# Database (SQLite is default and recommended for getting started)
|
|
14
|
+
IDP_OWOX_DB_TYPE=sqlite
|
|
15
|
+
IDP_OWOX_SQLITE_DB_PATH=./data/auth.db
|
|
16
|
+
IDP_OWOX_SQLITE_PRAGMA=journal_mode=WAL,synchronous=NORMAL
|
|
17
|
+
|
|
18
|
+
# IdentityOwox client (OWOX Identity Platform backend)
|
|
19
|
+
IDP_OWOX_BASE_URL=https://integrated-backend.bi.owox.com
|
|
20
|
+
IDP_OWOX_TIMEOUT=3s
|
|
21
|
+
# Optional: pass default headers to every request
|
|
22
|
+
IDP_OWOX_DEFAULT_HEADERS={"x-trace-id":"debug-local"}
|
|
23
|
+
|
|
24
|
+
# IDP App configuration
|
|
25
|
+
IDP_OWOX_CLIENT_ID=app-owox
|
|
26
|
+
IDP_OWOX_PLATFORM_SIGN_IN_URL=https://bi.owox.com/ui/p/signin
|
|
27
|
+
IDP_OWOX_CALLBACK_URL=/auth/callback
|
|
28
|
+
|
|
29
|
+
# JWT validation
|
|
30
|
+
IDP_OWOX_JWT_ISSUER=https://idp.owox.com
|
|
31
|
+
IDP_OWOX_JWT_CLOCK_TOLERANCE=5s
|
|
32
|
+
IDP_OWOX_JWT_CACHE_TTL=1h
|
|
33
|
+
IDP_OWOX_JWT_ALGORITHM=RS256
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
#### SQLite Default Path
|
|
37
|
+
|
|
38
|
+
If `IDP_OWOX_SQLITE_DB_PATH` is not provided, the database file will be created automatically in the system application data directory (using env-paths).
|
|
39
|
+
|
|
40
|
+
### 2. MySQL Configuration (Alternative)
|
|
41
|
+
|
|
42
|
+
If you prefer MySQL instead of SQLite:
|
|
43
|
+
|
|
44
|
+
```env
|
|
45
|
+
IDP_OWOX_DB_TYPE=mysql
|
|
46
|
+
IDP_OWOX_MYSQL_HOST=localhost
|
|
47
|
+
IDP_OWOX_MYSQL_PORT=3306
|
|
48
|
+
IDP_OWOX_MYSQL_USER=idp_user
|
|
49
|
+
IDP_OWOX_MYSQL_PASSWORD=your-secret
|
|
50
|
+
IDP_OWOX_MYSQL_DB=idp_owox
|
|
51
|
+
# Optional
|
|
52
|
+
IDP_OWOX_MYSQL_CONNECTION_LIMIT=10
|
|
53
|
+
IDP_OWOX_MYSQL_SSL={"rejectUnauthorized":true}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 3. Authentication Flow
|
|
57
|
+
|
|
58
|
+
1. Sign In: User is redirected to OWOX Platform sign-in page (`IDP_OWOX_PLATFORM_SIGN_IN_URL`)
|
|
59
|
+
2. Callback: On success, user is redirected back to `IDP_OWOX_CALLBACK_URL`
|
|
60
|
+
3. Introspection: Tokens are validated against OWOX Identity Platform
|
|
61
|
+
4. App Sign-In: Application redirects user to Sign-In page
|
|
62
|
+
|
|
63
|
+
#### Install dependencies
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
npm install
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
#### Build
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npm run build
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
#### Type checking
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npm run typecheck
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
#### Linting
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
npm run lint
|
|
85
|
+
npm run lint:fix
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
#### Formatting
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npm run format
|
|
92
|
+
npm run format:check
|
|
93
|
+
```
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage for mapping state -> code_verifier (PKCE).
|
|
3
|
+
* No ORM usage.
|
|
4
|
+
*/
|
|
5
|
+
export interface AuthorizationStore {
|
|
6
|
+
/**
|
|
7
|
+
* Initialize connections/resources and create schema if needed.
|
|
8
|
+
*/
|
|
9
|
+
initialize(): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Save mapping state -> code_verifier.
|
|
12
|
+
* Update existing record if it already exists.
|
|
13
|
+
* @param state unique key (state)
|
|
14
|
+
* @param codeVerifier PKCE code_verifier value
|
|
15
|
+
* @param expiresAt optional expiration date (if omitted — stored without TTL)
|
|
16
|
+
*/
|
|
17
|
+
save(state: string, codeVerifier: string, expiresAt?: Date | null): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Get code_verifier by state.
|
|
20
|
+
* Must return null if record is missing or expired.
|
|
21
|
+
*/
|
|
22
|
+
get(state: string): Promise<string | null>;
|
|
23
|
+
/**
|
|
24
|
+
* Delete a record by state.
|
|
25
|
+
*/
|
|
26
|
+
delete(state: string): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Remove expired records.
|
|
29
|
+
* @returns number of removed records
|
|
30
|
+
*/
|
|
31
|
+
purgeExpired(): Promise<number>;
|
|
32
|
+
/**
|
|
33
|
+
* Graceful shutdown, close connections.
|
|
34
|
+
*/
|
|
35
|
+
shutdown(): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=AuthorizationStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthorizationStore.d.ts","sourceRoot":"","sources":["../../src/auth/AuthorizationStore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B;;;;;;OAMG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElF;;;OAGG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAE3C;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErC;;;OAGG;IACH,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAEhC;;OAEG;IACH,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AuthorizationStore } from './AuthorizationStore';
|
|
2
|
+
import type { DbConfig } from '../config';
|
|
3
|
+
/**
|
|
4
|
+
* Factory that creates AuthorizationStore implementation based on configuration.
|
|
5
|
+
*/
|
|
6
|
+
export declare function createAuthorizationStore(config: DbConfig): AuthorizationStore;
|
|
7
|
+
//# sourceMappingURL=AuthorizationStoreFactory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthorizationStoreFactory.d.ts","sourceRoot":"","sources":["../../src/auth/AuthorizationStoreFactory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1C;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,QAAQ,GAAG,kBAAkB,CAS7E"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createAuthorizationStore = createAuthorizationStore;
|
|
4
|
+
const MysqlAuthorizationStore_1 = require("./MysqlAuthorizationStore");
|
|
5
|
+
const SqliteAuthorizationStore_1 = require("./SqliteAuthorizationStore");
|
|
6
|
+
/**
|
|
7
|
+
* Factory that creates AuthorizationStore implementation based on configuration.
|
|
8
|
+
*/
|
|
9
|
+
function createAuthorizationStore(config) {
|
|
10
|
+
const type = config.type;
|
|
11
|
+
if (type === 'sqlite') {
|
|
12
|
+
return new SqliteAuthorizationStore_1.SqliteAuthorizationStore(config.sqlite);
|
|
13
|
+
}
|
|
14
|
+
if (type === 'mysql') {
|
|
15
|
+
return new MysqlAuthorizationStore_1.MysqlAuthorizationStore(config.mysql);
|
|
16
|
+
}
|
|
17
|
+
throw new Error(`Unknown store type: ${type}`);
|
|
18
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { AuthorizationStore } from './AuthorizationStore';
|
|
2
|
+
import type { MysqlConfig } from '../config';
|
|
3
|
+
/**
|
|
4
|
+
* MySQL implementation (mysql2/promise, no ORM).
|
|
5
|
+
*/
|
|
6
|
+
export declare class MysqlAuthorizationStore implements AuthorizationStore {
|
|
7
|
+
private readonly config;
|
|
8
|
+
private pool?;
|
|
9
|
+
constructor(config: MysqlConfig);
|
|
10
|
+
initialize(): Promise<void>;
|
|
11
|
+
save(state: string, codeVerifier: string, expiresAt?: Date | null): Promise<void>;
|
|
12
|
+
get(state: string): Promise<string | null>;
|
|
13
|
+
delete(state: string): Promise<void>;
|
|
14
|
+
purgeExpired(): Promise<number>;
|
|
15
|
+
shutdown(): Promise<void>;
|
|
16
|
+
private getPool;
|
|
17
|
+
}
|
|
18
|
+
export default MysqlAuthorizationStore;
|
|
19
|
+
//# sourceMappingURL=MysqlAuthorizationStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MysqlAuthorizationStore.d.ts","sourceRoot":"","sources":["../../src/auth/MysqlAuthorizationStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAG7C;;GAEG;AACH,qBAAa,uBAAwB,YAAW,kBAAkB;IAGpD,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,OAAO,CAAC,IAAI,CAAC,CAAO;gBAES,MAAM,EAAE,WAAW;IAE1C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAgC3B,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAcjF,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAuB1C,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpC,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAO/B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAO/B,OAAO,CAAC,OAAO;CAIhB;AAED,eAAe,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MysqlAuthorizationStore = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* MySQL implementation (mysql2/promise, no ORM).
|
|
6
|
+
*/
|
|
7
|
+
class MysqlAuthorizationStore {
|
|
8
|
+
config;
|
|
9
|
+
pool;
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.config = config;
|
|
12
|
+
}
|
|
13
|
+
async initialize() {
|
|
14
|
+
const mysql = await import('mysql2/promise');
|
|
15
|
+
this.pool = mysql.createPool({
|
|
16
|
+
host: this.config.host,
|
|
17
|
+
port: this.config.port ?? 3306,
|
|
18
|
+
user: this.config.user,
|
|
19
|
+
password: this.config.password,
|
|
20
|
+
database: this.config.database,
|
|
21
|
+
waitForConnections: true,
|
|
22
|
+
connectionLimit: this.config.connectionLimit ?? 10,
|
|
23
|
+
ssl: this.config.ssl,
|
|
24
|
+
});
|
|
25
|
+
await this.getPool().query(`
|
|
26
|
+
CREATE TABLE IF NOT EXISTS auth_states (
|
|
27
|
+
state VARCHAR(255) NOT NULL PRIMARY KEY,
|
|
28
|
+
code_verifier VARCHAR(255) NOT NULL,
|
|
29
|
+
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
30
|
+
expires_at TIMESTAMP NULL
|
|
31
|
+
)
|
|
32
|
+
`);
|
|
33
|
+
try {
|
|
34
|
+
await this.getPool().query(`CREATE INDEX idx_auth_states_expires_at ON auth_states (expires_at)`);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// index already exists
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async save(state, codeVerifier, expiresAt) {
|
|
41
|
+
const exp = expiresAt ?? null;
|
|
42
|
+
await this.getPool().execute(`INSERT INTO auth_states (state, code_verifier, expires_at)
|
|
43
|
+
VALUES (?, ?, ?)
|
|
44
|
+
ON DUPLICATE KEY UPDATE
|
|
45
|
+
code_verifier = VALUES(code_verifier),
|
|
46
|
+
expires_at = VALUES(expires_at),
|
|
47
|
+
created_at = CURRENT_TIMESTAMP`, [state, codeVerifier, exp]);
|
|
48
|
+
}
|
|
49
|
+
async get(state) {
|
|
50
|
+
await this.purgeExpired();
|
|
51
|
+
const [rows] = await this.getPool().execute(`SELECT code_verifier, expires_at FROM auth_states WHERE state = ? LIMIT 1`, [state]);
|
|
52
|
+
const row = Array.isArray(rows) && rows.length > 0
|
|
53
|
+
? rows[0]
|
|
54
|
+
: null;
|
|
55
|
+
if (!row)
|
|
56
|
+
return null;
|
|
57
|
+
const exp = row.expires_at ? new Date(row.expires_at) : null;
|
|
58
|
+
if (exp && exp.getTime() <= Date.now()) {
|
|
59
|
+
await this.delete(state);
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
return row.code_verifier;
|
|
63
|
+
}
|
|
64
|
+
async delete(state) {
|
|
65
|
+
await this.getPool().execute(`DELETE FROM auth_states WHERE state = ?`, [state]);
|
|
66
|
+
}
|
|
67
|
+
async purgeExpired() {
|
|
68
|
+
const [result] = await this.getPool().execute(`DELETE FROM auth_states WHERE expires_at IS NOT NULL AND expires_at <= CURRENT_TIMESTAMP`);
|
|
69
|
+
return result.affectedRows ?? 0;
|
|
70
|
+
}
|
|
71
|
+
async shutdown() {
|
|
72
|
+
if (this.pool) {
|
|
73
|
+
await this.pool.end();
|
|
74
|
+
this.pool = undefined;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
getPool() {
|
|
78
|
+
if (!this.pool)
|
|
79
|
+
throw new Error('MysqlAuthorizationStore is not initialized');
|
|
80
|
+
return this.pool;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
exports.MysqlAuthorizationStore = MysqlAuthorizationStore;
|
|
84
|
+
exports.default = MysqlAuthorizationStore;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AuthorizationStore } from './AuthorizationStore';
|
|
2
|
+
import type { SqliteConfig } from '../config';
|
|
3
|
+
/**
|
|
4
|
+
* SQLite implementation (better-sqlite3, no ORM).
|
|
5
|
+
*/
|
|
6
|
+
export declare class SqliteAuthorizationStore implements AuthorizationStore {
|
|
7
|
+
private readonly config;
|
|
8
|
+
private db?;
|
|
9
|
+
constructor(config: SqliteConfig);
|
|
10
|
+
initialize(): Promise<void>;
|
|
11
|
+
save(state: string, codeVerifier: string, expiresAt?: Date | null): Promise<void>;
|
|
12
|
+
get(state: string): Promise<string | null>;
|
|
13
|
+
delete(state: string): Promise<void>;
|
|
14
|
+
purgeExpired(): Promise<number>;
|
|
15
|
+
shutdown(): Promise<void>;
|
|
16
|
+
private getTime;
|
|
17
|
+
private getDb;
|
|
18
|
+
}
|
|
19
|
+
export default SqliteAuthorizationStore;
|
|
20
|
+
//# sourceMappingURL=SqliteAuthorizationStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SqliteAuthorizationStore.d.ts","sourceRoot":"","sources":["../../src/auth/SqliteAuthorizationStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAG9C;;GAEG;AACH,qBAAa,wBAAyB,YAAW,kBAAkB;IAGrD,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,OAAO,CAAC,EAAE,CAAC,CAAW;gBAEO,MAAM,EAAE,YAAY;IAE3C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB3B,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAcjF,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAmB1C,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpC,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAQ/B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAO/B,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,KAAK;CAId;AAED,eAAe,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SqliteAuthorizationStore = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* SQLite implementation (better-sqlite3, no ORM).
|
|
6
|
+
*/
|
|
7
|
+
class SqliteAuthorizationStore {
|
|
8
|
+
config;
|
|
9
|
+
db;
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.config = config;
|
|
12
|
+
}
|
|
13
|
+
async initialize() {
|
|
14
|
+
// Lazy require to avoid typing/runtime coupling during build
|
|
15
|
+
const { default: Database } = await import('better-sqlite3');
|
|
16
|
+
this.db = new Database(this.config.dbPath, { fileMustExist: false });
|
|
17
|
+
if (this.config.pragma && this.config.pragma.length > 0) {
|
|
18
|
+
for (const p of this.config.pragma) {
|
|
19
|
+
this.db.pragma(p);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
this.db.pragma('journal_mode = WAL');
|
|
24
|
+
}
|
|
25
|
+
this.db.exec(`
|
|
26
|
+
CREATE TABLE IF NOT EXISTS auth_states (
|
|
27
|
+
state TEXT PRIMARY KEY,
|
|
28
|
+
code_verifier TEXT NOT NULL,
|
|
29
|
+
created_at INTEGER NOT NULL DEFAULT (strftime('%s','now')),
|
|
30
|
+
expires_at INTEGER
|
|
31
|
+
);
|
|
32
|
+
CREATE INDEX IF NOT EXISTS idx_auth_states_expires_at ON auth_states(expires_at);`);
|
|
33
|
+
}
|
|
34
|
+
async save(state, codeVerifier, expiresAt) {
|
|
35
|
+
this.getDb();
|
|
36
|
+
const exp = expiresAt ? this.getTime(expiresAt) : null;
|
|
37
|
+
const stmt = this.getDb().prepare(`INSERT INTO auth_states (state, code_verifier, expires_at)
|
|
38
|
+
VALUES (?, ?, ?)
|
|
39
|
+
ON CONFLICT(state) DO UPDATE SET
|
|
40
|
+
code_verifier = excluded.code_verifier,
|
|
41
|
+
expires_at = excluded.expires_at,
|
|
42
|
+
created_at = strftime('%s','now')`);
|
|
43
|
+
stmt.run(state, codeVerifier, exp);
|
|
44
|
+
}
|
|
45
|
+
async get(state) {
|
|
46
|
+
this.getDb();
|
|
47
|
+
const now = this.getTime();
|
|
48
|
+
await this.purgeExpired();
|
|
49
|
+
const row = this.getDb()
|
|
50
|
+
.prepare(`SELECT code_verifier, expires_at FROM auth_states WHERE state = ?`)
|
|
51
|
+
.get(state);
|
|
52
|
+
if (!row)
|
|
53
|
+
return null;
|
|
54
|
+
if (row.expires_at != null && row.expires_at <= now) {
|
|
55
|
+
await this.delete(state);
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
return row.code_verifier;
|
|
59
|
+
}
|
|
60
|
+
async delete(state) {
|
|
61
|
+
this.getDb().prepare(`DELETE FROM auth_states WHERE state = ?`).run(state);
|
|
62
|
+
}
|
|
63
|
+
async purgeExpired() {
|
|
64
|
+
const now = this.getTime();
|
|
65
|
+
const res = this.getDb()
|
|
66
|
+
.prepare(`DELETE FROM auth_states WHERE expires_at IS NOT NULL AND expires_at <= ?`)
|
|
67
|
+
.run(now);
|
|
68
|
+
return typeof res.changes === 'number' ? res.changes : 0;
|
|
69
|
+
}
|
|
70
|
+
async shutdown() {
|
|
71
|
+
if (this.db) {
|
|
72
|
+
this.db.close();
|
|
73
|
+
this.db = undefined;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
getTime(date) {
|
|
77
|
+
const ms = date ? date.getTime() : Date.now();
|
|
78
|
+
return Math.floor(ms / 1000);
|
|
79
|
+
}
|
|
80
|
+
getDb() {
|
|
81
|
+
if (!this.db)
|
|
82
|
+
throw new Error('SqliteAuthorizationStore is not initialized');
|
|
83
|
+
return this.db;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
exports.SqliteAuthorizationStore = SqliteAuthorizationStore;
|
|
87
|
+
exports.default = SqliteAuthorizationStore;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { TokenRequest, TokenResponse, RevocationRequest, RevocationResponse, IntrospectionRequest, IntrospectionResponse, JwksResponse } from './dto';
|
|
2
|
+
import { IdentityOwoxClientConfig } from '../config';
|
|
3
|
+
/**
|
|
4
|
+
* Represents a client for interacting with the Identity OWOX API.
|
|
5
|
+
* Provides methods for token management, validation, and retrieval of key sets.
|
|
6
|
+
*/
|
|
7
|
+
export declare class IdentityOwoxClient {
|
|
8
|
+
private readonly http;
|
|
9
|
+
constructor(config: IdentityOwoxClientConfig);
|
|
10
|
+
/**
|
|
11
|
+
* POST /api/idp/token
|
|
12
|
+
*/
|
|
13
|
+
getToken(req: TokenRequest): Promise<TokenResponse>;
|
|
14
|
+
/**
|
|
15
|
+
* POST /api/idp/revocation
|
|
16
|
+
*/
|
|
17
|
+
revokeToken(req: RevocationRequest): Promise<RevocationResponse>;
|
|
18
|
+
/**
|
|
19
|
+
* GET /api/idp/introspection
|
|
20
|
+
*/
|
|
21
|
+
introspectToken(req: IntrospectionRequest): Promise<IntrospectionResponse>;
|
|
22
|
+
/**
|
|
23
|
+
* GET /api/idp/.well-known/jwks.json
|
|
24
|
+
*/
|
|
25
|
+
getJwks(): Promise<JwksResponse>;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=IdentityOwoxClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IdentityOwoxClient.d.ts","sourceRoot":"","sources":["../../src/client/IdentityOwoxClient.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,YAAY,EAIb,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAGrD;;;GAGG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;gBAEzB,MAAM,EAAE,wBAAwB;IAW5C;;OAEG;IACG,QAAQ,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAKzD;;OAEG;IACG,WAAW,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAKtE;;OAEG;IACG,eAAe,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAUhF;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,YAAY,CAAC;CAIvC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.IdentityOwoxClient = void 0;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
const dto_1 = require("./dto");
|
|
9
|
+
const ms_1 = __importDefault(require("ms"));
|
|
10
|
+
/**
|
|
11
|
+
* Represents a client for interacting with the Identity OWOX API.
|
|
12
|
+
* Provides methods for token management, validation, and retrieval of key sets.
|
|
13
|
+
*/
|
|
14
|
+
class IdentityOwoxClient {
|
|
15
|
+
http;
|
|
16
|
+
constructor(config) {
|
|
17
|
+
this.http = axios_1.default.create({
|
|
18
|
+
baseURL: config.baseUrl,
|
|
19
|
+
timeout: (0, ms_1.default)(config.clientTimeout),
|
|
20
|
+
headers: {
|
|
21
|
+
'Content-Type': 'application/json',
|
|
22
|
+
...(config.defaultHeaders ?? {}),
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* POST /api/idp/token
|
|
28
|
+
*/
|
|
29
|
+
async getToken(req) {
|
|
30
|
+
const { data } = await this.http.post('/api/idp/token', req);
|
|
31
|
+
return dto_1.TokenResponseSchema.parse(data);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* POST /api/idp/revocation
|
|
35
|
+
*/
|
|
36
|
+
async revokeToken(req) {
|
|
37
|
+
const resp = await this.http.post('/api/idp/revocation', req);
|
|
38
|
+
return { success: resp.status >= 200 && resp.status < 300 };
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* GET /api/idp/introspection
|
|
42
|
+
*/
|
|
43
|
+
async introspectToken(req) {
|
|
44
|
+
const { data } = await this.http.get('/api/idp/introspection', {
|
|
45
|
+
headers: {
|
|
46
|
+
Authorization: req.token,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
return dto_1.IntrospectionResponseSchema.parse(data);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* GET /api/idp/.well-known/jwks.json
|
|
53
|
+
*/
|
|
54
|
+
async getJwks() {
|
|
55
|
+
const { data } = await this.http.get('/api/idp/.well-known/jwks.json');
|
|
56
|
+
return dto_1.JwksResponseSchema.parse(data);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.IdentityOwoxClient = IdentityOwoxClient;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const IdpOwoxPayloadSchema: z.ZodObject<{
|
|
3
|
+
userId: z.ZodString;
|
|
4
|
+
projectId: z.ZodString;
|
|
5
|
+
userEmail: z.ZodString;
|
|
6
|
+
userFullName: z.ZodString;
|
|
7
|
+
userAvatar: z.ZodString;
|
|
8
|
+
roles: z.ZodEffects<z.ZodEffects<z.ZodArray<z.ZodEnum<["admin", "editor", "viewer"]>, "atleastone">, ("admin" | "editor" | "viewer")[], ["admin" | "editor" | "viewer", ...("admin" | "editor" | "viewer")[]]>, ("admin" | "editor" | "viewer")[], unknown>;
|
|
9
|
+
projectTitle: z.ZodString;
|
|
10
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
11
|
+
userId: z.ZodString;
|
|
12
|
+
projectId: z.ZodString;
|
|
13
|
+
userEmail: z.ZodString;
|
|
14
|
+
userFullName: z.ZodString;
|
|
15
|
+
userAvatar: z.ZodString;
|
|
16
|
+
roles: z.ZodEffects<z.ZodEffects<z.ZodArray<z.ZodEnum<["admin", "editor", "viewer"]>, "atleastone">, ("admin" | "editor" | "viewer")[], ["admin" | "editor" | "viewer", ...("admin" | "editor" | "viewer")[]]>, ("admin" | "editor" | "viewer")[], unknown>;
|
|
17
|
+
projectTitle: z.ZodString;
|
|
18
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
19
|
+
userId: z.ZodString;
|
|
20
|
+
projectId: z.ZodString;
|
|
21
|
+
userEmail: z.ZodString;
|
|
22
|
+
userFullName: z.ZodString;
|
|
23
|
+
userAvatar: z.ZodString;
|
|
24
|
+
roles: z.ZodEffects<z.ZodEffects<z.ZodArray<z.ZodEnum<["admin", "editor", "viewer"]>, "atleastone">, ("admin" | "editor" | "viewer")[], ["admin" | "editor" | "viewer", ...("admin" | "editor" | "viewer")[]]>, ("admin" | "editor" | "viewer")[], unknown>;
|
|
25
|
+
projectTitle: z.ZodString;
|
|
26
|
+
}, z.ZodTypeAny, "passthrough">>;
|
|
27
|
+
export type IdpOwoxPayload = z.infer<typeof IdpOwoxPayloadSchema>;
|
|
28
|
+
//# sourceMappingURL=idpOwoxPayloadDto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idpOwoxPayloadDto.d.ts","sourceRoot":"","sources":["../../../src/client/dto/idpOwoxPayloadDto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;gCA2BjB,CAAC;AAEjB,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IdpOwoxPayloadSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const idp_protocol_1 = require("@owox/idp-protocol");
|
|
6
|
+
exports.IdpOwoxPayloadSchema = zod_1.z
|
|
7
|
+
.object({
|
|
8
|
+
userId: zod_1.z.string().min(1, 'userId is required'),
|
|
9
|
+
projectId: zod_1.z.string().min(1, 'projectId is required'),
|
|
10
|
+
userEmail: zod_1.z.string().email(),
|
|
11
|
+
userFullName: zod_1.z.string().min(1, 'userFullName is required'),
|
|
12
|
+
userAvatar: zod_1.z.string().url(),
|
|
13
|
+
roles: zod_1.z.preprocess(val => {
|
|
14
|
+
if (typeof val === 'string') {
|
|
15
|
+
return val
|
|
16
|
+
.split(',')
|
|
17
|
+
.map(r => r.trim().toLowerCase())
|
|
18
|
+
.filter(Boolean);
|
|
19
|
+
}
|
|
20
|
+
if (Array.isArray(val)) {
|
|
21
|
+
return val.map(r => String(r).trim().toLowerCase()).filter(Boolean);
|
|
22
|
+
}
|
|
23
|
+
return [];
|
|
24
|
+
}, zod_1.z
|
|
25
|
+
.array(idp_protocol_1.RoleEnum)
|
|
26
|
+
.nonempty()
|
|
27
|
+
.transform(arr => Array.from(new Set(arr)))),
|
|
28
|
+
projectTitle: zod_1.z.string().min(1, 'projectTitle is required'),
|
|
29
|
+
})
|
|
30
|
+
.passthrough();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/dto/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./jwksDto"), exports);
|
|
18
|
+
__exportStar(require("./tokenDto"), exports);
|
|
19
|
+
__exportStar(require("./introspectionDto"), exports);
|
|
20
|
+
__exportStar(require("./revocationDto"), exports);
|
|
21
|
+
__exportStar(require("./tokenType"), exports);
|
|
22
|
+
__exportStar(require("./idpOwoxPayloadDto"), exports);
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export interface IntrospectionRequest {
|
|
3
|
+
token: string;
|
|
4
|
+
}
|
|
5
|
+
export declare const IntrospectionResponseSchema: z.ZodDiscriminatedUnion<"isActive", [z.ZodObject<{
|
|
6
|
+
userId: z.ZodString;
|
|
7
|
+
projectId: z.ZodString;
|
|
8
|
+
userEmail: z.ZodString;
|
|
9
|
+
userFullName: z.ZodString;
|
|
10
|
+
userAvatar: z.ZodString;
|
|
11
|
+
roles: z.ZodEffects<z.ZodEffects<z.ZodArray<z.ZodEnum<["admin", "editor", "viewer"]>, "atleastone">, ("admin" | "editor" | "viewer")[], ["admin" | "editor" | "viewer", ...("admin" | "editor" | "viewer")[]]>, ("admin" | "editor" | "viewer")[], unknown>;
|
|
12
|
+
projectTitle: z.ZodString;
|
|
13
|
+
} & {
|
|
14
|
+
isActive: z.ZodLiteral<true>;
|
|
15
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
16
|
+
userId: z.ZodString;
|
|
17
|
+
projectId: z.ZodString;
|
|
18
|
+
userEmail: z.ZodString;
|
|
19
|
+
userFullName: z.ZodString;
|
|
20
|
+
userAvatar: z.ZodString;
|
|
21
|
+
roles: z.ZodEffects<z.ZodEffects<z.ZodArray<z.ZodEnum<["admin", "editor", "viewer"]>, "atleastone">, ("admin" | "editor" | "viewer")[], ["admin" | "editor" | "viewer", ...("admin" | "editor" | "viewer")[]]>, ("admin" | "editor" | "viewer")[], unknown>;
|
|
22
|
+
projectTitle: z.ZodString;
|
|
23
|
+
} & {
|
|
24
|
+
isActive: z.ZodLiteral<true>;
|
|
25
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
26
|
+
userId: z.ZodString;
|
|
27
|
+
projectId: z.ZodString;
|
|
28
|
+
userEmail: z.ZodString;
|
|
29
|
+
userFullName: z.ZodString;
|
|
30
|
+
userAvatar: z.ZodString;
|
|
31
|
+
roles: z.ZodEffects<z.ZodEffects<z.ZodArray<z.ZodEnum<["admin", "editor", "viewer"]>, "atleastone">, ("admin" | "editor" | "viewer")[], ["admin" | "editor" | "viewer", ...("admin" | "editor" | "viewer")[]]>, ("admin" | "editor" | "viewer")[], unknown>;
|
|
32
|
+
projectTitle: z.ZodString;
|
|
33
|
+
} & {
|
|
34
|
+
isActive: z.ZodLiteral<true>;
|
|
35
|
+
}, z.ZodTypeAny, "passthrough">>, z.ZodObject<{
|
|
36
|
+
[x: string]: z.ZodNull;
|
|
37
|
+
userId: z.ZodNull;
|
|
38
|
+
projectId: z.ZodNull;
|
|
39
|
+
userEmail: z.ZodNull;
|
|
40
|
+
userFullName: z.ZodNull;
|
|
41
|
+
userAvatar: z.ZodNull;
|
|
42
|
+
roles: z.ZodNull;
|
|
43
|
+
projectTitle: z.ZodNull;
|
|
44
|
+
} & {
|
|
45
|
+
isActive: z.ZodLiteral<false>;
|
|
46
|
+
}, "strict", z.ZodTypeAny, {
|
|
47
|
+
[x: string]: null;
|
|
48
|
+
userId?: unknown;
|
|
49
|
+
projectId?: unknown;
|
|
50
|
+
userEmail?: unknown;
|
|
51
|
+
userFullName?: unknown;
|
|
52
|
+
userAvatar?: unknown;
|
|
53
|
+
roles?: unknown;
|
|
54
|
+
projectTitle?: unknown;
|
|
55
|
+
isActive?: unknown;
|
|
56
|
+
}, {
|
|
57
|
+
[x: string]: null;
|
|
58
|
+
userId?: unknown;
|
|
59
|
+
projectId?: unknown;
|
|
60
|
+
userEmail?: unknown;
|
|
61
|
+
userFullName?: unknown;
|
|
62
|
+
userAvatar?: unknown;
|
|
63
|
+
roles?: unknown;
|
|
64
|
+
projectTitle?: unknown;
|
|
65
|
+
isActive?: unknown;
|
|
66
|
+
}>]>;
|
|
67
|
+
export type IntrospectionResponse = z.infer<typeof IntrospectionResponseSchema>;
|
|
68
|
+
//# sourceMappingURL=introspectionDto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"introspectionDto.d.ts","sourceRoot":"","sources":["../../../src/client/dto/introspectionDto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;CACf;AAgBD,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAGtC,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC"}
|