@ah-oh/ao-workspaces-api-sdk 1.0.23 → 1.0.24
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/CHANGELOG.md +11 -0
- package/README.md +24 -21
- package/package.json +1 -1
- package/src/lib/auth.module.js +14 -23
- package/src/lib/auth.module.js.map +1 -1
- package/src/lib/customer-center.service.d.ts +42 -6
- package/src/lib/customer-center.service.js +136 -42
- package/src/lib/customer-center.service.js.map +1 -1
- package/src/lib/guards/auth.guard.js +3 -4
- package/src/lib/guards/auth.guard.js.map +1 -1
- package/src/lib/guards/company.guard.js +3 -0
- package/src/lib/guards/company.guard.js.map +1 -1
- package/src/lib/guards/sethub-permissions.guard.js +4 -1
- package/src/lib/guards/sethub-permissions.guard.js.map +1 -1
- package/src/lib/guards/super-admin.guard.js +3 -0
- package/src/lib/guards/super-admin.guard.js.map +1 -1
- package/src/lib/guards/szales-basic-auth.guard.js +33 -14
- package/src/lib/guards/szales-basic-auth.guard.js.map +1 -1
- package/src/lib/mail-settings.service.d.ts +3 -3
- package/src/lib/mail-settings.service.js +63 -251
- package/src/lib/mail-settings.service.js.map +1 -1
- package/src/lib/models/auth.options.d.ts +13 -0
- package/src/lib/print.client.d.ts +4 -3
- package/src/lib/print.client.js +46 -32
- package/src/lib/print.client.js.map +1 -1
- package/src/lib/utils/axios-error.handler.d.ts +11 -0
- package/src/lib/utils/axios-error.handler.js +24 -3
- package/src/lib/utils/axios-error.handler.js.map +1 -1
- package/src/lib/utils/http-client.d.ts +9 -0
- package/src/lib/utils/http-client.js +35 -0
- package/src/lib/utils/http-client.js.map +1 -0
- package/src/lib/utils/jwt.util.d.ts +6 -0
- package/src/lib/utils/jwt.util.js +21 -0
- package/src/lib/utils/jwt.util.js.map +1 -0
- package/src/lib/utils/ttl-cache.d.ts +26 -0
- package/src/lib/utils/ttl-cache.js +66 -0
- package/src/lib/utils/ttl-cache.js.map +1 -0
- package/src/lib/utils/url-path.d.ts +7 -0
- package/src/lib/utils/url-path.js +28 -0
- package/src/lib/utils/url-path.js.map +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
## 1.0.24 (2026-10-18)
|
|
2
|
+
|
|
3
|
+
### 🚀 Features
|
|
4
|
+
|
|
5
|
+
- **api-sdk:** cache sign-in tokens and harden requests ([ec22d4b](https://github.com/ah-oh/ao-workspaces/commit/ec22d4b))
|
|
6
|
+
|
|
7
|
+
### ❤️ Thank You
|
|
8
|
+
|
|
9
|
+
- Claude Opus 5.5
|
|
10
|
+
- Jan Kessler
|
|
11
|
+
|
|
1
12
|
## 1.0.23 (2026-09-24)
|
|
2
13
|
|
|
3
14
|
### 🚀 Features
|
package/README.md
CHANGED
|
@@ -18,8 +18,9 @@ Admin fest. Fachliche Regeln: `docs/features/hardware-connector/` im Repository
|
|
|
18
18
|
`ah-oh/ao-workspaces`.
|
|
19
19
|
|
|
20
20
|
Der `PrintClient` wird vom `AuthModule` bereitgestellt (`forRoot` oder
|
|
21
|
-
`forRootAsync`) und meldet sich
|
|
22
|
-
|
|
21
|
+
`forRootAsync`) und meldet sich mit dem User-Token der App an (`tokenId`,
|
|
22
|
+
`tokenKey`). Das JWT wird pro Zugangsdaten zwischengespeichert (siehe
|
|
23
|
+
`docs/api-sdk-authentifizierung.md`, Abschnitt Token-Cache). `product` ist die aufrufende App, **nicht** `admin` –
|
|
23
24
|
nur so gilt der Aufruf als App und der Job trägt die App als Auslöser.
|
|
24
25
|
|
|
25
26
|
```ts
|
|
@@ -47,12 +48,12 @@ const current = await printClient.getJob({
|
|
|
47
48
|
});
|
|
48
49
|
```
|
|
49
50
|
|
|
50
|
-
| Methode | Zweck
|
|
51
|
-
| -------------------- |
|
|
52
|
-
| `print` | Legt einen Job an und liefert ihn im Zustand `queued`. Optionen: `copies` (1–99), bei PDF `paperSize` und `color`, `idempotencyKey`, `expiresInSeconds`.
|
|
53
|
-
| `getJob` | Liefert den aktuellen Zustand eines Jobs inklusive `error`.
|
|
54
|
-
| `waitForJob` | Fragt den Job ab, bis er abgeschlossen ist (`completed`, `failed`, `expired`, `canceled`) oder `timeoutMs` (Standard 60 s) vergangen ist.
|
|
55
|
-
| `isFinal` (statisch) | Prüft, ob ein Job sich nicht mehr ändert. `waitForJob` liefert nach Ablauf der Wartezeit den letzten, noch offenen Zustand.
|
|
51
|
+
| Methode | Zweck |
|
|
52
|
+
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
53
|
+
| `print` | Legt einen Job an und liefert ihn im Zustand `queued`. Optionen: `copies` (1–99), bei PDF `paperSize` und `color`, `idempotencyKey`, `expiresInSeconds`. |
|
|
54
|
+
| `getJob` | Liefert den aktuellen Zustand eines Jobs inklusive `error`. |
|
|
55
|
+
| `waitForJob` | Fragt den Job ab, bis er abgeschlossen ist (`completed`, `failed`, `expired`, `canceled`) oder `timeoutMs` (Standard 60 s) vergangen ist. Nutzt ein Token für alle Abfragen. |
|
|
56
|
+
| `isFinal` (statisch) | Prüft, ob ein Job sich nicht mehr ändert. `waitForJob` liefert nach Ablauf der Wartezeit den letzten, noch offenen Zustand. |
|
|
56
57
|
|
|
57
58
|
Hinweise:
|
|
58
59
|
|
|
@@ -70,19 +71,21 @@ Fehler der Hardware-API werden als `PrintClientError` geworfen (abgeleitet von
|
|
|
70
71
|
Nests `HttpException`). `code` enthält den maschinenlesbaren Fehlercode,
|
|
71
72
|
`getStatus()` den HTTP-Status:
|
|
72
73
|
|
|
73
|
-
| `code` | Status | Bedeutung
|
|
74
|
-
| ----------------------- | ------ |
|
|
75
|
-
| `target_not_found` | 404 | Druckziel gibt es in der Company nicht
|
|
76
|
-
| `target_unassigned` | 422 | Druckziel ist keinem Drucker zugeordnet
|
|
77
|
-
| `option_not_allowed` | 422 | `paperSize` oder `color` bei ZPL
|
|
78
|
-
| `content_type_mismatch` | 422 | Drucker bzw. Druckziel akzeptiert diesen Inhaltstyp nicht
|
|
79
|
-
| `printer_disabled` | 422 | Zugeordneter Drucker ist nicht freigegeben
|
|
80
|
-
| `content_missing` | 400 | Kein Inhalt übergeben
|
|
81
|
-
| `content_invalid` | 422 | Inhalt ist kein gültiges PDF
|
|
82
|
-
| `content_too_large` | 413 | Inhalt größer als 50 MB
|
|
83
|
-
| `job_not_found` | 404 | Job-ID unbekannt
|
|
84
|
-
|
|
85
|
-
Validierungsfehler (400)
|
|
74
|
+
| `code` | Status | Bedeutung |
|
|
75
|
+
| ----------------------- | ------ | ---------------------------------------------------------------- |
|
|
76
|
+
| `target_not_found` | 404 | Druckziel gibt es in der Company nicht |
|
|
77
|
+
| `target_unassigned` | 422 | Druckziel ist keinem Drucker zugeordnet |
|
|
78
|
+
| `option_not_allowed` | 422 | `paperSize` oder `color` bei ZPL |
|
|
79
|
+
| `content_type_mismatch` | 422 | Drucker bzw. Druckziel akzeptiert diesen Inhaltstyp nicht |
|
|
80
|
+
| `printer_disabled` | 422 | Zugeordneter Drucker ist nicht freigegeben |
|
|
81
|
+
| `content_missing` | 400 | Kein Inhalt übergeben |
|
|
82
|
+
| `content_invalid` | 422 | Inhalt ist kein gültiges PDF |
|
|
83
|
+
| `content_too_large` | 413 | Inhalt größer als 50 MB (prüft schon der Client, vor dem Upload) |
|
|
84
|
+
| `job_not_found` | 404 | Job-ID unbekannt |
|
|
85
|
+
|
|
86
|
+
Validierungsfehler (400), Netzwerkfehler (502) und Zeitüberschreitungen (504)
|
|
87
|
+
haben keinen `code`. Ungültige IDs (leer, `.` oder `..`) wirft der Client
|
|
88
|
+
vorab als `BadRequestException`.
|
|
86
89
|
|
|
87
90
|
```ts
|
|
88
91
|
try {
|
package/package.json
CHANGED
package/src/lib/auth.module.js
CHANGED
|
@@ -12,39 +12,33 @@ var auth_constants_2 = require("./auth.constants");
|
|
|
12
12
|
Object.defineProperty(exports, "AUTH_MODULE_OPTIONS", { enumerable: true, get: function () { return auth_constants_2.AUTH_MODULE_OPTIONS; } });
|
|
13
13
|
Object.defineProperty(exports, "AUTH_TOKEN", { enumerable: true, get: function () { return auth_constants_2.AUTH_TOKEN; } });
|
|
14
14
|
Object.defineProperty(exports, "AUTH_MODULE", { enumerable: true, get: function () { return auth_constants_2.AUTH_MODULE; } });
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
/**
|
|
16
|
+
* `AUTH_TOKEN` points to the same instance as `CustomerCenterService`, so the
|
|
17
|
+
* guards and the clients share one token and session cache.
|
|
18
|
+
*/
|
|
19
|
+
const authTokenProvider = {
|
|
20
|
+
provide: auth_constants_1.AUTH_TOKEN,
|
|
21
|
+
useExisting: customer_center_service_1.CustomerCenterService,
|
|
21
22
|
};
|
|
23
|
+
const services = [customer_center_service_1.CustomerCenterService, mail_settings_service_1.MailSettingsService, print_client_1.PrintClient];
|
|
22
24
|
let AuthModule = AuthModule_1 = class AuthModule {
|
|
23
25
|
static forRoot(options) {
|
|
24
|
-
const provider = createAuthProvider(options);
|
|
25
26
|
return {
|
|
26
27
|
module: AuthModule_1,
|
|
27
28
|
providers: [
|
|
28
29
|
{ provide: auth_constants_1.AUTH_MODULE_OPTIONS, useValue: options },
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
mail_settings_service_1.MailSettingsService,
|
|
32
|
-
print_client_1.PrintClient,
|
|
30
|
+
authTokenProvider,
|
|
31
|
+
...services,
|
|
33
32
|
],
|
|
34
|
-
exports: [
|
|
33
|
+
exports: [auth_constants_1.AUTH_TOKEN, ...services],
|
|
35
34
|
};
|
|
36
35
|
}
|
|
37
36
|
static forRootAsync(options) {
|
|
38
|
-
const provider = {
|
|
39
|
-
inject: [auth_constants_1.AUTH_MODULE_OPTIONS],
|
|
40
|
-
provide: auth_constants_1.AUTH_TOKEN,
|
|
41
|
-
useFactory: async (options) => getAuthOptions(options),
|
|
42
|
-
};
|
|
43
37
|
return {
|
|
44
38
|
module: AuthModule_1,
|
|
45
39
|
imports: options.imports,
|
|
46
|
-
providers: [...this.createAsyncProviders(options),
|
|
47
|
-
exports: [
|
|
40
|
+
providers: [...this.createAsyncProviders(options), authTokenProvider, ...services],
|
|
41
|
+
exports: [auth_constants_1.AUTH_TOKEN, ...services],
|
|
48
42
|
};
|
|
49
43
|
}
|
|
50
44
|
static createAsyncProviders(options) {
|
|
@@ -68,10 +62,7 @@ let AuthModule = AuthModule_1 = class AuthModule {
|
|
|
68
62
|
inject: options.inject || [],
|
|
69
63
|
};
|
|
70
64
|
}
|
|
71
|
-
const inject = [
|
|
72
|
-
(options.useClass ||
|
|
73
|
-
options.useExisting),
|
|
74
|
-
];
|
|
65
|
+
const inject = [(options.useClass || options.useExisting)];
|
|
75
66
|
return {
|
|
76
67
|
provide: auth_constants_1.AUTH_MODULE_OPTIONS,
|
|
77
68
|
useFactory: async (optionsFactory) => await optionsFactory.createHttpModuleOptions(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.module.js","sourceRoot":"","sources":["../../../../../libs/api-sdk/src/lib/auth.module.ts"],"names":[],"mappings":";;;;;AAAA,2CAA+E;AAE/E,qDAAmE;AACnE,uEAAkE;AAClE,mEAA8D;AAC9D,iDAA6C;AAO7C,mDAAgF;AAAvE,qHAAA,mBAAmB,OAAA;AAAE,4GAAA,UAAU,OAAA;AAAE,6GAAA,WAAW,OAAA;AAErD,MAAM,
|
|
1
|
+
{"version":3,"file":"auth.module.js","sourceRoot":"","sources":["../../../../../libs/api-sdk/src/lib/auth.module.ts"],"names":[],"mappings":";;;;;AAAA,2CAA+E;AAE/E,qDAAmE;AACnE,uEAAkE;AAClE,mEAA8D;AAC9D,iDAA6C;AAO7C,mDAAgF;AAAvE,qHAAA,mBAAmB,OAAA;AAAE,4GAAA,UAAU,OAAA;AAAE,6GAAA,WAAW,OAAA;AAErD;;;GAGG;AACH,MAAM,iBAAiB,GAAa;IAClC,OAAO,EAAE,2BAAU;IACnB,WAAW,EAAE,+CAAqB;CACnC,CAAC;AAEF,MAAM,QAAQ,GAAG,CAAC,+CAAqB,EAAE,2CAAmB,EAAE,0BAAW,CAAC,CAAC;AAIpE,IAAM,UAAU,kBAAhB,MAAM,UAAU;IACd,MAAM,CAAC,OAAO,CAAC,OAA0B;QAC9C,OAAO;YACL,MAAM,EAAE,YAAU;YAClB,SAAS,EAAE;gBACT,EAAE,OAAO,EAAE,oCAAmB,EAAE,QAAQ,EAAE,OAAO,EAAE;gBACnD,iBAAiB;gBACjB,GAAG,QAAQ;aACZ;YACD,OAAO,EAAE,CAAC,2BAAU,EAAE,GAAG,QAAQ,CAAC;SACnC,CAAC;IACJ,CAAC;IAEM,MAAM,CAAC,YAAY,CAAC,OAA+B;QACxD,OAAO;YACL,MAAM,EAAE,YAAU;YAClB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,SAAS,EAAE,CAAC,GAAG,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,EAAE,iBAAiB,EAAE,GAAG,QAAQ,CAAC;YAClF,OAAO,EAAE,CAAC,2BAAU,EAAE,GAAG,QAAQ,CAAC;SACnC,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,oBAAoB,CAAC,OAA+B;QACjE,IAAI,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;YAC9C,OAAO,CAAC,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAmC,CAAC;QAE7D,OAAO;YACL,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC;YACxC;gBACE,OAAO,EAAE,QAAQ;gBACjB,QAAQ;aACT;SACF,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,0BAA0B,CAAC,OAA+B;QACvE,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;YACvB,OAAO;gBACL,OAAO,EAAE,oCAAmB;gBAC5B,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;aAC7B,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,WAAW,CAA4B,CAAC,CAAC;QAEtF,OAAO;YACL,OAAO,EAAE,oCAAmB;YAC5B,UAAU,EAAE,KAAK,EAAE,cAAiC,EAAE,EAAE,CACtD,MAAM,cAAc,CAAC,uBAAuB,EAAE;YAChD,MAAM;SACP,CAAC;IACJ,CAAC;CACF,CAAA;AAxDY,gCAAU;qBAAV,UAAU;IAFtB,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,UAAU,CAwDtB"}
|
|
@@ -1,25 +1,61 @@
|
|
|
1
1
|
import { ApiKey, ApiKeyType } from './models/api-key.model';
|
|
2
2
|
import { AuthModuleOptions } from './models/auth.options';
|
|
3
3
|
import { Product, UserSession } from './models/user-session.model';
|
|
4
|
+
export interface TokenSignInDto {
|
|
5
|
+
tokenId: string;
|
|
6
|
+
tokenKey: string;
|
|
7
|
+
product: Product;
|
|
8
|
+
}
|
|
4
9
|
export declare class CustomerCenterService {
|
|
5
10
|
private readonly options;
|
|
6
|
-
private
|
|
11
|
+
private readonly http;
|
|
12
|
+
/** Cache keys are HMACs, so the heap holds neither token keys nor tokens as keys. */
|
|
13
|
+
private readonly cacheKeySecret;
|
|
14
|
+
private readonly tokenCache;
|
|
15
|
+
private readonly sessionCache;
|
|
16
|
+
/** Until then `verifyInstanceToken` uses `GET /auth/verify/:token` directly. */
|
|
17
|
+
private legacyVerifyUntil;
|
|
7
18
|
constructor(options: AuthModuleOptions);
|
|
19
|
+
/**
|
|
20
|
+
* Verifies a token and returns its session. The token travels in the
|
|
21
|
+
* `Authorization` header, not in the URL, so access logs do not record it.
|
|
22
|
+
* Concurrent calls with the same token share one request; with
|
|
23
|
+
* `sessionCacheTtlMs` the session is cached.
|
|
24
|
+
*/
|
|
8
25
|
verifyInstanceToken(token: string): Promise<UserSession>;
|
|
9
26
|
sendCompanyRefreshTokenMail(id: string, expiresIn: number): Promise<{
|
|
10
27
|
done: boolean;
|
|
11
28
|
}>;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Exchanges a user token for a JWT. Unless `tokenCache` is `false`, the JWT
|
|
31
|
+
* is reused for the same credentials until shortly before it expires.
|
|
32
|
+
*/
|
|
33
|
+
tokenSignIn(dto: TokenSignInDto): Promise<{
|
|
17
34
|
token: string;
|
|
18
35
|
}>;
|
|
36
|
+
/**
|
|
37
|
+
* Runs `call` with `Bearer <jwt>` for the credentials. If the server rejects
|
|
38
|
+
* a cached token with 401, the token is dropped and `call` runs once more
|
|
39
|
+
* with a new one.
|
|
40
|
+
*/
|
|
41
|
+
withToken<T>(dto: TokenSignInDto, call: (authorization: string) => Promise<T>): Promise<T>;
|
|
42
|
+
/** Drops all cached tokens and sessions. */
|
|
43
|
+
clearCache(): void;
|
|
19
44
|
getApiKey(args: {
|
|
20
45
|
company: string;
|
|
21
46
|
type: ApiKeyType;
|
|
22
47
|
ip: string;
|
|
23
48
|
authorization: string;
|
|
24
49
|
}): Promise<ApiKey>;
|
|
50
|
+
private signIn;
|
|
51
|
+
/**
|
|
52
|
+
* Servers before `POST /auth/verify` answer it with 404; for them the token
|
|
53
|
+
* goes into the path as before.
|
|
54
|
+
*/
|
|
55
|
+
private fetchSession;
|
|
56
|
+
private tokenTtl;
|
|
57
|
+
private sessionTtl;
|
|
58
|
+
private tokenCacheKey;
|
|
59
|
+
private cacheKey;
|
|
60
|
+
private request;
|
|
25
61
|
}
|
|
@@ -3,75 +3,163 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.CustomerCenterService = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const common_1 = require("@nestjs/common");
|
|
6
|
-
const
|
|
6
|
+
const node_crypto_1 = require("node:crypto");
|
|
7
7
|
const auth_constants_1 = require("./auth.constants");
|
|
8
8
|
const axios_error_handler_1 = require("./utils/axios-error.handler");
|
|
9
|
+
const http_client_1 = require("./utils/http-client");
|
|
10
|
+
const jwt_util_1 = require("./utils/jwt.util");
|
|
11
|
+
const ttl_cache_1 = require("./utils/ttl-cache");
|
|
12
|
+
const url_path_1 = require("./utils/url-path");
|
|
13
|
+
/** Cached tokens are renewed this long before they expire. */
|
|
14
|
+
const TOKEN_REFRESH_MARGIN_MS = 5 * 60_000;
|
|
15
|
+
/** Upper bound for caching a token, so a revoked user token stops working soon. */
|
|
16
|
+
const TOKEN_MAX_CACHE_MS = 60 * 60_000;
|
|
17
|
+
const TOKEN_CACHE_SIZE = 1_000;
|
|
18
|
+
const SESSION_CACHE_SIZE = 10_000;
|
|
19
|
+
/** How long to use the legacy verify endpoint after the server lacked `POST /auth/verify`. */
|
|
20
|
+
const LEGACY_VERIFY_RECHECK_MS = 10 * 60_000;
|
|
21
|
+
/** Visible ASCII only: the token goes into a header and, on old servers, into the path. */
|
|
22
|
+
const TOKEN_PATTERN = /^[\x21-\x7e]+$/;
|
|
9
23
|
let CustomerCenterService = class CustomerCenterService {
|
|
10
24
|
options;
|
|
11
|
-
|
|
25
|
+
http;
|
|
26
|
+
/** Cache keys are HMACs, so the heap holds neither token keys nor tokens as keys. */
|
|
27
|
+
cacheKeySecret = (0, node_crypto_1.randomBytes)(32);
|
|
28
|
+
tokenCache = new ttl_cache_1.TtlCache(TOKEN_CACHE_SIZE);
|
|
29
|
+
sessionCache = new ttl_cache_1.TtlCache(SESSION_CACHE_SIZE);
|
|
30
|
+
/** Until then `verifyInstanceToken` uses `GET /auth/verify/:token` directly. */
|
|
31
|
+
legacyVerifyUntil = 0;
|
|
12
32
|
constructor(options) {
|
|
13
33
|
this.options = options;
|
|
14
|
-
this.
|
|
34
|
+
this.http = (0, http_client_1.createHttpClient)(options);
|
|
15
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Verifies a token and returns its session. The token travels in the
|
|
38
|
+
* `Authorization` header, not in the URL, so access logs do not record it.
|
|
39
|
+
* Concurrent calls with the same token share one request; with
|
|
40
|
+
* `sessionCacheTtlMs` the session is cached.
|
|
41
|
+
*/
|
|
16
42
|
async verifyInstanceToken(token) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
baseURL: this.BASE_URL,
|
|
20
|
-
url: `/auth-api/auth/verify/${token}`,
|
|
21
|
-
headers: { accept: 'application/json' },
|
|
22
|
-
};
|
|
23
|
-
try {
|
|
24
|
-
const res = await axios_1.default.request(options);
|
|
25
|
-
return res.data;
|
|
26
|
-
}
|
|
27
|
-
catch (error) {
|
|
28
|
-
(0, axios_error_handler_1.handleAxiosError)(error);
|
|
43
|
+
if (typeof token !== 'string' || !TOKEN_PATTERN.test(token) || !(0, url_path_1.isValidPathSegment)(token)) {
|
|
44
|
+
throw new common_1.UnauthorizedException('Invalid authentication token');
|
|
29
45
|
}
|
|
46
|
+
const { value } = await this.sessionCache.getOrLoad(this.cacheKey('session', token), async () => ({
|
|
47
|
+
value: await this.fetchSession(token),
|
|
48
|
+
ttlMs: this.sessionTtl(token),
|
|
49
|
+
}));
|
|
50
|
+
// Callers get their own copy, so changing one request's session leaves the others alone.
|
|
51
|
+
return structuredClone(value);
|
|
30
52
|
}
|
|
31
53
|
async sendCompanyRefreshTokenMail(id, expiresIn) {
|
|
32
|
-
|
|
54
|
+
return this.request({
|
|
33
55
|
method: 'GET',
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
headers: { accept: 'application/json' },
|
|
37
|
-
};
|
|
38
|
-
try {
|
|
39
|
-
const res = await axios_1.default.request(options);
|
|
40
|
-
return res.data;
|
|
41
|
-
}
|
|
42
|
-
catch (error) {
|
|
43
|
-
(0, axios_error_handler_1.handleAxiosError)(error);
|
|
44
|
-
}
|
|
56
|
+
url: (0, url_path_1.urlPath) `/public/companies/${id}/${expiresIn}/mail`,
|
|
57
|
+
});
|
|
45
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Exchanges a user token for a JWT. Unless `tokenCache` is `false`, the JWT
|
|
61
|
+
* is reused for the same credentials until shortly before it expires.
|
|
62
|
+
*/
|
|
46
63
|
async tokenSignIn(dto) {
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
64
|
+
const { token } = await this.signIn(dto);
|
|
65
|
+
return { token };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Runs `call` with `Bearer <jwt>` for the credentials. If the server rejects
|
|
69
|
+
* a cached token with 401, the token is dropped and `call` runs once more
|
|
70
|
+
* with a new one.
|
|
71
|
+
*/
|
|
72
|
+
async withToken(dto, call) {
|
|
73
|
+
const { token, fromCache } = await this.signIn(dto);
|
|
54
74
|
try {
|
|
55
|
-
|
|
56
|
-
return res.data;
|
|
75
|
+
return await call(`Bearer ${token}`);
|
|
57
76
|
}
|
|
58
77
|
catch (error) {
|
|
59
|
-
(0, axios_error_handler_1.
|
|
78
|
+
if (!fromCache || !(0, axios_error_handler_1.isUnauthorizedError)(error))
|
|
79
|
+
throw error;
|
|
80
|
+
this.tokenCache.delete(this.tokenCacheKey(dto), token);
|
|
81
|
+
const renewed = await this.signIn(dto);
|
|
82
|
+
return call(`Bearer ${renewed.token}`);
|
|
60
83
|
}
|
|
61
84
|
}
|
|
85
|
+
/** Drops all cached tokens and sessions. */
|
|
86
|
+
clearCache() {
|
|
87
|
+
this.tokenCache.clear();
|
|
88
|
+
this.sessionCache.clear();
|
|
89
|
+
}
|
|
62
90
|
async getApiKey(args) {
|
|
63
|
-
|
|
91
|
+
return this.request({
|
|
64
92
|
method: 'GET',
|
|
65
|
-
|
|
66
|
-
url: `/api-keys/${args.company}/${args.type}/with-key`,
|
|
93
|
+
url: (0, url_path_1.urlPath) `/api-keys/${args.company}/${args.type}/with-key`,
|
|
67
94
|
headers: {
|
|
68
|
-
accept: 'application/json',
|
|
69
95
|
'x-real-ip': args.ip,
|
|
70
96
|
authorization: args.authorization,
|
|
71
97
|
},
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
async signIn(dto) {
|
|
101
|
+
const load = async () => {
|
|
102
|
+
const { token } = await this.request({
|
|
103
|
+
method: 'POST',
|
|
104
|
+
url: '/auth-api/token/auth/sign-in',
|
|
105
|
+
data: { tokenId: dto.tokenId, tokenKey: dto.tokenKey, product: dto.product },
|
|
106
|
+
});
|
|
107
|
+
return { value: token, ttlMs: this.tokenTtl(token) };
|
|
72
108
|
};
|
|
109
|
+
if (this.options.tokenCache === false) {
|
|
110
|
+
return { token: (await load()).value, fromCache: false };
|
|
111
|
+
}
|
|
112
|
+
const { value, fromCache } = await this.tokenCache.getOrLoad(this.tokenCacheKey(dto), load);
|
|
113
|
+
return { token: value, fromCache };
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Servers before `POST /auth/verify` answer it with 404; for them the token
|
|
117
|
+
* goes into the path as before.
|
|
118
|
+
*/
|
|
119
|
+
async fetchSession(token) {
|
|
120
|
+
if (Date.now() >= this.legacyVerifyUntil) {
|
|
121
|
+
try {
|
|
122
|
+
return await this.request({
|
|
123
|
+
method: 'POST',
|
|
124
|
+
url: '/auth-api/auth/verify',
|
|
125
|
+
headers: { authorization: `Bearer ${token}` },
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
if (!isMissingEndpoint(error))
|
|
130
|
+
throw error;
|
|
131
|
+
this.legacyVerifyUntil = Date.now() + LEGACY_VERIFY_RECHECK_MS;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return this.request({
|
|
135
|
+
method: 'GET',
|
|
136
|
+
url: (0, url_path_1.urlPath) `/auth-api/auth/verify/${token}`,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
tokenTtl(token) {
|
|
140
|
+
const expiresAt = (0, jwt_util_1.getJwtExpiresAt)(token);
|
|
141
|
+
if (expiresAt === undefined)
|
|
142
|
+
return 0;
|
|
143
|
+
return Math.min(expiresAt - Date.now() - TOKEN_REFRESH_MARGIN_MS, TOKEN_MAX_CACHE_MS);
|
|
144
|
+
}
|
|
145
|
+
sessionTtl(token) {
|
|
146
|
+
const ttl = this.options.sessionCacheTtlMs ?? 0;
|
|
147
|
+
if (ttl <= 0)
|
|
148
|
+
return 0;
|
|
149
|
+
const expiresAt = (0, jwt_util_1.getJwtExpiresAt)(token);
|
|
150
|
+
return expiresAt === undefined ? ttl : Math.min(ttl, expiresAt - Date.now());
|
|
151
|
+
}
|
|
152
|
+
tokenCacheKey(dto) {
|
|
153
|
+
return this.cacheKey('token', dto.tokenId, dto.tokenKey, dto.product);
|
|
154
|
+
}
|
|
155
|
+
cacheKey(...parts) {
|
|
156
|
+
return (0, node_crypto_1.createHmac)('sha256', this.cacheKeySecret)
|
|
157
|
+
.update(JSON.stringify(parts))
|
|
158
|
+
.digest('base64url');
|
|
159
|
+
}
|
|
160
|
+
async request(config) {
|
|
73
161
|
try {
|
|
74
|
-
const res = await
|
|
162
|
+
const res = await this.http.request(config);
|
|
75
163
|
return res.data;
|
|
76
164
|
}
|
|
77
165
|
catch (error) {
|
|
@@ -85,4 +173,10 @@ exports.CustomerCenterService = CustomerCenterService = tslib_1.__decorate([
|
|
|
85
173
|
tslib_1.__param(0, (0, common_1.Inject)(auth_constants_1.AUTH_MODULE_OPTIONS)),
|
|
86
174
|
tslib_1.__metadata("design:paramtypes", [Object])
|
|
87
175
|
], CustomerCenterService);
|
|
176
|
+
function isMissingEndpoint(error) {
|
|
177
|
+
if (!(error instanceof common_1.HttpException))
|
|
178
|
+
return false;
|
|
179
|
+
const status = error.getStatus();
|
|
180
|
+
return status === common_1.HttpStatus.NOT_FOUND || status === common_1.HttpStatus.METHOD_NOT_ALLOWED;
|
|
181
|
+
}
|
|
88
182
|
//# sourceMappingURL=customer-center.service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"customer-center.service.js","sourceRoot":"","sources":["../../../../../libs/api-sdk/src/lib/customer-center.service.ts"],"names":[],"mappings":";;;;AAAA,
|
|
1
|
+
{"version":3,"file":"customer-center.service.js","sourceRoot":"","sources":["../../../../../libs/api-sdk/src/lib/customer-center.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,10 +12,9 @@ let AuthGuard = class AuthGuard {
|
|
|
12
12
|
}
|
|
13
13
|
async canActivate(context) {
|
|
14
14
|
const request = context.switchToHttp().getRequest();
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
token = token?.replace('Bearer ', '');
|
|
15
|
+
// `cookies` only exists with the cookie-parser middleware.
|
|
16
|
+
const raw = request.headers.dev ?? request.cookies?.['jwt'] ?? request.headers.authorization;
|
|
17
|
+
const token = typeof raw === 'string' ? raw.replace(/^Bearer\s+/i, '').trim() : undefined;
|
|
19
18
|
if (!token?.length) {
|
|
20
19
|
throw new common_1.UnauthorizedException('No authentication token provided');
|
|
21
20
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.guard.js","sourceRoot":"","sources":["../../../../../../libs/api-sdk/src/lib/guards/auth.guard.ts"],"names":[],"mappings":";;;;AAAA,2CAMwB;AAExB,gDAA4C;AAC5C,wEAAmE;AAG5D,IAAM,SAAS,GAAf,MAAM,SAAS;
|
|
1
|
+
{"version":3,"file":"auth.guard.js","sourceRoot":"","sources":["../../../../../../libs/api-sdk/src/lib/guards/auth.guard.ts"],"names":[],"mappings":";;;;AAAA,2CAMwB;AAExB,gDAA4C;AAC5C,wEAAmE;AAG5D,IAAM,SAAS,GAAf,MAAM,SAAS;IAGD;IAFnB,YAEmB,qBAA4C;QAA5C,0BAAqB,GAArB,qBAAqB,CAAuB;IAC5D,CAAC;IAEJ,KAAK,CAAC,WAAW,CAAC,OAAyB;QACzC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;QAEpD,2DAA2D;QAC3D,MAAM,GAAG,GACP,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC;QACnF,MAAM,KAAK,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAE1F,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;YACnB,MAAM,IAAI,8BAAqB,CAAC,kCAAkC,CAAC,CAAC;QACtE,CAAC;QAED,OAAO,CAAC,OAAO,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAE9E,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AAtBY,8BAAS;oBAAT,SAAS;IADrB,IAAA,mBAAU,GAAE;IAGR,mBAAA,IAAA,eAAM,EAAC,wBAAU,CAAC,CAAA;6CACqB,+CAAqB;GAHpD,SAAS,CAsBrB"}
|
|
@@ -9,6 +9,9 @@ let CompanyGuard = class CompanyGuard {
|
|
|
9
9
|
const request = context.switchToHttp().getRequest();
|
|
10
10
|
const companyId = request.params.companyId;
|
|
11
11
|
const session = request.session;
|
|
12
|
+
if (!session) {
|
|
13
|
+
throw new common_1.UnauthorizedException('No session; use AuthGuard first');
|
|
14
|
+
}
|
|
12
15
|
if (user_session_model_1.AllAccessRoles.includes(session.role) ||
|
|
13
16
|
(companyId && session.enabledCompanies?.includes(companyId))) {
|
|
14
17
|
return true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"company.guard.js","sourceRoot":"","sources":["../../../../../../libs/api-sdk/src/lib/guards/company.guard.ts"],"names":[],"mappings":";;;;AAAA,
|
|
1
|
+
{"version":3,"file":"company.guard.js","sourceRoot":"","sources":["../../../../../../libs/api-sdk/src/lib/guards/company.guard.ts"],"names":[],"mappings":";;;;AAAA,2CAOwB;AAExB,qEAA2E;AAGpE,IAAM,YAAY,GAAlB,MAAM,YAAY;IACvB,KAAK,CAAC,WAAW,CAAC,OAAyB;QACzC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;QAEpD,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC;QAC3C,MAAM,OAAO,GAA4B,OAAO,CAAC,OAAO,CAAC;QACzD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,8BAAqB,CAAC,iCAAiC,CAAC,CAAC;QACrE,CAAC;QACD,IACE,mCAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC;YACrC,CAAC,SAAS,IAAI,OAAO,CAAC,gBAAgB,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,EAC5D,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,IAAI,sBAAa,CAAC,oBAAoB,EAAE,mBAAU,CAAC,WAAW,CAAC,CAAC;IACxE,CAAC;CACF,CAAA;AAlBY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;GACA,YAAY,CAkBxB"}
|
|
@@ -16,11 +16,14 @@ let SetHubPermissionsGuard = class SetHubPermissionsGuard {
|
|
|
16
16
|
return true;
|
|
17
17
|
}
|
|
18
18
|
const request = context.switchToHttp().getRequest();
|
|
19
|
+
if (!request.session) {
|
|
20
|
+
throw new common_1.UnauthorizedException('No session; use AuthGuard first');
|
|
21
|
+
}
|
|
19
22
|
const { setHubPermission, product, role } = request.session;
|
|
20
23
|
if (user_session_model_1.AllAccessRoles.includes(role) ||
|
|
21
24
|
(setHubPermission &&
|
|
22
25
|
product === user_session_model_1.Product.SETHUB &&
|
|
23
|
-
permissions.every(
|
|
26
|
+
permissions.every(p => setHubPermission[p] === true))) {
|
|
24
27
|
return true;
|
|
25
28
|
}
|
|
26
29
|
throw new common_1.HttpException('Missing permission', common_1.HttpStatus.UNAUTHORIZED);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sethub-permissions.guard.js","sourceRoot":"","sources":["../../../../../../libs/api-sdk/src/lib/guards/sethub-permissions.guard.ts"],"names":[],"mappings":";;;;AAAA,
|
|
1
|
+
{"version":3,"file":"sethub-permissions.guard.js","sourceRoot":"","sources":["../../../../../../libs/api-sdk/src/lib/guards/sethub-permissions.guard.ts"],"names":[],"mappings":";;;;AAAA,2CAOwB;AACxB,uCAAyC;AAGzC,qEAAuE;AAGhE,IAAM,sBAAsB,GAA5B,MAAM,sBAAsB;IACb;IAApB,YAAoB,SAAoB;QAApB,cAAS,GAAT,SAAS,CAAW;IAAG,CAAC;IAE5C,WAAW,CAAC,OAAyB;QACnC,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAqB,aAAa,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QAChG,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;QACpD,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACrB,MAAM,IAAI,8BAAqB,CAAC,iCAAiC,CAAC,CAAC;QACrE,CAAC;QACD,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;QAE5D,IACE,mCAAc,CAAC,QAAQ,CAAC,IAAI,CAAC;YAC7B,CAAC,gBAAgB;gBACf,OAAO,KAAK,4BAAO,CAAC,MAAM;gBAC1B,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,EACvD,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,IAAI,sBAAa,CAAC,oBAAoB,EAAE,mBAAU,CAAC,YAAY,CAAC,CAAC;IACzE,CAAC;CACF,CAAA;AAzBY,wDAAsB;iCAAtB,sBAAsB;IADlC,IAAA,mBAAU,GAAE;6CAEoB,gBAAS;GAD7B,sBAAsB,CAyBlC"}
|
|
@@ -8,6 +8,9 @@ let SuperAdminGuard = class SuperAdminGuard {
|
|
|
8
8
|
async canActivate(context) {
|
|
9
9
|
const request = context.switchToHttp().getRequest();
|
|
10
10
|
const session = request.session;
|
|
11
|
+
if (!session) {
|
|
12
|
+
throw new common_1.UnauthorizedException('No session; use AuthGuard first');
|
|
13
|
+
}
|
|
11
14
|
if (user_session_model_1.AllAccessRoles.includes(session.role)) {
|
|
12
15
|
return true;
|
|
13
16
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"super-admin.guard.js","sourceRoot":"","sources":["../../../../../../libs/api-sdk/src/lib/guards/super-admin.guard.ts"],"names":[],"mappings":";;;;AAAA,
|
|
1
|
+
{"version":3,"file":"super-admin.guard.js","sourceRoot":"","sources":["../../../../../../libs/api-sdk/src/lib/guards/super-admin.guard.ts"],"names":[],"mappings":";;;;AAAA,2CAOwB;AAExB,qEAA2E;AAGpE,IAAM,eAAe,GAArB,MAAM,eAAe;IAC1B,KAAK,CAAC,WAAW,CAAC,OAAyB;QACzC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;QAEpD,MAAM,OAAO,GAA4B,OAAO,CAAC,OAAO,CAAC;QACzD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,8BAAqB,CAAC,iCAAiC,CAAC,CAAC;QACrE,CAAC;QACD,IAAI,mCAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,IAAI,sBAAa,CAAC,oBAAoB,EAAE,mBAAU,CAAC,WAAW,CAAC,CAAC;IACxE,CAAC;CACF,CAAA;AAdY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,mBAAU,GAAE;GACA,eAAe,CAc3B"}
|