@zola_do/authorization 0.1.9 → 0.1.13
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 +121 -0
- package/dist/guards/jwt.guard.js +1 -3
- package/dist/guards/jwt.guard.js.map +1 -1
- package/dist/guards/optional-jwt.guard.js +1 -3
- package/dist/guards/optional-jwt.guard.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/package.json +9 -4
- package/dist/utils/extract-user.d.ts +0 -1
- package/dist/utils/extract-user.js +0 -31
- package/dist/utils/extract-user.js.map +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# @zola_do/authorization
|
|
2
|
+
|
|
3
|
+
JWT authentication, API key validation, guards, and strategies for NestJS.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Install individually
|
|
9
|
+
npm install @zola_do/authorization
|
|
10
|
+
|
|
11
|
+
# Or via meta package
|
|
12
|
+
npm install @zola_do/nestjs-shared
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Module Setup
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { Module } from '@nestjs/common';
|
|
21
|
+
import { AuthorizationModule } from '@zola_do/authorization';
|
|
22
|
+
|
|
23
|
+
@Module({
|
|
24
|
+
imports: [AuthorizationModule],
|
|
25
|
+
})
|
|
26
|
+
export class AppModule {}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
By default, `JwtGuard` is registered as a global guard. Protect routes automatically; use `@AllowAnonymous()` for public routes.
|
|
30
|
+
|
|
31
|
+
### Protected Routes
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import { Controller, Get } from '@nestjs/common';
|
|
35
|
+
import { CurrentUser, JwtGuard, UseGuards } from '@zola_do/authorization';
|
|
36
|
+
|
|
37
|
+
@Controller('profile')
|
|
38
|
+
@UseGuards(JwtGuard)
|
|
39
|
+
export class ProfileController {
|
|
40
|
+
@Get()
|
|
41
|
+
getProfile(@CurrentUser() user: any) {
|
|
42
|
+
return user; // Contains JWT payload (id, email, organization, etc.)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Anonymous Routes
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { AllowAnonymous } from '@zola_do/authorization';
|
|
51
|
+
|
|
52
|
+
@Get('public')
|
|
53
|
+
@AllowAnonymous()
|
|
54
|
+
getPublicData() {
|
|
55
|
+
return { message: 'No auth required' };
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Permission Guards
|
|
60
|
+
|
|
61
|
+
Require specific permissions on routes:
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { PermissionsGuard } from '@zola_do/authorization';
|
|
65
|
+
|
|
66
|
+
@Post()
|
|
67
|
+
@UseGuards(JwtGuard, PermissionsGuard('product:create'))
|
|
68
|
+
createProduct(@Body() dto: CreateProductDto) {}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### API Key Guard
|
|
72
|
+
|
|
73
|
+
Protect routes with API key validation:
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { ApiKeyGuard } from '@zola_do/authorization';
|
|
77
|
+
|
|
78
|
+
@UseGuards(ApiKeyGuard)
|
|
79
|
+
@Get('api-data')
|
|
80
|
+
getApiData() {}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### AuthHelper
|
|
84
|
+
|
|
85
|
+
Generate and verify tokens:
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { AuthHelper } from '@zola_do/authorization';
|
|
89
|
+
|
|
90
|
+
@Injectable()
|
|
91
|
+
export class AuthService {
|
|
92
|
+
constructor(private readonly authHelper: AuthHelper) {}
|
|
93
|
+
|
|
94
|
+
async login(user: User) {
|
|
95
|
+
return this.authHelper.generateTokens(user);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Environment Variables
|
|
101
|
+
|
|
102
|
+
| Variable | Description |
|
|
103
|
+
|----------|-------------|
|
|
104
|
+
| `JWT_ACCESS_TOKEN_SECRET` | Secret for access token signing |
|
|
105
|
+
| `JWT_REFRESH_TOKEN_SECRET` | Secret for refresh token signing |
|
|
106
|
+
| `JWT_ACCESS_TOKEN_EXPIRES` | Access token TTL (e.g. `15m`) |
|
|
107
|
+
| `JWT_REFRESH_TOKEN_EXPIRES` | Refresh token TTL (e.g. `7d`) |
|
|
108
|
+
| `API_KEY` | API key for `ApiKeyGuard` validation |
|
|
109
|
+
|
|
110
|
+
## Exports
|
|
111
|
+
|
|
112
|
+
- **Guards:** `JwtGuard`, `JwtRefreshGuard`, `PermissionsGuard`, `ApiKeyGuard`, `VendorGuard`, `OptionalJwtGuard`, `ThrottlerBehindProxyGuard`
|
|
113
|
+
- **Decorators:** `@CurrentUser()`, `@AllowAnonymous()`
|
|
114
|
+
- **Strategies:** `JwtStrategy`, `JwtRefreshTokenStrategy`
|
|
115
|
+
- **Helpers:** `AuthHelper`
|
|
116
|
+
|
|
117
|
+
## Related Packages
|
|
118
|
+
|
|
119
|
+
- [@zola_do/core](../core) — Shared types and decorators
|
|
120
|
+
- [@zola_do/interceptors](../interceptors) — TenantInterceptor uses `req.user` from JWT
|
|
121
|
+
- [@zola_do/crud](../crud) — Uses JwtGuard and PermissionsGuard
|
package/dist/guards/jwt.guard.js
CHANGED
|
@@ -14,7 +14,6 @@ const common_1 = require("@nestjs/common");
|
|
|
14
14
|
const core_1 = require("@nestjs/core");
|
|
15
15
|
const allow_anonymous_decorator_1 = require("../decorators/allow-anonymous.decorator");
|
|
16
16
|
const jsonwebtoken = require("jsonwebtoken");
|
|
17
|
-
const extract_user_1 = require("../utils/extract-user");
|
|
18
17
|
let JwtGuard = class JwtGuard {
|
|
19
18
|
constructor(reflector) {
|
|
20
19
|
this.reflector = reflector;
|
|
@@ -37,8 +36,7 @@ let JwtGuard = class JwtGuard {
|
|
|
37
36
|
throw new common_1.UnauthorizedException('ConfigurationError', 'JWT_ACCESS_TOKEN_SECRET is not configured');
|
|
38
37
|
}
|
|
39
38
|
const user = jsonwebtoken.verify(token, secret);
|
|
40
|
-
|
|
41
|
-
request.user = parsedUser;
|
|
39
|
+
request.user = user;
|
|
42
40
|
return true;
|
|
43
41
|
}
|
|
44
42
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt.guard.js","sourceRoot":"","sources":["../../src/guards/jwt.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAKwB;AAExB,uCAAyC;AACzC,uFAAmF;AACnF,6CAA4C;
|
|
1
|
+
{"version":3,"file":"jwt.guard.js","sourceRoot":"","sources":["../../src/guards/jwt.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAKwB;AAExB,uCAAyC;AACzC,uFAAmF;AACnF,6CAA4C;AAGrC,IAAM,QAAQ,GAAd,MAAM,QAAQ;IACnB,YACmB,SAAoB;QAApB,cAAS,GAAT,SAAS,CAAW;IACnC,CAAC;IAEL,KAAK,CAAC,WAAW,CAAC,OAAyB;;QACzC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;YACpD,MAAM,kBAAkB,GAAG,MAAA,IAAI,CAAC,SAAS,0CAAE,iBAAiB,CAC1D,oDAAwB,EACxB,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAC3C,CAAC;YACF,IAAI,kBAAkB,EAAE,CAAC;gBACvB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;gBAC3B,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,KAAK,GAAG,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;YACnD,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,IAAI,8BAAqB,CAC7B,mBAAmB,EACnB,sBAAsB,CACvB,CAAC;YACJ,CAAC;YAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC;YACnD,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,8BAAqB,CAC7B,oBAAoB,EACpB,2CAA2C,CAC5C,CAAC;YACJ,CAAC;YAED,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAEhD,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAEO,sBAAsB,CAAC,OAAgB;;QAC7C,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,MAAA,MAAA,OAAO,CAAC,OAAO,CAAC,aAAa,0CAAE,KAAK,CAAC,GAAG,CAAC,mCAAI,EAAE,CAAC;QACtE,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/C,CAAC;CACF,CAAA;AA9CY,4BAAQ;mBAAR,QAAQ;IADpB,IAAA,mBAAU,GAAE;qCAGmB,gBAAS;GAF5B,QAAQ,CA8CpB"}
|
|
@@ -12,7 +12,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.OptionalJwtGuard = void 0;
|
|
13
13
|
const common_1 = require("@nestjs/common");
|
|
14
14
|
const auth_helper_1 = require("../helper/auth.helper");
|
|
15
|
-
const extract_user_1 = require("../utils/extract-user");
|
|
16
15
|
let OptionalJwtGuard = class OptionalJwtGuard {
|
|
17
16
|
constructor(authHelper) {
|
|
18
17
|
this.authHelper = authHelper;
|
|
@@ -32,8 +31,7 @@ let OptionalJwtGuard = class OptionalJwtGuard {
|
|
|
32
31
|
return true;
|
|
33
32
|
}
|
|
34
33
|
const user = await this.authHelper.verify(token, secret);
|
|
35
|
-
|
|
36
|
-
request.user = parsedUser;
|
|
34
|
+
request.user = user;
|
|
37
35
|
return true;
|
|
38
36
|
}
|
|
39
37
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"optional-jwt.guard.js","sourceRoot":"","sources":["../../src/guards/optional-jwt.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA2E;AAE3E,uDAAmD;
|
|
1
|
+
{"version":3,"file":"optional-jwt.guard.js","sourceRoot":"","sources":["../../src/guards/optional-jwt.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA2E;AAE3E,uDAAmD;AAG5C,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;IAC3B,YAA6B,UAAsB;QAAtB,eAAU,GAAV,UAAU,CAAY;IAAG,CAAC;IAEvD,KAAK,CAAC,WAAW,CAAC,OAAyB;QACzC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;YACpD,MAAM,KAAK,GAAG,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;YACnD,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC;YACnD,IAAI,CAAC,MAAM,EAAE,CAAC;gBAGZ,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;oBAC1C,OAAO,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;gBAC5D,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAEzD,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAEO,sBAAsB,CAAC,OAAgB;;QAC7C,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,MAAA,MAAA,OAAO,CAAC,OAAO,CAAC,aAAa,0CAAE,KAAK,CAAC,GAAG,CAAC,mCAAI,EAAE,CAAC;QACtE,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/C,CAAC;CACF,CAAA;AAlCY,4CAAgB;2BAAhB,gBAAgB;IAD5B,IAAA,mBAAU,GAAE;qCAE8B,wBAAU;GADxC,gBAAgB,CAkC5B"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -14,7 +14,9 @@ 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
|
-
|
|
17
|
+
exports.AuthorizationModule = void 0;
|
|
18
|
+
var authorization_module_1 = require("./authorization.module");
|
|
19
|
+
Object.defineProperty(exports, "AuthorizationModule", { enumerable: true, get: function () { return authorization_module_1.AuthorizationModule; } });
|
|
18
20
|
__exportStar(require("./decorators/allow-anonymous.decorator"), exports);
|
|
19
21
|
__exportStar(require("./decorators/current-user.decorator"), exports);
|
|
20
22
|
__exportStar(require("./guards/jwt.guard"), exports);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,+DAA6D;AAApD,2HAAA,mBAAmB,OAAA;AAC5B,yEAAuD;AACvD,sEAAoD;AACpD,qDAAmC;AACnC,6DAA2C;AAC3C,uDAAqC;AACrC,6DAA2C;AAC3C,wEAAsD;AACtD,yDAAuC;AACvC,wDAAsC;AACtC,8DAA4C;AAC5C,wEAAsD;AACtD,0DAAwC;AACxC,sDAAoC;AACpC,oDAAkC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zola_do/authorization",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"description": "JWT auth, guards, strategies for NestJS",
|
|
5
5
|
"author": "zolaDO",
|
|
6
6
|
"license": "ISC",
|
|
@@ -15,7 +15,10 @@
|
|
|
15
15
|
"default": "./dist/index.js"
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
|
-
"files": [
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"README.md"
|
|
21
|
+
],
|
|
19
22
|
"scripts": {
|
|
20
23
|
"build": "rimraf dist && tsc",
|
|
21
24
|
"prepublishOnly": "npm run build"
|
|
@@ -33,10 +36,12 @@
|
|
|
33
36
|
"rxjs": "^7.0.0 || ^8.0.0"
|
|
34
37
|
},
|
|
35
38
|
"peerDependenciesMeta": {
|
|
36
|
-
"@nestjs/throttler": {
|
|
39
|
+
"@nestjs/throttler": {
|
|
40
|
+
"optional": true
|
|
41
|
+
}
|
|
37
42
|
},
|
|
38
43
|
"dependencies": {
|
|
39
|
-
"@zola_do/core": "
|
|
44
|
+
"@zola_do/core": "^0.1.9",
|
|
40
45
|
"bcrypt": "^6.0.0",
|
|
41
46
|
"jsonwebtoken": "^9.0.2"
|
|
42
47
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const extractUser: (request: any, user: any) => any;
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
-
var t = {};
|
|
4
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
-
t[p] = s[p];
|
|
6
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
-
t[p[i]] = s[p[i]];
|
|
10
|
-
}
|
|
11
|
-
return t;
|
|
12
|
-
};
|
|
13
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.extractUser = void 0;
|
|
15
|
-
const extractUser = (request, user) => {
|
|
16
|
-
const { organizations } = user, rest = __rest(user, ["organizations"]);
|
|
17
|
-
let parsedUser = rest;
|
|
18
|
-
if (organizations && organizations.length > 0) {
|
|
19
|
-
let organization;
|
|
20
|
-
if (request.headers && request.headers['x-organization-id']) {
|
|
21
|
-
organization = organizations.find((x) => x.organization.id == request.headers['x-organization-id']);
|
|
22
|
-
}
|
|
23
|
-
else {
|
|
24
|
-
organization = organizations[0];
|
|
25
|
-
}
|
|
26
|
-
parsedUser = Object.assign(Object.assign(Object.assign({}, parsedUser), { fullName: parsedUser.firstName + ' ' + parsedUser.lastName }), organization);
|
|
27
|
-
}
|
|
28
|
-
return parsedUser;
|
|
29
|
-
};
|
|
30
|
-
exports.extractUser = extractUser;
|
|
31
|
-
//# sourceMappingURL=extract-user.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"extract-user.js","sourceRoot":"","sources":["../../src/utils/extract-user.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAO,MAAM,WAAW,GAAG,CAAC,OAAY,EAAE,IAAS,EAAE,EAAE;IACrD,MAAM,EAAE,aAAa,KAAc,IAAI,EAAb,IAAI,UAAK,IAAI,EAAjC,iBAA0B,CAAO,CAAC;IACxC,IAAI,UAAU,GAAQ,IAAI,CAAC;IAC3B,IAAI,aAAa,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,IAAI,YAAiB,CAAC;QAEtB,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,CAAC;YAC5D,YAAY,GAAG,aAAa,CAAC,IAAI,CAC/B,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,IAAI,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,CACtE,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,YAAY,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;QAClC,CAAC;QAED,UAAU,iDACL,UAAU,KACb,QAAQ,EAAE,UAAU,CAAC,SAAS,GAAG,GAAG,GAAG,UAAU,CAAC,QAAQ,KACvD,YAAY,CAChB,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC;AArBW,QAAA,WAAW,eAqBtB"}
|