@viardex/viardex-libs 1.0.4 → 1.0.5
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 +179 -0
- package/dist/argon/argon.module.d.ts +2 -0
- package/dist/{notification/notification.module.js → argon/argon.module.js} +9 -8
- package/dist/argon/argon.service.d.ts +6 -0
- package/dist/argon/argon.service.js +74 -0
- package/dist/argon/index.d.ts +2 -0
- package/dist/{notification → argon}/index.js +2 -4
- package/dist/auth/auth.constants.d.ts +4 -0
- package/dist/auth/auth.constants.js +7 -0
- package/dist/auth/auth.interfaces.d.ts +19 -0
- package/dist/auth/auth.module.d.ts +2 -0
- package/dist/auth/auth.module.js +30 -0
- package/dist/auth/auth.service.d.ts +13 -0
- package/dist/auth/auth.service.js +99 -0
- package/dist/auth/decorators/auth-token-types.decorator.d.ts +2 -0
- package/dist/auth/decorators/auth-token-types.decorator.js +7 -0
- package/dist/auth/decorators/current-auth.decorator.d.ts +1 -0
- package/dist/auth/decorators/current-auth.decorator.js +10 -0
- package/dist/auth/decorators/index.d.ts +5 -0
- package/dist/auth/decorators/index.js +21 -0
- package/dist/auth/decorators/permissions.decorator.d.ts +1 -0
- package/dist/auth/decorators/permissions.decorator.js +7 -0
- package/dist/auth/decorators/public.decorator.d.ts +1 -0
- package/dist/auth/decorators/public.decorator.js +7 -0
- package/dist/auth/decorators/roles.decorator.d.ts +1 -0
- package/dist/auth/decorators/roles.decorator.js +7 -0
- package/dist/auth/guards/auth.guard.d.ts +10 -0
- package/dist/auth/guards/auth.guard.js +58 -0
- package/dist/auth/guards/index.d.ts +3 -0
- package/dist/auth/guards/index.js +19 -0
- package/dist/auth/guards/permissions.guard.d.ts +7 -0
- package/dist/auth/guards/permissions.guard.js +47 -0
- package/dist/auth/guards/roles.guard.d.ts +7 -0
- package/dist/auth/guards/roles.guard.js +48 -0
- package/dist/auth/index.d.ts +6 -0
- package/dist/auth/index.js +22 -0
- package/dist/cache/cache.constants.d.ts +1 -0
- package/dist/cache/cache.constants.js +4 -0
- package/dist/cache/cache.module.js +5 -1
- package/dist/cache/cache.service.d.ts +5 -0
- package/dist/cache/cache.service.js +28 -1
- package/dist/cache/index.d.ts +1 -0
- package/dist/cache/index.js +1 -0
- package/dist/common/config/nats.config.d.ts +7 -8
- package/dist/common/config/nats.config.js +25 -4
- package/dist/common/constants/queues.constants.d.ts +7 -15
- package/dist/common/constants/queues.constants.js +8 -16
- package/dist/common/enums/index.d.ts +0 -2
- package/dist/common/enums/index.js +0 -2
- package/dist/health/health.controller.d.ts +19 -0
- package/dist/health/health.controller.js +88 -0
- package/dist/health/health.module.d.ts +2 -0
- package/dist/health/health.module.js +21 -0
- package/dist/health/index.d.ts +2 -0
- package/dist/health/index.js +18 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +5 -1
- package/dist/logger/index.d.ts +2 -0
- package/dist/logger/index.js +18 -0
- package/dist/logger/logger.module.d.ts +2 -0
- package/dist/logger/logger.module.js +58 -0
- package/dist/logger/logging.interceptor.d.ts +8 -0
- package/dist/logger/logging.interceptor.js +62 -0
- package/dist/rpc/index.d.ts +0 -36
- package/dist/rpc/index.js +3 -73
- package/dist/storage/index.d.ts +5 -0
- package/dist/storage/index.js +21 -0
- package/dist/storage/r2.service.d.ts +20 -0
- package/dist/storage/r2.service.js +208 -0
- package/dist/storage/s3.service.d.ts +20 -0
- package/dist/storage/s3.service.js +204 -0
- package/dist/storage/storage.interface.d.ts +29 -0
- package/dist/storage/storage.interface.js +2 -0
- package/dist/storage/storage.module.d.ts +2 -0
- package/dist/storage/storage.module.js +24 -0
- package/dist/storage/storage.service.d.ts +22 -0
- package/dist/storage/storage.service.js +54 -0
- package/package.json +80 -27
- package/dist/common/enums/support-action.enum.d.ts +0 -7
- package/dist/common/enums/support-action.enum.js +0 -11
- package/dist/common/enums/ticket.enum.d.ts +0 -19
- package/dist/common/enums/ticket.enum.js +0 -25
- package/dist/notification/index.d.ts +0 -4
- package/dist/notification/notification.client.d.ts +0 -76
- package/dist/notification/notification.client.js +0 -325
- package/dist/notification/notification.enum.d.ts +0 -54
- package/dist/notification/notification.enum.js +0 -73
- package/dist/notification/notification.interface.d.ts +0 -285
- package/dist/notification/notification.module.d.ts +0 -2
- package/dist/tsconfig.tsbuildinfo +0 -1
- /package/dist/{notification/notification.interface.js → auth/auth.interfaces.js} +0 -0
package/README.md
CHANGED
|
@@ -1 +1,180 @@
|
|
|
1
1
|
# Viardex Libs
|
|
2
|
+
|
|
3
|
+
Shared NestJS infrastructure for Viardex services.
|
|
4
|
+
|
|
5
|
+
## Argon
|
|
6
|
+
|
|
7
|
+
`@viardex/viardex-libs` provides a shared Argon2id hashing module for passwords, passcodes, and transaction PINs.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { ArgonModule, ArgonService } from '@viardex/viardex-libs';
|
|
11
|
+
|
|
12
|
+
@Module({
|
|
13
|
+
imports: [ArgonModule],
|
|
14
|
+
})
|
|
15
|
+
export class AppModule {}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Example:
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
constructor(private readonly argonService: ArgonService) {}
|
|
22
|
+
|
|
23
|
+
const hash = await this.argonService.hash(password);
|
|
24
|
+
const isValid = await this.argonService.verify(hash, password);
|
|
25
|
+
const shouldRotate = await this.argonService.needsRehash(hash);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`ArgonService.verify()` safely returns `false` for malformed hashes instead of leaking low-level argon exceptions into auth flows.
|
|
29
|
+
|
|
30
|
+
## Auth
|
|
31
|
+
|
|
32
|
+
`@viardex/viardex-libs` provides the shared JWT verifier module.
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { AuthModule } from '@viardex/viardex-libs';
|
|
36
|
+
|
|
37
|
+
@Module({
|
|
38
|
+
imports: [AuthModule],
|
|
39
|
+
})
|
|
40
|
+
export class AppModule {}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Decorators
|
|
44
|
+
|
|
45
|
+
Use the shared barrel:
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import {
|
|
49
|
+
AuthModule,
|
|
50
|
+
CurrentAuth,
|
|
51
|
+
Permissions,
|
|
52
|
+
Public,
|
|
53
|
+
Roles,
|
|
54
|
+
} from '@viardex/viardex-libs';
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
- `@Public()` marks a route as bypassing the global JWT guard.
|
|
58
|
+
- `@Roles(...roles)` declares allowed staff roles for a route.
|
|
59
|
+
- `@Permissions(...permissions)` declares required permissions for a route.
|
|
60
|
+
- `@CurrentAuth()` returns the verified JWT principal from the request.
|
|
61
|
+
|
|
62
|
+
### Guards
|
|
63
|
+
|
|
64
|
+
Guard classes live under `src/auth/guards` and are exported through the shared barrel:
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
import { PermissionsGuard, RolesGuard } from '@viardex/viardex-libs';
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Example:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
@UseGuards(RolesGuard, PermissionsGuard)
|
|
74
|
+
@Roles('admin', 'support')
|
|
75
|
+
@Permissions('tickets.read', 'tickets.resolve')
|
|
76
|
+
@Get('tickets')
|
|
77
|
+
listTickets() {}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### JWT Config
|
|
81
|
+
|
|
82
|
+
Services should expose:
|
|
83
|
+
|
|
84
|
+
```env
|
|
85
|
+
JWT_ALGORITHM=RS256
|
|
86
|
+
JWT_ISSUER=viardex-user-service
|
|
87
|
+
JWT_AUDIENCE=viardex-api
|
|
88
|
+
JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The shared auth module verifies JWTs globally. Role and permission guards are opt-in at the route or controller level.
|
|
92
|
+
|
|
93
|
+
## Logger
|
|
94
|
+
|
|
95
|
+
`LoggerModule` is global and wraps `nestjs-pino`.
|
|
96
|
+
|
|
97
|
+
- development uses `pino-pretty`
|
|
98
|
+
- non-HTTP contexts are ignored by `LoggingInterceptor`
|
|
99
|
+
- request logging keeps request id, method, URL, status code, and duration
|
|
100
|
+
|
|
101
|
+
## Health
|
|
102
|
+
|
|
103
|
+
`HealthModule` exposes:
|
|
104
|
+
|
|
105
|
+
- `GET /health` for lightweight liveness
|
|
106
|
+
- `GET /health/ready` for readiness checks
|
|
107
|
+
|
|
108
|
+
Readiness currently checks storage, memory, and NATS connectivity.
|
|
109
|
+
|
|
110
|
+
## Cache
|
|
111
|
+
|
|
112
|
+
`CacheModule.register()` exposes a Redis-backed `CacheService`.
|
|
113
|
+
|
|
114
|
+
Preferred APIs:
|
|
115
|
+
|
|
116
|
+
- `set()` / `get()`
|
|
117
|
+
- `setJson()` / `getJson()`
|
|
118
|
+
- `setIfNotExists()` for idempotency / locks
|
|
119
|
+
- `scan()` instead of `keys()` for production-safe pattern reads
|
|
120
|
+
- `ping()` for lightweight health checks
|
|
121
|
+
|
|
122
|
+
## Nest And Go Mapping
|
|
123
|
+
|
|
124
|
+
The Go shared package in `viardex-go` follows the same auth concepts, but uses middleware and request context instead of Nest metadata and guards.
|
|
125
|
+
|
|
126
|
+
| Nest (`viardex-libs`) | Go (`viardex-go`) |
|
|
127
|
+
| --- | --- |
|
|
128
|
+
| `AuthModule` | `auth` package setup in service bootstrap |
|
|
129
|
+
| `AuthService` | `auth.NewService(...)` / `auth.Service` |
|
|
130
|
+
| `AuthPrincipal` | `auth.Principal` |
|
|
131
|
+
| `AuthTokenType` | `auth.TokenType` |
|
|
132
|
+
| `AuthGuard` | `middlewares.Auth(...)` |
|
|
133
|
+
| `RolesGuard` | `middlewares.RequireRoles(...)` |
|
|
134
|
+
| `PermissionsGuard` | `middlewares.RequirePermissions(...)` |
|
|
135
|
+
| `AuthTokenTypes(...)` | `middlewares.RequireTokenTypes(...)` |
|
|
136
|
+
| `Public()` | keep route/group outside auth middleware |
|
|
137
|
+
| `Roles(...)` | wrap route/group with `middlewares.RequireRoles(...)` |
|
|
138
|
+
| `Permissions(...)` | wrap route/group with `middlewares.RequirePermissions(...)` |
|
|
139
|
+
| `CurrentAuth()` | `auth.PrincipalFromContext(r.Context())` |
|
|
140
|
+
|
|
141
|
+
### Example Comparison
|
|
142
|
+
|
|
143
|
+
Nest:
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
@UseGuards(PermissionsGuard)
|
|
147
|
+
@Permissions('ledger.read')
|
|
148
|
+
@Get('/ledger')
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Go:
|
|
152
|
+
|
|
153
|
+
```go
|
|
154
|
+
r.With(middlewares.RequirePermissions("ledger.read")).Get("/ledger", handler)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Nest:
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
@Public()
|
|
161
|
+
@Get('/health')
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Go:
|
|
165
|
+
|
|
166
|
+
```go
|
|
167
|
+
r.Get("/health", handler)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Nest:
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
const principal = request.user;
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Go:
|
|
177
|
+
|
|
178
|
+
```go
|
|
179
|
+
principal, ok := auth.PrincipalFromContext(r.Context())
|
|
180
|
+
```
|
|
@@ -6,15 +6,16 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
6
6
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
7
|
};
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.
|
|
9
|
+
exports.ArgonModule = void 0;
|
|
10
10
|
const common_1 = require("@nestjs/common");
|
|
11
|
-
const
|
|
12
|
-
let
|
|
11
|
+
const argon_service_1 = require("./argon.service");
|
|
12
|
+
let ArgonModule = class ArgonModule {
|
|
13
13
|
};
|
|
14
|
-
exports.
|
|
15
|
-
exports.
|
|
14
|
+
exports.ArgonModule = ArgonModule;
|
|
15
|
+
exports.ArgonModule = ArgonModule = __decorate([
|
|
16
|
+
(0, common_1.Global)(),
|
|
16
17
|
(0, common_1.Module)({
|
|
17
|
-
providers: [
|
|
18
|
-
exports: [
|
|
18
|
+
providers: [argon_service_1.ArgonService],
|
|
19
|
+
exports: [argon_service_1.ArgonService],
|
|
19
20
|
})
|
|
20
|
-
],
|
|
21
|
+
], ArgonModule);
|
|
@@ -0,0 +1,74 @@
|
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
19
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
20
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
21
|
+
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;
|
|
22
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
23
|
+
};
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.ArgonService = void 0;
|
|
43
|
+
const common_1 = require("@nestjs/common");
|
|
44
|
+
const argon2 = __importStar(require("argon2"));
|
|
45
|
+
let ArgonService = class ArgonService {
|
|
46
|
+
options = {
|
|
47
|
+
type: argon2.argon2id,
|
|
48
|
+
memoryCost: 2 ** 16,
|
|
49
|
+
timeCost: 3,
|
|
50
|
+
parallelism: 1,
|
|
51
|
+
};
|
|
52
|
+
async hash(value) {
|
|
53
|
+
return argon2.hash(value, this.options);
|
|
54
|
+
}
|
|
55
|
+
async verify(hash, value) {
|
|
56
|
+
try {
|
|
57
|
+
return await argon2.verify(hash, value);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async needsRehash(hash) {
|
|
64
|
+
return argon2.needsRehash(hash, {
|
|
65
|
+
memoryCost: this.options.memoryCost,
|
|
66
|
+
timeCost: this.options.timeCost,
|
|
67
|
+
parallelism: this.options.parallelism,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
exports.ArgonService = ArgonService;
|
|
72
|
+
exports.ArgonService = ArgonService = __decorate([
|
|
73
|
+
(0, common_1.Injectable)()
|
|
74
|
+
], ArgonService);
|
|
@@ -14,7 +14,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./
|
|
18
|
-
__exportStar(require("./
|
|
19
|
-
__exportStar(require("./notification.enum"), exports);
|
|
20
|
-
__exportStar(require("./notification.module"), exports);
|
|
17
|
+
__exportStar(require("./argon.module"), exports);
|
|
18
|
+
__exportStar(require("./argon.service"), exports);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AUTH_PERMISSIONS_KEY = exports.AUTH_ROLES_KEY = exports.AUTH_TOKEN_TYPES_KEY = exports.IS_PUBLIC_KEY = void 0;
|
|
4
|
+
exports.IS_PUBLIC_KEY = 'viardex:isPublic';
|
|
5
|
+
exports.AUTH_TOKEN_TYPES_KEY = 'viardex:authTokenTypes';
|
|
6
|
+
exports.AUTH_ROLES_KEY = 'viardex:authRoles';
|
|
7
|
+
exports.AUTH_PERMISSIONS_KEY = 'viardex:authPermissions';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type AuthTokenType = 'user' | 'ops';
|
|
2
|
+
export interface TokenVerifierConfig {
|
|
3
|
+
issuer: string;
|
|
4
|
+
audience: string;
|
|
5
|
+
publicKey?: string;
|
|
6
|
+
algorithm: string;
|
|
7
|
+
}
|
|
8
|
+
export interface AuthPrincipal {
|
|
9
|
+
sub: string;
|
|
10
|
+
iss: string;
|
|
11
|
+
aud: string | string[];
|
|
12
|
+
iat?: number;
|
|
13
|
+
exp?: number;
|
|
14
|
+
jti?: string;
|
|
15
|
+
tokenType: AuthTokenType;
|
|
16
|
+
role?: string;
|
|
17
|
+
permissions?: string[];
|
|
18
|
+
claims: Record<string, unknown>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.AuthModule = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
const core_1 = require("@nestjs/core");
|
|
12
|
+
const guards_1 = require("./guards");
|
|
13
|
+
const auth_service_1 = require("./auth.service");
|
|
14
|
+
let AuthModule = class AuthModule {
|
|
15
|
+
};
|
|
16
|
+
exports.AuthModule = AuthModule;
|
|
17
|
+
exports.AuthModule = AuthModule = __decorate([
|
|
18
|
+
(0, common_1.Global)(),
|
|
19
|
+
(0, common_1.Module)({
|
|
20
|
+
providers: [
|
|
21
|
+
auth_service_1.AuthService,
|
|
22
|
+
guards_1.AuthGuard,
|
|
23
|
+
{
|
|
24
|
+
provide: core_1.APP_GUARD,
|
|
25
|
+
useClass: guards_1.AuthGuard,
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
exports: [guards_1.AuthGuard, auth_service_1.AuthService],
|
|
29
|
+
})
|
|
30
|
+
], AuthModule);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ConfigService } from '@nestjs/config';
|
|
2
|
+
import { AuthPrincipal, AuthTokenType, TokenVerifierConfig } from './auth.interfaces';
|
|
3
|
+
type ResolvedVerifierConfig = TokenVerifierConfig & {
|
|
4
|
+
tokenType: AuthTokenType;
|
|
5
|
+
};
|
|
6
|
+
export declare class AuthService {
|
|
7
|
+
private readonly configService;
|
|
8
|
+
constructor(configService: ConfigService);
|
|
9
|
+
verifyAccessToken(token: string): AuthPrincipal;
|
|
10
|
+
getVerifierConfig(): ResolvedVerifierConfig;
|
|
11
|
+
private normalizePublicKey;
|
|
12
|
+
}
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,99 @@
|
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
19
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
20
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
21
|
+
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;
|
|
22
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
23
|
+
};
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.AuthService = void 0;
|
|
43
|
+
const common_1 = require("@nestjs/common");
|
|
44
|
+
const jwt = __importStar(require("jsonwebtoken"));
|
|
45
|
+
let AuthService = class AuthService {
|
|
46
|
+
configService;
|
|
47
|
+
constructor(configService) {
|
|
48
|
+
this.configService = configService;
|
|
49
|
+
}
|
|
50
|
+
verifyAccessToken(token) {
|
|
51
|
+
const verifier = this.getVerifierConfig();
|
|
52
|
+
if (!verifier.publicKey) {
|
|
53
|
+
throw new common_1.UnauthorizedException('Missing JWT public key configuration');
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
const claims = jwt.verify(token, verifier.publicKey, {
|
|
57
|
+
algorithms: [verifier.algorithm],
|
|
58
|
+
issuer: verifier.issuer,
|
|
59
|
+
audience: verifier.audience,
|
|
60
|
+
});
|
|
61
|
+
if (!claims.sub || !claims.iss || !claims.aud) {
|
|
62
|
+
throw new common_1.UnauthorizedException('JWT payload is missing required claims');
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
sub: String(claims.sub),
|
|
66
|
+
iss: String(claims.iss),
|
|
67
|
+
aud: claims.aud,
|
|
68
|
+
iat: claims.iat,
|
|
69
|
+
exp: claims.exp,
|
|
70
|
+
jti: claims.jti,
|
|
71
|
+
tokenType: verifier.tokenType,
|
|
72
|
+
role: claims.role ? String(claims.role) : undefined,
|
|
73
|
+
permissions: Array.isArray(claims.permissions)
|
|
74
|
+
? claims.permissions.map((permission) => String(permission))
|
|
75
|
+
: undefined,
|
|
76
|
+
claims: claims,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
throw new common_1.UnauthorizedException(error?.message || 'Token verification failed');
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
getVerifierConfig() {
|
|
84
|
+
return {
|
|
85
|
+
issuer: this.configService.get('jwt.issuer', ''),
|
|
86
|
+
audience: this.configService.get('jwt.audience', ''),
|
|
87
|
+
publicKey: this.normalizePublicKey(this.configService.get('jwt.publicKey')),
|
|
88
|
+
algorithm: this.configService.get('jwt.algorithm', 'RS256') ?? 'RS256',
|
|
89
|
+
tokenType: 'user',
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
normalizePublicKey(value) {
|
|
93
|
+
return value?.replace(/\\n/g, '\n');
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
exports.AuthService = AuthService;
|
|
97
|
+
exports.AuthService = AuthService = __decorate([
|
|
98
|
+
(0, common_1.Injectable)()
|
|
99
|
+
], AuthService);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AuthTokenTypes = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const auth_constants_1 = require("../auth.constants");
|
|
6
|
+
const AuthTokenTypes = (...types) => (0, common_1.SetMetadata)(auth_constants_1.AUTH_TOKEN_TYPES_KEY, types);
|
|
7
|
+
exports.AuthTokenTypes = AuthTokenTypes;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const CurrentAuth: (...dataOrPipes: unknown[]) => ParameterDecorator;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CurrentAuth = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
exports.CurrentAuth = (0, common_1.createParamDecorator)((_data, context) => {
|
|
6
|
+
const request = context
|
|
7
|
+
.switchToHttp()
|
|
8
|
+
.getRequest();
|
|
9
|
+
return request.user;
|
|
10
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
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("./auth-token-types.decorator"), exports);
|
|
18
|
+
__exportStar(require("./current-auth.decorator"), exports);
|
|
19
|
+
__exportStar(require("./permissions.decorator"), exports);
|
|
20
|
+
__exportStar(require("./public.decorator"), exports);
|
|
21
|
+
__exportStar(require("./roles.decorator"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const Permissions: (...permissions: string[]) => import("@nestjs/common").CustomDecorator<string>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Permissions = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const auth_constants_1 = require("../auth.constants");
|
|
6
|
+
const Permissions = (...permissions) => (0, common_1.SetMetadata)(auth_constants_1.AUTH_PERMISSIONS_KEY, permissions);
|
|
7
|
+
exports.Permissions = Permissions;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const Public: () => import("@nestjs/common").CustomDecorator<string>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Public = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const auth_constants_1 = require("../auth.constants");
|
|
6
|
+
const Public = () => (0, common_1.SetMetadata)(auth_constants_1.IS_PUBLIC_KEY, true);
|
|
7
|
+
exports.Public = Public;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const Roles: (...roles: string[]) => import("@nestjs/common").CustomDecorator<string>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Roles = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const auth_constants_1 = require("../auth.constants");
|
|
6
|
+
const Roles = (...roles) => (0, common_1.SetMetadata)(auth_constants_1.AUTH_ROLES_KEY, roles);
|
|
7
|
+
exports.Roles = Roles;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
|
2
|
+
import { Reflector } from '@nestjs/core';
|
|
3
|
+
import { AuthService } from '../auth.service';
|
|
4
|
+
export declare class AuthGuard implements CanActivate {
|
|
5
|
+
private readonly reflector;
|
|
6
|
+
private readonly authService;
|
|
7
|
+
constructor(reflector: Reflector, authService: AuthService);
|
|
8
|
+
canActivate(context: ExecutionContext): boolean;
|
|
9
|
+
private extractBearerToken;
|
|
10
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.AuthGuard = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
const auth_constants_1 = require("../auth.constants");
|
|
12
|
+
let AuthGuard = class AuthGuard {
|
|
13
|
+
reflector;
|
|
14
|
+
authService;
|
|
15
|
+
constructor(reflector, authService) {
|
|
16
|
+
this.reflector = reflector;
|
|
17
|
+
this.authService = authService;
|
|
18
|
+
}
|
|
19
|
+
canActivate(context) {
|
|
20
|
+
const isPublic = this.reflector.getAllAndOverride(auth_constants_1.IS_PUBLIC_KEY, [
|
|
21
|
+
context.getHandler(),
|
|
22
|
+
context.getClass(),
|
|
23
|
+
]);
|
|
24
|
+
if (isPublic) {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
const request = context.switchToHttp().getRequest();
|
|
28
|
+
const token = this.extractBearerToken(request.headers.authorization);
|
|
29
|
+
const principal = this.authService.verifyAccessToken(token);
|
|
30
|
+
const allowedTypes = this.reflector.getAllAndOverride(auth_constants_1.AUTH_TOKEN_TYPES_KEY, [
|
|
31
|
+
context.getHandler(),
|
|
32
|
+
context.getClass(),
|
|
33
|
+
]) ?? [];
|
|
34
|
+
if (allowedTypes.length > 0 &&
|
|
35
|
+
!allowedTypes.includes(principal.tokenType)) {
|
|
36
|
+
throw new common_1.UnauthorizedException('Token type is not allowed for this route');
|
|
37
|
+
}
|
|
38
|
+
request.user = principal;
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
extractBearerToken(authorizationHeader) {
|
|
42
|
+
const value = Array.isArray(authorizationHeader)
|
|
43
|
+
? authorizationHeader[0]
|
|
44
|
+
: authorizationHeader;
|
|
45
|
+
if (!value) {
|
|
46
|
+
throw new common_1.UnauthorizedException('Authorization header is missing');
|
|
47
|
+
}
|
|
48
|
+
const [scheme, token] = value.split(' ');
|
|
49
|
+
if (scheme !== 'Bearer' || !token) {
|
|
50
|
+
throw new common_1.UnauthorizedException('Invalid authorization header format');
|
|
51
|
+
}
|
|
52
|
+
return token;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
exports.AuthGuard = AuthGuard;
|
|
56
|
+
exports.AuthGuard = AuthGuard = __decorate([
|
|
57
|
+
(0, common_1.Injectable)()
|
|
58
|
+
], AuthGuard);
|