@origins-digital/nestjs-shared-key-http 0.0.0-stage → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +106 -2
- package/dist/caller-auth-keys.d.ts +40 -0
- package/dist/caller-auth-keys.d.ts.map +1 -0
- package/dist/caller-auth-keys.js +63 -0
- package/dist/caller-auth-keys.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/internal-auth.rule.d.ts +27 -0
- package/dist/internal-auth.rule.d.ts.map +1 -0
- package/dist/internal-auth.rule.js +43 -0
- package/dist/internal-auth.rule.js.map +1 -0
- package/dist/shared-key-http.module.d.ts +16 -0
- package/dist/shared-key-http.module.d.ts.map +1 -0
- package/dist/shared-key-http.module.js +56 -0
- package/dist/shared-key-http.module.js.map +1 -0
- package/dist/shared-key-http.options.d.ts +22 -0
- package/dist/shared-key-http.options.d.ts.map +1 -0
- package/dist/shared-key-http.options.js +15 -0
- package/dist/shared-key-http.options.js.map +1 -0
- package/dist/shared-key-http.service.d.ts +41 -0
- package/dist/shared-key-http.service.d.ts.map +1 -0
- package/dist/shared-key-http.service.js +120 -0
- package/dist/shared-key-http.service.js.map +1 -0
- package/package.json +100 -4
package/README.md
CHANGED
|
@@ -1,3 +1,107 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @origins-digital/nestjs-shared-key-http
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`HttpService` for calls between Origins services: it adds the internal service
|
|
4
|
+
token (`x-internal-auth-token`) and `x-service-name`, so services no longer
|
|
5
|
+
build those headers by hand.
|
|
6
|
+
|
|
7
|
+
## Rule (`applyInternalAuth`)
|
|
8
|
+
|
|
9
|
+
The internal headers are added only when the request has **neither** an
|
|
10
|
+
`authorization` **nor** an `x-internal-auth-token` header key (case-insensitive,
|
|
11
|
+
whatever the value, `undefined` and `''` included). Key presence means "the
|
|
12
|
+
caller decided": a forwarded session token that is missing is not replaced by
|
|
13
|
+
the internal token, so the service still answers 401.
|
|
14
|
+
|
|
15
|
+
- A caller-provided `x-internal-auth-token` or `x-service-name` is never overwritten.
|
|
16
|
+
- The JWT is fetched only when it will be sent.
|
|
17
|
+
- If the token cannot be resolved, the request rejects before it is sent.
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
yarn add @origins-digital/nestjs-shared-key-http
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Peer dependencies: `@nestjs/common`, `@nestjs/axios`, `axios`, `rxjs`,
|
|
26
|
+
`@origins-digital/nestjs-shared-key`.
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
`SharedKeyHttpService` needs `SharedKeyService`. The module never registers
|
|
31
|
+
`SharedKeyModule` itself, so the app keeps its key backend (SSM or Secrets
|
|
32
|
+
Manager) and its options. Either register it globally once:
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
@Module({
|
|
36
|
+
imports: [
|
|
37
|
+
SharedKeyModule.forRoot({ isGlobal: true }),
|
|
38
|
+
SharedKeyHttpModule, // default options
|
|
39
|
+
],
|
|
40
|
+
})
|
|
41
|
+
export class AppModule {}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
or pass the module that provides it:
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
SharedKeyHttpModule.register({
|
|
48
|
+
serviceName: 'origins-backoffice-orchestrator', // x-service-name
|
|
49
|
+
imports: [SharedKeyModule],
|
|
50
|
+
axiosConfig: { timeout: 10_000 }, // defaults of the module's own axios instance
|
|
51
|
+
isGlobal: false,
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Then inject it (it extends `HttpService`):
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
@Injectable()
|
|
59
|
+
export class VideoClient {
|
|
60
|
+
constructor(private readonly http: SharedKeyHttpService) {}
|
|
61
|
+
|
|
62
|
+
async getVideo(id: string) {
|
|
63
|
+
const { data } = await this.http.getAsPromise<Video>(`${host}/videos/${id}`, {
|
|
64
|
+
requestedService: 'origins-video-service',
|
|
65
|
+
});
|
|
66
|
+
return data;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
- `getAsPromise`, `postAsPromise`, `putAsPromise`, `patchAsPromise`,
|
|
72
|
+
`deleteAsPromise`, `headAsPromise` turn HTTP errors into the Nest exception
|
|
73
|
+
built by `raiseError` (`@origins-digital/error-utils`), labelled with
|
|
74
|
+
`requestedService`. Other errors pass through unchanged.
|
|
75
|
+
- The Observable methods of `HttpService` (`get`, `post`, ...) apply the same rule.
|
|
76
|
+
- The service uses its own axios instance: a plain `HttpModule` (calls to
|
|
77
|
+
external hosts) never gets the internal token.
|
|
78
|
+
|
|
79
|
+
`x-service-name` defaults to `${APP_ENV}-${npm_package_name}` (the package name
|
|
80
|
+
alone without `APP_ENV`, `unknown-service` without a package name). Note that
|
|
81
|
+
`npm_package_name` is only set when the app is started through npm/yarn; pass
|
|
82
|
+
`serviceName` to make it explicit.
|
|
83
|
+
|
|
84
|
+
## Other clients (hey-api)
|
|
85
|
+
|
|
86
|
+
The rule is a plain axios request interceptor, reusable on any axios instance:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
client.instance.interceptors.request.use((config) =>
|
|
90
|
+
applyInternalAuth(config, () => sharedKeyHttp.internalHeaders()),
|
|
91
|
+
);
|
|
92
|
+
keepCallerAuthKeys(client);
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
hey-api drops header keys whose value is `undefined` before axios runs, so the
|
|
96
|
+
rule would not see `authorization: undefined`. `keepCallerAuthKeys(client)`
|
|
97
|
+
wraps the client's request methods and sends `''` instead
|
|
98
|
+
(`withCallerAuthKeys(options)` is the pure version). Nest's `HttpService` keeps
|
|
99
|
+
undefined keys, so `SharedKeyHttpService` does not need it.
|
|
100
|
+
|
|
101
|
+
## Build
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
yarn build
|
|
105
|
+
yarn test
|
|
106
|
+
yarn lint
|
|
107
|
+
```
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export type CallerAuthCallOptions = {
|
|
2
|
+
headers?: unknown;
|
|
3
|
+
};
|
|
4
|
+
export declare const HTTP_CLIENT_METHODS: readonly ["request", "get", "post", "put", "patch", "delete", "head", "options", "connect", "trace"];
|
|
5
|
+
/**
|
|
6
|
+
* The part of a generated client (e.g. a hey-api axios client) that
|
|
7
|
+
* `keepCallerAuthKeys` wraps. Methods are declared as methods (bivariant
|
|
8
|
+
* parameters), so each generated client's narrower option types fit.
|
|
9
|
+
*/
|
|
10
|
+
export interface CallerAuthClient {
|
|
11
|
+
request(options?: CallerAuthCallOptions): unknown;
|
|
12
|
+
get(options?: CallerAuthCallOptions): unknown;
|
|
13
|
+
post(options?: CallerAuthCallOptions): unknown;
|
|
14
|
+
put(options?: CallerAuthCallOptions): unknown;
|
|
15
|
+
patch(options?: CallerAuthCallOptions): unknown;
|
|
16
|
+
delete(options?: CallerAuthCallOptions): unknown;
|
|
17
|
+
head(options?: CallerAuthCallOptions): unknown;
|
|
18
|
+
options(options?: CallerAuthCallOptions): unknown;
|
|
19
|
+
connect(options?: CallerAuthCallOptions): unknown;
|
|
20
|
+
trace(options?: CallerAuthCallOptions): unknown;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Returns `options` with undefined `authorization` / `x-internal-auth-token`
|
|
24
|
+
* header values replaced by ''. Only plain-object headers are normalised;
|
|
25
|
+
* anything else (none, `Headers`, `AxiosHeaders`) is returned as is.
|
|
26
|
+
*/
|
|
27
|
+
export declare const withCallerAuthKeys: (options?: CallerAuthCallOptions) => CallerAuthCallOptions | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Some clients (hey-api) drop header keys whose value is undefined before axios
|
|
30
|
+
* runs, so `applyInternalAuth` would not see `authorization: undefined` and
|
|
31
|
+
* would add the internal token. Wrapping the client's request methods with
|
|
32
|
+
* `withCallerAuthKeys` sends '' instead, which keeps the caller's choice
|
|
33
|
+
* visible: the rule leaves the request alone and the service answers 401, as
|
|
34
|
+
* it does for a missing header. Mutates and returns `client`.
|
|
35
|
+
*
|
|
36
|
+
* Not needed on Nest's `HttpService`: it hands the config to axios as is, and
|
|
37
|
+
* axios keeps undefined header keys.
|
|
38
|
+
*/
|
|
39
|
+
export declare const keepCallerAuthKeys: <C extends CallerAuthClient>(client: C) => C;
|
|
40
|
+
//# sourceMappingURL=caller-auth-keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"caller-auth-keys.d.ts","sourceRoot":"","sources":["../src/caller-auth-keys.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,qBAAqB,GAAG;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAE1D,eAAO,MAAM,mBAAmB,sGAWtB,CAAC;AAEX;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC;IAClD,GAAG,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC;IAC9C,IAAI,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC;IAC/C,GAAG,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC;IAC9C,KAAK,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC;IAChD,MAAM,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC;IACjD,IAAI,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC;IAC/C,OAAO,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC;IAClD,OAAO,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC;IAClD,KAAK,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC;CACjD;AAWD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAC7B,UAAU,qBAAqB,KAC9B,qBAAqB,GAAG,SAY1B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,GAAI,CAAC,SAAS,gBAAgB,EAC3D,QAAQ,CAAC,KACR,CAQF,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.keepCallerAuthKeys = exports.withCallerAuthKeys = exports.HTTP_CLIENT_METHODS = void 0;
|
|
4
|
+
const internal_auth_rule_1 = require("./internal-auth.rule");
|
|
5
|
+
exports.HTTP_CLIENT_METHODS = [
|
|
6
|
+
'request',
|
|
7
|
+
'get',
|
|
8
|
+
'post',
|
|
9
|
+
'put',
|
|
10
|
+
'patch',
|
|
11
|
+
'delete',
|
|
12
|
+
'head',
|
|
13
|
+
'options',
|
|
14
|
+
'connect',
|
|
15
|
+
'trace',
|
|
16
|
+
];
|
|
17
|
+
const isPlainObject = (value) => {
|
|
18
|
+
if (typeof value !== 'object' || value === null)
|
|
19
|
+
return false;
|
|
20
|
+
const proto = Object.getPrototypeOf(value);
|
|
21
|
+
return proto === Object.prototype || proto === null;
|
|
22
|
+
};
|
|
23
|
+
const isUndefinedCallerAuth = ([key, value]) => value === undefined && internal_auth_rule_1.CALLER_AUTH_HEADERS.has(key.toLowerCase());
|
|
24
|
+
/**
|
|
25
|
+
* Returns `options` with undefined `authorization` / `x-internal-auth-token`
|
|
26
|
+
* header values replaced by ''. Only plain-object headers are normalised;
|
|
27
|
+
* anything else (none, `Headers`, `AxiosHeaders`) is returned as is.
|
|
28
|
+
*/
|
|
29
|
+
const withCallerAuthKeys = (options) => {
|
|
30
|
+
const headers = options === null || options === void 0 ? void 0 : options.headers;
|
|
31
|
+
if (!isPlainObject(headers))
|
|
32
|
+
return options;
|
|
33
|
+
const entries = Object.entries(headers);
|
|
34
|
+
if (!entries.some(isUndefinedCallerAuth))
|
|
35
|
+
return options;
|
|
36
|
+
const kept = entries.map(([key, value]) => [
|
|
37
|
+
key,
|
|
38
|
+
isUndefinedCallerAuth([key, value]) ? '' : value,
|
|
39
|
+
]);
|
|
40
|
+
return Object.assign(Object.assign({}, options), { headers: Object.fromEntries(kept) });
|
|
41
|
+
};
|
|
42
|
+
exports.withCallerAuthKeys = withCallerAuthKeys;
|
|
43
|
+
/**
|
|
44
|
+
* Some clients (hey-api) drop header keys whose value is undefined before axios
|
|
45
|
+
* runs, so `applyInternalAuth` would not see `authorization: undefined` and
|
|
46
|
+
* would add the internal token. Wrapping the client's request methods with
|
|
47
|
+
* `withCallerAuthKeys` sends '' instead, which keeps the caller's choice
|
|
48
|
+
* visible: the rule leaves the request alone and the service answers 401, as
|
|
49
|
+
* it does for a missing header. Mutates and returns `client`.
|
|
50
|
+
*
|
|
51
|
+
* Not needed on Nest's `HttpService`: it hands the config to axios as is, and
|
|
52
|
+
* axios keeps undefined header keys.
|
|
53
|
+
*/
|
|
54
|
+
const keepCallerAuthKeys = (client) => {
|
|
55
|
+
const target = client;
|
|
56
|
+
for (const method of exports.HTTP_CLIENT_METHODS) {
|
|
57
|
+
const send = target[method].bind(target);
|
|
58
|
+
target[method] = (options) => send((0, exports.withCallerAuthKeys)(options));
|
|
59
|
+
}
|
|
60
|
+
return client;
|
|
61
|
+
};
|
|
62
|
+
exports.keepCallerAuthKeys = keepCallerAuthKeys;
|
|
63
|
+
//# sourceMappingURL=caller-auth-keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"caller-auth-keys.js","sourceRoot":"","sources":["../src/caller-auth-keys.ts"],"names":[],"mappings":";;;AAAA,6DAA2D;AAI9C,QAAA,mBAAmB,GAAG;IACjC,SAAS;IACT,KAAK;IACL,MAAM;IACN,KAAK;IACL,OAAO;IACP,QAAQ;IACR,MAAM;IACN,SAAS;IACT,SAAS;IACT,OAAO;CACC,CAAC;AAoBX,MAAM,aAAa,GAAG,CAAC,KAAc,EAAoC,EAAE;IACzE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,KAAK,GAAY,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACpD,OAAO,KAAK,KAAK,MAAM,CAAC,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC;AACtD,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,CAAoB,EAAW,EAAE,CACzE,KAAK,KAAK,SAAS,IAAI,wCAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;AAEpE;;;;GAIG;AACI,MAAM,kBAAkB,GAAG,CAChC,OAA+B,EACI,EAAE;IACrC,MAAM,OAAO,GAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,CAAC;IACjC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IAE5C,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACxC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC;QAAE,OAAO,OAAO,CAAC;IAEzD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAqB,EAAE,CAAC;QAC5D,GAAG;QACH,qBAAqB,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK;KACjD,CAAC,CAAC;IACH,uCAAY,OAAO,KAAE,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAG;AAC3D,CAAC,CAAC;AAdW,QAAA,kBAAkB,sBAc7B;AAEF;;;;;;;;;;GAUG;AACI,MAAM,kBAAkB,GAAG,CAChC,MAAS,EACN,EAAE;IACL,MAAM,MAAM,GAAqB,MAAM,CAAC;IACxC,KAAK,MAAM,MAAM,IAAI,2BAAmB,EAAE,CAAC;QACzC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,OAA+B,EAAE,EAAE,CACnD,IAAI,CAAC,IAAA,0BAAkB,EAAC,OAAO,CAAC,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAVW,QAAA,kBAAkB,sBAU7B"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -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("./internal-auth.rule"), exports);
|
|
18
|
+
__exportStar(require("./caller-auth-keys"), exports);
|
|
19
|
+
__exportStar(require("./shared-key-http.options"), exports);
|
|
20
|
+
__exportStar(require("./shared-key-http.service"), exports);
|
|
21
|
+
__exportStar(require("./shared-key-http.module"), exports);
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,uDAAqC;AACrC,qDAAmC;AACnC,4DAA0C;AAC1C,4DAA0C;AAC1C,2DAAyC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { InternalAxiosRequestConfig } from 'axios';
|
|
2
|
+
export declare const INTERNAL_AUTH_TOKEN_HEADER = "x-internal-auth-token";
|
|
3
|
+
export declare const SERVICE_NAME_HEADER = "x-service-name";
|
|
4
|
+
/** Header keys that mean "the caller already chose the credential to send". */
|
|
5
|
+
export declare const CALLER_AUTH_HEADERS: ReadonlySet<string>;
|
|
6
|
+
/** Internal headers to add, e.g. `x-internal-auth-token` and `x-service-name`. */
|
|
7
|
+
export type InternalAuthHeaders = Readonly<Record<string, string>>;
|
|
8
|
+
/** Resolves the internal headers; only called when they will be sent. */
|
|
9
|
+
export type InternalHeadersProvider = () => Promise<InternalAuthHeaders>;
|
|
10
|
+
/**
|
|
11
|
+
* Axios request-interceptor rule for calls to internal services: adds the
|
|
12
|
+
* headers of `headersProvider` unless the request already carries an
|
|
13
|
+
* `authorization` or `x-internal-auth-token` header KEY, compared
|
|
14
|
+
* case-insensitively and whatever its value.
|
|
15
|
+
*
|
|
16
|
+
* Key presence, not value: a caller that forwards `authorization: sessionToken`
|
|
17
|
+
* with an undefined or empty token keeps sending no valid credential (the
|
|
18
|
+
* service answers 401) instead of silently getting the internal token.
|
|
19
|
+
* AxiosHeaders keeps keys whose value is undefined, so `Object.keys` sees them
|
|
20
|
+
* (`has()` would not). Headers the caller already set (e.g. `x-service-name`)
|
|
21
|
+
* are never overwritten. A rejection of `headersProvider` rejects the request
|
|
22
|
+
* before it is sent.
|
|
23
|
+
*
|
|
24
|
+
* Usage: `instance.interceptors.request.use((config) => applyInternalAuth(config, provider))`.
|
|
25
|
+
*/
|
|
26
|
+
export declare const applyInternalAuth: (config: InternalAxiosRequestConfig, headersProvider: InternalHeadersProvider) => Promise<InternalAxiosRequestConfig>;
|
|
27
|
+
//# sourceMappingURL=internal-auth.rule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal-auth.rule.d.ts","sourceRoot":"","sources":["../src/internal-auth.rule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,0BAA0B,EAAE,MAAM,OAAO,CAAC;AAEjE,eAAO,MAAM,0BAA0B,0BAA0B,CAAC;AAClE,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AAEpD,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAGlD,CAAC;AAEH,kFAAkF;AAClF,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAEnE,yEAAyE;AACzE,MAAM,MAAM,uBAAuB,GAAG,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC;AASzE;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,0BAA0B,EAClC,iBAAiB,uBAAuB,KACvC,OAAO,CAAC,0BAA0B,CAWpC,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.applyInternalAuth = exports.CALLER_AUTH_HEADERS = exports.SERVICE_NAME_HEADER = exports.INTERNAL_AUTH_TOKEN_HEADER = void 0;
|
|
4
|
+
const axios_1 = require("axios");
|
|
5
|
+
exports.INTERNAL_AUTH_TOKEN_HEADER = 'x-internal-auth-token';
|
|
6
|
+
exports.SERVICE_NAME_HEADER = 'x-service-name';
|
|
7
|
+
/** Header keys that mean "the caller already chose the credential to send". */
|
|
8
|
+
exports.CALLER_AUTH_HEADERS = new Set([
|
|
9
|
+
'authorization',
|
|
10
|
+
exports.INTERNAL_AUTH_TOKEN_HEADER,
|
|
11
|
+
]);
|
|
12
|
+
/** Whether `headers` has one of `names` as a key, compared case-insensitively. */
|
|
13
|
+
const hasHeaderKey = (headers, names) => Object.keys(headers !== null && headers !== void 0 ? headers : {}).some((key) => names.has(key.toLowerCase()));
|
|
14
|
+
/**
|
|
15
|
+
* Axios request-interceptor rule for calls to internal services: adds the
|
|
16
|
+
* headers of `headersProvider` unless the request already carries an
|
|
17
|
+
* `authorization` or `x-internal-auth-token` header KEY, compared
|
|
18
|
+
* case-insensitively and whatever its value.
|
|
19
|
+
*
|
|
20
|
+
* Key presence, not value: a caller that forwards `authorization: sessionToken`
|
|
21
|
+
* with an undefined or empty token keeps sending no valid credential (the
|
|
22
|
+
* service answers 401) instead of silently getting the internal token.
|
|
23
|
+
* AxiosHeaders keeps keys whose value is undefined, so `Object.keys` sees them
|
|
24
|
+
* (`has()` would not). Headers the caller already set (e.g. `x-service-name`)
|
|
25
|
+
* are never overwritten. A rejection of `headersProvider` rejects the request
|
|
26
|
+
* before it is sent.
|
|
27
|
+
*
|
|
28
|
+
* Usage: `instance.interceptors.request.use((config) => applyInternalAuth(config, provider))`.
|
|
29
|
+
*/
|
|
30
|
+
const applyInternalAuth = async (config, headersProvider) => {
|
|
31
|
+
if (hasHeaderKey(config.headers, exports.CALLER_AUTH_HEADERS))
|
|
32
|
+
return config;
|
|
33
|
+
const headers = axios_1.AxiosHeaders.from(config.headers);
|
|
34
|
+
for (const [name, value] of Object.entries(await headersProvider())) {
|
|
35
|
+
if (!hasHeaderKey(headers, new Set([name.toLowerCase()]))) {
|
|
36
|
+
headers.set(name, value);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
config.headers = headers;
|
|
40
|
+
return config;
|
|
41
|
+
};
|
|
42
|
+
exports.applyInternalAuth = applyInternalAuth;
|
|
43
|
+
//# sourceMappingURL=internal-auth.rule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal-auth.rule.js","sourceRoot":"","sources":["../src/internal-auth.rule.ts"],"names":[],"mappings":";;;AAAA,iCAAiE;AAEpD,QAAA,0BAA0B,GAAG,uBAAuB,CAAC;AACrD,QAAA,mBAAmB,GAAG,gBAAgB,CAAC;AAEpD,+EAA+E;AAClE,QAAA,mBAAmB,GAAwB,IAAI,GAAG,CAAC;IAC9D,eAAe;IACf,kCAA0B;CAC3B,CAAC,CAAC;AAQH,kFAAkF;AAClF,MAAM,YAAY,GAAG,CACnB,OAA2B,EAC3B,KAA0B,EACjB,EAAE,CACX,MAAM,CAAC,IAAI,CAAC,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;AAEzE;;;;;;;;;;;;;;;GAeG;AACI,MAAM,iBAAiB,GAAG,KAAK,EACpC,MAAkC,EAClC,eAAwC,EACH,EAAE;IACvC,IAAI,YAAY,CAAC,MAAM,CAAC,OAAO,EAAE,2BAAmB,CAAC;QAAE,OAAO,MAAM,CAAC;IAErE,MAAM,OAAO,GAAG,oBAAY,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAClD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,eAAe,EAAE,CAAC,EAAE,CAAC;QACpE,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1D,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IACD,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAdW,QAAA,iBAAiB,qBAc5B"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { DynamicModule } from '@nestjs/common';
|
|
2
|
+
import { SharedKeyHttpModuleOptions } from './shared-key-http.options';
|
|
3
|
+
/**
|
|
4
|
+
* Provides `SharedKeyHttpService`. It needs `SharedKeyService`: either the app
|
|
5
|
+
* registers `SharedKeyModule.forRoot({ isGlobal: true })` once, or the module
|
|
6
|
+
* gets it through `register({ imports: [...] })`. It never registers
|
|
7
|
+
* `SharedKeyModule` itself, so the app keeps its choice of key backend
|
|
8
|
+
* (SSM / Secrets Manager) and options.
|
|
9
|
+
*
|
|
10
|
+
* - `imports: [SharedKeyHttpModule]`: default options, global `SharedKeyService`.
|
|
11
|
+
* - `imports: [SharedKeyHttpModule.register({ serviceName, imports, isGlobal })]`.
|
|
12
|
+
*/
|
|
13
|
+
export declare class SharedKeyHttpModule {
|
|
14
|
+
static register(options?: SharedKeyHttpModuleOptions): DynamicModule;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=shared-key-http.module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-key-http.module.d.ts","sourceRoot":"","sources":["../src/shared-key-http.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAoB,MAAM,gBAAgB,CAAC;AAEjE,OAAO,EAGL,0BAA0B,EAC3B,MAAM,2BAA2B,CAAC;AAanC;;;;;;;;;GASG;AACH,qBAIa,mBAAmB;IAC9B,MAAM,CAAC,QAAQ,CAAC,OAAO,GAAE,0BAA+B,GAAG,aAAa;CASzE"}
|
|
@@ -0,0 +1,56 @@
|
|
|
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 __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
+
};
|
|
11
|
+
var SharedKeyHttpModule_1;
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.SharedKeyHttpModule = void 0;
|
|
14
|
+
const common_1 = require("@nestjs/common");
|
|
15
|
+
const axios_1 = __importDefault(require("axios"));
|
|
16
|
+
const shared_key_http_options_1 = require("./shared-key-http.options");
|
|
17
|
+
const shared_key_http_service_1 = require("./shared-key-http.service");
|
|
18
|
+
const createProviders = (options) => [
|
|
19
|
+
{ provide: shared_key_http_options_1.SHARED_KEY_HTTP_OPTIONS, useValue: options },
|
|
20
|
+
{
|
|
21
|
+
// Own instance: the auth interceptor never reaches the global axios.
|
|
22
|
+
provide: shared_key_http_options_1.SHARED_KEY_HTTP_AXIOS_INSTANCE,
|
|
23
|
+
useFactory: () => axios_1.default.create(options.axiosConfig),
|
|
24
|
+
},
|
|
25
|
+
shared_key_http_service_1.SharedKeyHttpService,
|
|
26
|
+
];
|
|
27
|
+
/**
|
|
28
|
+
* Provides `SharedKeyHttpService`. It needs `SharedKeyService`: either the app
|
|
29
|
+
* registers `SharedKeyModule.forRoot({ isGlobal: true })` once, or the module
|
|
30
|
+
* gets it through `register({ imports: [...] })`. It never registers
|
|
31
|
+
* `SharedKeyModule` itself, so the app keeps its choice of key backend
|
|
32
|
+
* (SSM / Secrets Manager) and options.
|
|
33
|
+
*
|
|
34
|
+
* - `imports: [SharedKeyHttpModule]`: default options, global `SharedKeyService`.
|
|
35
|
+
* - `imports: [SharedKeyHttpModule.register({ serviceName, imports, isGlobal })]`.
|
|
36
|
+
*/
|
|
37
|
+
let SharedKeyHttpModule = SharedKeyHttpModule_1 = class SharedKeyHttpModule {
|
|
38
|
+
static register(options = {}) {
|
|
39
|
+
var _a, _b;
|
|
40
|
+
return {
|
|
41
|
+
module: SharedKeyHttpModule_1,
|
|
42
|
+
global: (_a = options.isGlobal) !== null && _a !== void 0 ? _a : false,
|
|
43
|
+
imports: (_b = options.imports) !== null && _b !== void 0 ? _b : [],
|
|
44
|
+
providers: createProviders(options),
|
|
45
|
+
exports: [shared_key_http_service_1.SharedKeyHttpService],
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
exports.SharedKeyHttpModule = SharedKeyHttpModule;
|
|
50
|
+
exports.SharedKeyHttpModule = SharedKeyHttpModule = SharedKeyHttpModule_1 = __decorate([
|
|
51
|
+
(0, common_1.Module)({
|
|
52
|
+
providers: createProviders({}),
|
|
53
|
+
exports: [shared_key_http_service_1.SharedKeyHttpService],
|
|
54
|
+
})
|
|
55
|
+
], SharedKeyHttpModule);
|
|
56
|
+
//# sourceMappingURL=shared-key-http.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-key-http.module.js","sourceRoot":"","sources":["../src/shared-key-http.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAAiE;AACjE,kDAA0B;AAC1B,uEAImC;AACnC,uEAAiE;AAEjE,MAAM,eAAe,GAAG,CAAC,OAAmC,EAAc,EAAE,CAAC;IAC3E,EAAE,OAAO,EAAE,iDAAuB,EAAE,QAAQ,EAAE,OAAO,EAAE;IACvD;QACE,qEAAqE;QACrE,OAAO,EAAE,wDAA8B;QACvC,UAAU,EAAE,GAAG,EAAE,CAAC,eAAK,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;KACpD;IACD,8CAAoB;CACrB,CAAC;AAEF;;;;;;;;;GASG;AAKI,IAAM,mBAAmB,2BAAzB,MAAM,mBAAmB;IAC9B,MAAM,CAAC,QAAQ,CAAC,UAAsC,EAAE;;QACtD,OAAO;YACL,MAAM,EAAE,qBAAmB;YAC3B,MAAM,EAAE,MAAA,OAAO,CAAC,QAAQ,mCAAI,KAAK;YACjC,OAAO,EAAE,MAAA,OAAO,CAAC,OAAO,mCAAI,EAAE;YAC9B,SAAS,EAAE,eAAe,CAAC,OAAO,CAAC;YACnC,OAAO,EAAE,CAAC,8CAAoB,CAAC;SAChC,CAAC;IACJ,CAAC;CACF,CAAA;AAVY,kDAAmB;8BAAnB,mBAAmB;IAJ/B,IAAA,eAAM,EAAC;QACN,SAAS,EAAE,eAAe,CAAC,EAAE,CAAC;QAC9B,OAAO,EAAE,CAAC,8CAAoB,CAAC;KAChC,CAAC;GACW,mBAAmB,CAU/B"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ModuleMetadata } from '@nestjs/common';
|
|
2
|
+
import { CreateAxiosDefaults } from 'axios';
|
|
3
|
+
export declare const SHARED_KEY_HTTP_OPTIONS: unique symbol;
|
|
4
|
+
export declare const SHARED_KEY_HTTP_AXIOS_INSTANCE: unique symbol;
|
|
5
|
+
export declare const DEFAULT_SERVICE_NAME = "unknown-service";
|
|
6
|
+
export type SharedKeyHttpModuleOptions = {
|
|
7
|
+
/** `x-service-name` sent with the internal token. Default: `defaultServiceName()`. */
|
|
8
|
+
serviceName?: string;
|
|
9
|
+
/** Defaults of the module's own axios instance (e.g. `timeout`). */
|
|
10
|
+
axiosConfig?: CreateAxiosDefaults;
|
|
11
|
+
/**
|
|
12
|
+
* Modules that provide `SharedKeyService`, e.g. `[SharedKeyModule]`. Leave it
|
|
13
|
+
* empty when the app registers `SharedKeyModule.forRoot({ isGlobal: true })`
|
|
14
|
+
* (or `SharedSecretModule`) once at the root.
|
|
15
|
+
*/
|
|
16
|
+
imports?: ModuleMetadata['imports'];
|
|
17
|
+
/** Registers the module globally. Default: false. */
|
|
18
|
+
isGlobal?: boolean;
|
|
19
|
+
};
|
|
20
|
+
/** `${APP_ENV}-${npm_package_name}`, the package name alone without APP_ENV, else `unknown-service`. */
|
|
21
|
+
export declare const defaultServiceName: (env?: NodeJS.ProcessEnv) => string;
|
|
22
|
+
//# sourceMappingURL=shared-key-http.options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-key-http.options.d.ts","sourceRoot":"","sources":["../src/shared-key-http.options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAE5C,eAAO,MAAM,uBAAuB,eAAoC,CAAC;AACzE,eAAO,MAAM,8BAA8B,eAE1C,CAAC;AACF,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AAEtD,MAAM,MAAM,0BAA0B,GAAG;IACvC,sFAAsF;IACtF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC;;;;OAIG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC,SAAS,CAAC,CAAC;IACpC,qDAAqD;IACrD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,wGAAwG;AACxG,eAAO,MAAM,kBAAkB,GAC7B,MAAK,MAAM,CAAC,UAAwB,KACnC,MAIF,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defaultServiceName = exports.DEFAULT_SERVICE_NAME = exports.SHARED_KEY_HTTP_AXIOS_INSTANCE = exports.SHARED_KEY_HTTP_OPTIONS = void 0;
|
|
4
|
+
exports.SHARED_KEY_HTTP_OPTIONS = Symbol('SHARED_KEY_HTTP_OPTIONS');
|
|
5
|
+
exports.SHARED_KEY_HTTP_AXIOS_INSTANCE = Symbol('SHARED_KEY_HTTP_AXIOS_INSTANCE');
|
|
6
|
+
exports.DEFAULT_SERVICE_NAME = 'unknown-service';
|
|
7
|
+
/** `${APP_ENV}-${npm_package_name}`, the package name alone without APP_ENV, else `unknown-service`. */
|
|
8
|
+
const defaultServiceName = (env = process.env) => {
|
|
9
|
+
const packageName = env.npm_package_name;
|
|
10
|
+
if (!packageName)
|
|
11
|
+
return exports.DEFAULT_SERVICE_NAME;
|
|
12
|
+
return env.APP_ENV ? `${env.APP_ENV}-${packageName}` : packageName;
|
|
13
|
+
};
|
|
14
|
+
exports.defaultServiceName = defaultServiceName;
|
|
15
|
+
//# sourceMappingURL=shared-key-http.options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-key-http.options.js","sourceRoot":"","sources":["../src/shared-key-http.options.ts"],"names":[],"mappings":";;;AAGa,QAAA,uBAAuB,GAAG,MAAM,CAAC,yBAAyB,CAAC,CAAC;AAC5D,QAAA,8BAA8B,GAAG,MAAM,CAClD,gCAAgC,CACjC,CAAC;AACW,QAAA,oBAAoB,GAAG,iBAAiB,CAAC;AAiBtD,wGAAwG;AACjG,MAAM,kBAAkB,GAAG,CAChC,MAAyB,OAAO,CAAC,GAAG,EAC5B,EAAE;IACV,MAAM,WAAW,GAAG,GAAG,CAAC,gBAAgB,CAAC;IACzC,IAAI,CAAC,WAAW;QAAE,OAAO,4BAAoB,CAAC;IAC9C,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,IAAI,WAAW,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;AACrE,CAAC,CAAC;AANW,QAAA,kBAAkB,sBAM7B"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { HttpService } from '@nestjs/axios';
|
|
2
|
+
import { SharedKeyService } from '@origins-digital/nestjs-shared-key';
|
|
3
|
+
import { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
|
|
4
|
+
import { InternalAuthHeaders } from './internal-auth.rule';
|
|
5
|
+
import { SharedKeyHttpModuleOptions } from './shared-key-http.options';
|
|
6
|
+
export declare const DEFAULT_REQUESTED_SERVICE = "shared-key-http-service";
|
|
7
|
+
/** Axios config plus the service label used in the errors of `*AsPromise`. */
|
|
8
|
+
export type SharedKeyHttpRequestConfig<D = unknown> = AxiosRequestConfig<D> & {
|
|
9
|
+
requestedService?: string;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* `HttpService` for calls to internal Origins services: `applyInternalAuth`
|
|
13
|
+
* adds `x-internal-auth-token` and `x-service-name` unless the caller set an
|
|
14
|
+
* `authorization` or `x-internal-auth-token` header key.
|
|
15
|
+
*
|
|
16
|
+
* It runs on the module's own axios instance, never the global axios, so a
|
|
17
|
+
* plain `HttpModule` (calls to external hosts) is left untouched.
|
|
18
|
+
*/
|
|
19
|
+
export declare class SharedKeyHttpService extends HttpService {
|
|
20
|
+
private readonly sharedKeyService;
|
|
21
|
+
private readonly serviceName;
|
|
22
|
+
constructor(axiosInstance: AxiosInstance, sharedKeyService: SharedKeyService, options: SharedKeyHttpModuleOptions);
|
|
23
|
+
/**
|
|
24
|
+
* Internal auth headers, also usable as the headers provider of other clients
|
|
25
|
+
* (`() => sharedKeyHttp.internalHeaders()`). Rejects when no token resolves.
|
|
26
|
+
*/
|
|
27
|
+
internalHeaders(): Promise<InternalAuthHeaders>;
|
|
28
|
+
getAsPromise<T = unknown, D = unknown>(url: string, config?: SharedKeyHttpRequestConfig<D>): Promise<AxiosResponse<T, D>>;
|
|
29
|
+
deleteAsPromise<T = unknown, D = unknown>(url: string, config?: SharedKeyHttpRequestConfig<D>): Promise<AxiosResponse<T, D>>;
|
|
30
|
+
headAsPromise<T = unknown, D = unknown>(url: string, config?: SharedKeyHttpRequestConfig<D>): Promise<AxiosResponse<T, D>>;
|
|
31
|
+
postAsPromise<T = unknown, D = unknown>(url: string, data?: D, config?: SharedKeyHttpRequestConfig<D>): Promise<AxiosResponse<T, D>>;
|
|
32
|
+
putAsPromise<T = unknown, D = unknown>(url: string, data?: D, config?: SharedKeyHttpRequestConfig<D>): Promise<AxiosResponse<T, D>>;
|
|
33
|
+
patchAsPromise<T = unknown, D = unknown>(url: string, data?: D, config?: SharedKeyHttpRequestConfig<D>): Promise<AxiosResponse<T, D>>;
|
|
34
|
+
private resolveConfig;
|
|
35
|
+
/**
|
|
36
|
+
* HTTP errors become the Nest exception `raiseError` builds, labelled with
|
|
37
|
+
* `requestedService`; other errors (e.g. from the auth rule) pass through.
|
|
38
|
+
*/
|
|
39
|
+
private toPromise;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=shared-key-http.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-key-http.service.d.ts","sourceRoot":"","sources":["../src/shared-key-http.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAQ5C,OAAO,EAEL,gBAAgB,EACjB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,aAAa,EAEd,MAAM,OAAO,CAAC;AAEf,OAAO,EAGL,mBAAmB,EAEpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAIL,0BAA0B,EAC3B,MAAM,2BAA2B,CAAC;AAEnC,eAAO,MAAM,yBAAyB,4BAA4B,CAAC;AAEnE,8EAA8E;AAC9E,MAAM,MAAM,0BAA0B,CAAC,CAAC,GAAG,OAAO,IAAI,kBAAkB,CAAC,CAAC,CAAC,GAAG;IAC5E,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF;;;;;;;GAOG;AACH,qBACa,oBAAqB,SAAQ,WAAW;IAKjD,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IAJnC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAGK,aAAa,EAAE,aAAa,EACnD,gBAAgB,EAAE,gBAAgB,EAClB,OAAO,EAAE,0BAA0B;IAStE;;;OAGG;IACG,eAAe,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAerD,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EACnC,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,0BAA0B,CAAC,CAAC,CAAC,GACrC,OAAO,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAK/B,eAAe,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EACtC,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,0BAA0B,CAAC,CAAC,CAAC,GACrC,OAAO,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAK/B,aAAa,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EACpC,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,0BAA0B,CAAC,CAAC,CAAC,GACrC,OAAO,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAK/B,aAAa,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EACpC,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,CAAC,EACR,MAAM,CAAC,EAAE,0BAA0B,CAAC,CAAC,CAAC,GACrC,OAAO,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAQ/B,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EACnC,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,CAAC,EACR,MAAM,CAAC,EAAE,0BAA0B,CAAC,CAAC,CAAC,GACrC,OAAO,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAQ/B,cAAc,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EACrC,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,CAAC,EACR,MAAM,CAAC,EAAE,0BAA0B,CAAC,CAAC,CAAC,GACrC,OAAO,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAQ/B,OAAO,CAAC,aAAa;IAerB;;;OAGG;IACH,OAAO,CAAC,SAAS;CAalB"}
|
|
@@ -0,0 +1,120 @@
|
|
|
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 __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
15
|
+
var t = {};
|
|
16
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
17
|
+
t[p] = s[p];
|
|
18
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
19
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
20
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
21
|
+
t[p[i]] = s[p[i]];
|
|
22
|
+
}
|
|
23
|
+
return t;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.SharedKeyHttpService = exports.DEFAULT_REQUESTED_SERVICE = void 0;
|
|
27
|
+
const axios_1 = require("@nestjs/axios");
|
|
28
|
+
const common_1 = require("@nestjs/common");
|
|
29
|
+
const cacheable_1 = require("@origins-digital/cacheable");
|
|
30
|
+
const error_utils_1 = require("@origins-digital/error-utils");
|
|
31
|
+
const nestjs_shared_key_1 = require("@origins-digital/nestjs-shared-key");
|
|
32
|
+
const axios_2 = require("axios");
|
|
33
|
+
const rxjs_1 = require("rxjs");
|
|
34
|
+
const internal_auth_rule_1 = require("./internal-auth.rule");
|
|
35
|
+
const shared_key_http_options_1 = require("./shared-key-http.options");
|
|
36
|
+
exports.DEFAULT_REQUESTED_SERVICE = 'shared-key-http-service';
|
|
37
|
+
/**
|
|
38
|
+
* `HttpService` for calls to internal Origins services: `applyInternalAuth`
|
|
39
|
+
* adds `x-internal-auth-token` and `x-service-name` unless the caller set an
|
|
40
|
+
* `authorization` or `x-internal-auth-token` header key.
|
|
41
|
+
*
|
|
42
|
+
* It runs on the module's own axios instance, never the global axios, so a
|
|
43
|
+
* plain `HttpModule` (calls to external hosts) is left untouched.
|
|
44
|
+
*/
|
|
45
|
+
let SharedKeyHttpService = class SharedKeyHttpService extends axios_1.HttpService {
|
|
46
|
+
constructor(axiosInstance, sharedKeyService, options) {
|
|
47
|
+
var _a;
|
|
48
|
+
super(axiosInstance);
|
|
49
|
+
this.sharedKeyService = sharedKeyService;
|
|
50
|
+
this.serviceName = (_a = options.serviceName) !== null && _a !== void 0 ? _a : (0, shared_key_http_options_1.defaultServiceName)();
|
|
51
|
+
axiosInstance.interceptors.request.use((config) => (0, internal_auth_rule_1.applyInternalAuth)(config, () => this.internalHeaders()));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Internal auth headers, also usable as the headers provider of other clients
|
|
55
|
+
* (`() => sharedKeyHttp.internalHeaders()`). Rejects when no token resolves.
|
|
56
|
+
*/
|
|
57
|
+
async internalHeaders() {
|
|
58
|
+
const jwtAccessToken = cacheable_1.GenericOutput.data(await this.sharedKeyService.getInternalAuthJWT());
|
|
59
|
+
if (!(jwtAccessToken === null || jwtAccessToken === void 0 ? void 0 : jwtAccessToken.key)) {
|
|
60
|
+
throw new common_1.InternalServerErrorException('Could not resolve the internal shared key token');
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
[internal_auth_rule_1.INTERNAL_AUTH_TOKEN_HEADER]: jwtAccessToken.key,
|
|
64
|
+
[internal_auth_rule_1.SERVICE_NAME_HEADER]: this.serviceName,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
getAsPromise(url, config) {
|
|
68
|
+
const { requestedService, axiosConfig } = this.resolveConfig(config);
|
|
69
|
+
return this.toPromise(this.get(url, axiosConfig), requestedService);
|
|
70
|
+
}
|
|
71
|
+
deleteAsPromise(url, config) {
|
|
72
|
+
const { requestedService, axiosConfig } = this.resolveConfig(config);
|
|
73
|
+
return this.toPromise(this.delete(url, axiosConfig), requestedService);
|
|
74
|
+
}
|
|
75
|
+
headAsPromise(url, config) {
|
|
76
|
+
const { requestedService, axiosConfig } = this.resolveConfig(config);
|
|
77
|
+
return this.toPromise(this.head(url, axiosConfig), requestedService);
|
|
78
|
+
}
|
|
79
|
+
postAsPromise(url, data, config) {
|
|
80
|
+
const { requestedService, axiosConfig } = this.resolveConfig(config);
|
|
81
|
+
return this.toPromise(this.post(url, data, axiosConfig), requestedService);
|
|
82
|
+
}
|
|
83
|
+
putAsPromise(url, data, config) {
|
|
84
|
+
const { requestedService, axiosConfig } = this.resolveConfig(config);
|
|
85
|
+
return this.toPromise(this.put(url, data, axiosConfig), requestedService);
|
|
86
|
+
}
|
|
87
|
+
patchAsPromise(url, data, config) {
|
|
88
|
+
const { requestedService, axiosConfig } = this.resolveConfig(config);
|
|
89
|
+
return this.toPromise(this.patch(url, data, axiosConfig), requestedService);
|
|
90
|
+
}
|
|
91
|
+
resolveConfig(config) {
|
|
92
|
+
if (!config) {
|
|
93
|
+
return {
|
|
94
|
+
requestedService: exports.DEFAULT_REQUESTED_SERVICE,
|
|
95
|
+
axiosConfig: undefined,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
const { requestedService = exports.DEFAULT_REQUESTED_SERVICE } = config, axiosConfig = __rest(config, ["requestedService"]);
|
|
99
|
+
return { requestedService, axiosConfig };
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* HTTP errors become the Nest exception `raiseError` builds, labelled with
|
|
103
|
+
* `requestedService`; other errors (e.g. from the auth rule) pass through.
|
|
104
|
+
*/
|
|
105
|
+
toPromise(request$, requestedService) {
|
|
106
|
+
return (0, rxjs_1.firstValueFrom)(request$.pipe((0, rxjs_1.catchError)((error) => {
|
|
107
|
+
if ((0, axios_2.isAxiosError)(error))
|
|
108
|
+
(0, error_utils_1.raiseError)(error, { requestedService });
|
|
109
|
+
throw error;
|
|
110
|
+
})));
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
exports.SharedKeyHttpService = SharedKeyHttpService;
|
|
114
|
+
exports.SharedKeyHttpService = SharedKeyHttpService = __decorate([
|
|
115
|
+
(0, common_1.Injectable)(),
|
|
116
|
+
__param(0, (0, common_1.Inject)(shared_key_http_options_1.SHARED_KEY_HTTP_AXIOS_INSTANCE)),
|
|
117
|
+
__param(2, (0, common_1.Inject)(shared_key_http_options_1.SHARED_KEY_HTTP_OPTIONS)),
|
|
118
|
+
__metadata("design:paramtypes", [Function, nestjs_shared_key_1.SharedKeyService, Object])
|
|
119
|
+
], SharedKeyHttpService);
|
|
120
|
+
//# sourceMappingURL=shared-key-http.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-key-http.service.js","sourceRoot":"","sources":["../src/shared-key-http.service.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,102 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@origins-digital/nestjs-shared-key-http",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "NestJS HttpService that adds the internal shared-key auth headers to calls between Origins services",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.d.ts",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"author": "Origins Digital (https://www.origins-digital.com/)",
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
18
|
+
"lint": "eslint \"src/**/*.ts\"",
|
|
19
|
+
"lint:fix": "eslint \"src/**/*.ts\" --fix",
|
|
20
|
+
"test": "jest --passWithNoTests",
|
|
21
|
+
"test:watch": "jest --watch",
|
|
22
|
+
"test:cov": "jest --coverage",
|
|
23
|
+
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
|
|
24
|
+
"build": "rimraf dist && tsc -p tsconfig.build.json",
|
|
25
|
+
"release:patch": "release-it patch --ci",
|
|
26
|
+
"release:minor": "release-it minor --ci",
|
|
27
|
+
"release:major": "release-it major --ci",
|
|
28
|
+
"commit": "git-cz",
|
|
29
|
+
"prepublish": "yarn build"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@origins-digital/cacheable": "3.4.0",
|
|
33
|
+
"@origins-digital/error-utils": "2.1.4"
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"@nestjs/axios": ">=4.0.1",
|
|
37
|
+
"@nestjs/common": ">=11.0.0",
|
|
38
|
+
"@origins-digital/nestjs-shared-key": ">=3.2.1",
|
|
39
|
+
"axios": ">=1.4.0",
|
|
40
|
+
"rxjs": ">=7.1.0"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@commitlint/cli": "^17.6.6",
|
|
44
|
+
"@commitlint/config-conventional": "^17.6.6",
|
|
45
|
+
"@nestjs/testing": "^11.1.11",
|
|
46
|
+
"@types/node": "^20.3.1",
|
|
47
|
+
"commitizen": "^4.3.0",
|
|
48
|
+
"conventional-recommended-bump": "^11.2.0",
|
|
49
|
+
"cz-conventional-changelog": "^3.3.0",
|
|
50
|
+
"eslint": "^9.0.0",
|
|
51
|
+
"eslint-config-prettier": "^9.0.0",
|
|
52
|
+
"eslint-plugin-prettier": "^5.0.0",
|
|
53
|
+
"jest": "^29.5.0",
|
|
54
|
+
"prettier": "^3.0.0",
|
|
55
|
+
"rimraf": "^5.0.5",
|
|
56
|
+
"ts-jest": "^29.1.0",
|
|
57
|
+
"ts-node": "^10.9.1",
|
|
58
|
+
"tsconfig-paths": "^4.2.0",
|
|
59
|
+
"typescript": "^5.3.2"
|
|
60
|
+
},
|
|
61
|
+
"jest": {
|
|
62
|
+
"moduleFileExtensions": [
|
|
63
|
+
"js",
|
|
64
|
+
"json",
|
|
65
|
+
"ts"
|
|
66
|
+
],
|
|
67
|
+
"rootDir": "src",
|
|
68
|
+
"testRegex": ".*\\.spec\\.ts$",
|
|
69
|
+
"transform": {
|
|
70
|
+
"^.+\\.ts$": "ts-jest"
|
|
71
|
+
},
|
|
72
|
+
"collectCoverageFrom": [
|
|
73
|
+
"**/*.(t|j)s"
|
|
74
|
+
],
|
|
75
|
+
"coverageDirectory": "../coverage",
|
|
76
|
+
"testEnvironment": "node"
|
|
77
|
+
},
|
|
78
|
+
"publishConfig": {
|
|
79
|
+
"registry": "https://registry.npmjs.org",
|
|
80
|
+
"access": "public"
|
|
81
|
+
},
|
|
82
|
+
"release-it": {
|
|
83
|
+
"git": {
|
|
84
|
+
"requireCleanWorkingDir": false,
|
|
85
|
+
"commitMessage": "chore(release): bump nestjs-shared-key-http ${version}",
|
|
86
|
+
"tagName": "${npm.name}-v${version}",
|
|
87
|
+
"tagAnnotation": "nestjs-shared-key-http-${version}",
|
|
88
|
+
"push": false,
|
|
89
|
+
"commit": true,
|
|
90
|
+
"addUntrackedFiles": false
|
|
91
|
+
},
|
|
92
|
+
"npm": {
|
|
93
|
+
"publish": true
|
|
94
|
+
},
|
|
95
|
+
"hooks": {
|
|
96
|
+
"before:init": [
|
|
97
|
+
"yarn test",
|
|
98
|
+
"yarn build"
|
|
99
|
+
]
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|