@easyweb/authentication 1.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -9
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/middleware/authenticate.d.ts +37 -2
- package/dist/middleware/authenticate.d.ts.map +1 -1
- package/dist/middleware/authenticate.js +79 -15
- package/dist/middleware/authenticate.js.map +1 -1
- package/package.json +15 -6
- package/dist/errors/bad-request-error.d.ts +0 -10
- package/dist/errors/bad-request-error.d.ts.map +0 -1
- package/dist/errors/bad-request-error.js +0 -16
- package/dist/errors/bad-request-error.js.map +0 -1
- package/dist/errors/custom-error.d.ts +0 -9
- package/dist/errors/custom-error.d.ts.map +0 -1
- package/dist/errors/custom-error.js +0 -11
- package/dist/errors/custom-error.js.map +0 -1
- package/dist/errors/database-connection-error.d.ts +0 -10
- package/dist/errors/database-connection-error.d.ts.map +0 -1
- package/dist/errors/database-connection-error.js +0 -17
- package/dist/errors/database-connection-error.js.map +0 -1
- package/dist/errors/index.d.ts +0 -6
- package/dist/errors/index.d.ts.map +0 -1
- package/dist/errors/index.js +0 -22
- package/dist/errors/index.js.map +0 -1
- package/dist/errors/not-authorized-error.d.ts +0 -9
- package/dist/errors/not-authorized-error.d.ts.map +0 -1
- package/dist/errors/not-authorized-error.js +0 -16
- package/dist/errors/not-authorized-error.js.map +0 -1
- package/dist/errors/not-found-error.d.ts +0 -9
- package/dist/errors/not-found-error.d.ts.map +0 -1
- package/dist/errors/not-found-error.js +0 -16
- package/dist/errors/not-found-error.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,10 +1,56 @@
|
|
|
1
1
|
# @easyweb/authentication
|
|
2
2
|
|
|
3
3
|
Shared authentication primitives for Easyweb microservices — stateless JWT middleware,
|
|
4
|
-
request-context middleware, and the
|
|
4
|
+
request-context middleware, and the token verification helpers services build on.
|
|
5
5
|
|
|
6
|
-
Companion to [`@easyweb/
|
|
7
|
-
|
|
6
|
+
Companion to [`@easyweb/events`](https://www.npmjs.com/package/@easyweb/events) for
|
|
7
|
+
messaging, and [`@easyweb/errors`](https://www.npmjs.com/package/@easyweb/errors) for
|
|
8
|
+
the HTTP error taxonomy.
|
|
9
|
+
|
|
10
|
+
## 2.1.0 — `SUPER_ADMIN` now satisfies `authorize(["ADMIN"])`
|
|
11
|
+
|
|
12
|
+
`authorize()` was an exact string match. Every admin route in the platform is written
|
|
13
|
+
`authorize(["ADMIN"])`, and auth-service's `admin-seed.ts` grants the bootstrap operator
|
|
14
|
+
`SUPER_ADMIN` by default — so the seeded account could not call a single admin route on
|
|
15
|
+
the platform.
|
|
16
|
+
|
|
17
|
+
`SUPER_ADMIN` now implies `ADMIN`. Nothing else implies anything: `ADMIN` deliberately
|
|
18
|
+
does **not** imply `USER`, because that edge would silently widen every future customer
|
|
19
|
+
route to staff.
|
|
20
|
+
|
|
21
|
+
**Additive, and widening only.** A service still on 2.0.0 behaves exactly as it did —
|
|
22
|
+
`SUPER_ADMIN` simply stays locked out there — so this needs no coordinated deploy. Since
|
|
23
|
+
every service declares `^2.0.0` but installs from a lockfile, pick it up with:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm i @easyweb/authentication@^2.1.0
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The new `effectiveRoles(roles)` export does the same expansion for a service with its own
|
|
30
|
+
guard (auth-service's DB-backed middleware, in particular).
|
|
31
|
+
|
|
32
|
+
The status is unchanged: `authorize()` still throws `NotAuthorizedError`, which is **401**
|
|
33
|
+
even for a signed-in caller with the wrong role. Every service's http suite pins that.
|
|
34
|
+
A caller needing to tell "not signed in" from "not permitted" must check the role itself.
|
|
35
|
+
|
|
36
|
+
## Upgrading to 2.0.0 — BREAKING
|
|
37
|
+
|
|
38
|
+
The error classes moved to `@easyweb/errors`. Error handling is cross-cutting and has
|
|
39
|
+
nothing to do with JWTs; a service needing `ConflictError` should not have to depend on
|
|
40
|
+
an auth package for it.
|
|
41
|
+
|
|
42
|
+
```diff
|
|
43
|
+
- import { NotAuthorizedError } from "@easyweb/authentication";
|
|
44
|
+
+ import { NotAuthorizedError } from "@easyweb/errors";
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`@easyweb/errors` is a **peerDependency** — install it alongside this package. Do not let
|
|
48
|
+
it end up nested under `node_modules/@easyweb/authentication/`: two copies of
|
|
49
|
+
`CustomError` means `instanceof` fails across the boundary and the error handler answers
|
|
50
|
+
500 for everything, with no type error to warn you. Verify with `npm ls @easyweb/errors`.
|
|
51
|
+
|
|
52
|
+
Also new in 2.0.0: `extractToken` and `isValidAccessPayload` are exported, for services
|
|
53
|
+
that keep their own DB-backed middleware (see below) and would otherwise copy them.
|
|
8
54
|
|
|
9
55
|
## Install
|
|
10
56
|
|
|
@@ -23,11 +69,7 @@ package never has to reach into a service's `config` module.
|
|
|
23
69
|
```ts
|
|
24
70
|
import express from "express";
|
|
25
71
|
import cookieParser from "cookie-parser";
|
|
26
|
-
import {
|
|
27
|
-
createAuthMiddleware,
|
|
28
|
-
requestContext,
|
|
29
|
-
NotAuthorizedError,
|
|
30
|
-
} from "@easyweb/authentication";
|
|
72
|
+
import { createAuthMiddleware, requestContext } from "@easyweb/authentication";
|
|
31
73
|
import config from "./config";
|
|
32
74
|
|
|
33
75
|
const app = express();
|
|
@@ -83,9 +125,17 @@ would deny every request.
|
|
|
83
125
|
| `requestContext` | propagates / generates `x-request-id` |
|
|
84
126
|
| `createJwtVerifier(config)` | `(token) => JwtAccessPayload`, throws on invalid |
|
|
85
127
|
| `createJwtSigner(config)` | `(claims) => string` |
|
|
86
|
-
| `
|
|
128
|
+
| `extractToken(req)` | Bearer header, then the `accessToken` cookie |
|
|
129
|
+
| `isValidAccessPayload(decoded)` | type guard: is this a well-formed *access* token? |
|
|
130
|
+
| `effectiveRoles(roles)` | the roles held, expanded through the implication map (2.1.0) |
|
|
131
|
+
| `effectiveRoles(roles)` | the roles held, expanded through the implication map (2.1.0) |
|
|
87
132
|
| `JwtAccessPayload`, `JwtAccessClaims`, `JwtVerifyConfig`, `JwtSignConfig` | types |
|
|
88
133
|
|
|
134
|
+
`extractToken` and `isValidAccessPayload` exist for services that must keep a DB-backed
|
|
135
|
+
middleware. They were previously private, so auth-service copied them — and the copies
|
|
136
|
+
drifted. If you need the same checks with different error messages, import these rather
|
|
137
|
+
than reimplementing them.
|
|
138
|
+
|
|
89
139
|
Importing the package also augments `Express.Request` with `user`, `auth`, and
|
|
90
140
|
`requestId`. Remove any local copy of that `declare global` block or TypeScript will
|
|
91
141
|
report duplicate members.
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,6 @@ 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("./errors"), exports);
|
|
18
17
|
__exportStar(require("./jwt"), exports);
|
|
19
18
|
__exportStar(require("./middleware"), exports);
|
|
20
19
|
__exportStar(require("./types/jwt"), exports);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,wCAAsB;AACtB,+CAA6B;AAC7B,8CAA4B"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { NextFunction, Request, Response } from "express";
|
|
2
|
-
import type { JwtVerifyConfig } from "../types/jwt";
|
|
2
|
+
import type { JwtAccessPayload, JwtVerifyConfig } from "../types/jwt";
|
|
3
3
|
/**
|
|
4
4
|
* Stateless verification. Unlike auth-service's own middleware there is no
|
|
5
5
|
* database round trip: the access token is verified against the shared secret
|
|
@@ -35,12 +35,47 @@ declare global {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Bearer header first, then the `accessToken` cookie auth-service sets.
|
|
40
|
+
*
|
|
41
|
+
* Exported because auth-service keeps its own DB-backed middleware (see the
|
|
42
|
+
* trade-off above) and would otherwise copy this verbatim — which it did, and
|
|
43
|
+
* the copy drifted.
|
|
44
|
+
*/
|
|
45
|
+
export declare function extractToken(req: Request): string | null;
|
|
46
|
+
/**
|
|
47
|
+
* Is this a well-formed *access* token payload?
|
|
48
|
+
*
|
|
49
|
+
* A valid signature only proves we minted the token, not that we minted it for
|
|
50
|
+
* this purpose — a refresh token is signed with the same secret. Without the
|
|
51
|
+
* `type` check a refresh token would authenticate a request.
|
|
52
|
+
*
|
|
53
|
+
* `iat` is required because DB-backed consumers compare it against
|
|
54
|
+
* `passwordChangedAt` to invalidate tokens issued before a password change.
|
|
55
|
+
*
|
|
56
|
+
* Exported alongside `extractToken` for auth-service's own middleware, which
|
|
57
|
+
* needs the same guard but reports failure with its own message.
|
|
58
|
+
*/
|
|
59
|
+
export declare function isValidAccessPayload(decoded: JwtAccessPayload | null | undefined): decoded is JwtAccessPayload;
|
|
60
|
+
/**
|
|
61
|
+
* The roles a caller holds, plus everything those roles stand in for.
|
|
62
|
+
*
|
|
63
|
+
* Exported for tests and for any service that needs the same expansion outside
|
|
64
|
+
* a middleware — auth-service's own DB-backed guard, in particular, which does
|
|
65
|
+
* not go through `createAuthMiddleware`.
|
|
66
|
+
*/
|
|
67
|
+
export declare function effectiveRoles(roles: readonly string[]): Set<string>;
|
|
38
68
|
export type AuthMiddleware = {
|
|
39
69
|
/** Rejects with 401 unless the request carries a valid access token. */
|
|
40
70
|
authenticate: (req: Request, res: Response, next: NextFunction) => void;
|
|
41
71
|
/** Populates `req.user` when a valid token is present; never rejects. */
|
|
42
72
|
optionalAuth: (req: Request, res: Response, next: NextFunction) => void;
|
|
43
|
-
/**
|
|
73
|
+
/**
|
|
74
|
+
* Role guard. Use after `authenticate`.
|
|
75
|
+
*
|
|
76
|
+
* Matches against the caller's roles expanded through `ROLE_IMPLIES`, so
|
|
77
|
+
* `authorize(["ADMIN"])` admits `SUPER_ADMIN`.
|
|
78
|
+
*/
|
|
44
79
|
authorize: (allowedRoles: string[]) => (req: Request, res: Response, next: NextFunction) => void;
|
|
45
80
|
};
|
|
46
81
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authenticate.d.ts","sourceRoot":"","sources":["../../src/middleware/authenticate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAG/D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"authenticate.d.ts","sourceRoot":"","sources":["../../src/middleware/authenticate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAG/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEtE;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,IAAI,CAAC,EAAE;gBACL,EAAE,EAAE,MAAM,CAAC;gBACX,KAAK,EAAE,MAAM,CAAC;gBACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;gBACxB,KAAK,EAAE,MAAM,EAAE,CAAC;gBAChB,WAAW,EAAE,MAAM,EAAE,CAAC;aACvB,CAAC;YACF,IAAI,CAAC,EAAE;gBACL,MAAM,EAAE,MAAM,CAAC;gBACf,SAAS,CAAC,EAAE,MAAM,CAAC;aACpB,CAAC;SACH;KACF;CACF;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAYxD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,gBAAgB,GAAG,IAAI,GAAG,SAAS,GAC3C,OAAO,IAAI,gBAAgB,CAQ7B;AAsBD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAUpE;AAqBD,MAAM,MAAM,cAAc,GAAG;IAC3B,wEAAwE;IACxE,YAAY,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IACxE,yEAAyE;IACzE,YAAY,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IACxE;;;;;OAKG;IACH,SAAS,EAAE,CACT,YAAY,EAAE,MAAM,EAAE,KACnB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;CAChE,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,GAAG,cAAc,CA6E5E"}
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractToken = extractToken;
|
|
4
|
+
exports.isValidAccessPayload = isValidAccessPayload;
|
|
5
|
+
exports.effectiveRoles = effectiveRoles;
|
|
3
6
|
exports.createAuthMiddleware = createAuthMiddleware;
|
|
4
7
|
const verify_1 = require("../jwt/verify");
|
|
5
|
-
const
|
|
6
|
-
/**
|
|
8
|
+
const errors_1 = require("@easyweb/errors");
|
|
9
|
+
/**
|
|
10
|
+
* Bearer header first, then the `accessToken` cookie auth-service sets.
|
|
11
|
+
*
|
|
12
|
+
* Exported because auth-service keeps its own DB-backed middleware (see the
|
|
13
|
+
* trade-off above) and would otherwise copy this verbatim — which it did, and
|
|
14
|
+
* the copy drifted.
|
|
15
|
+
*/
|
|
7
16
|
function extractToken(req) {
|
|
8
17
|
const authHeader = req.headers.authorization;
|
|
9
18
|
if (authHeader && authHeader.startsWith("Bearer ")) {
|
|
@@ -14,6 +23,61 @@ function extractToken(req) {
|
|
|
14
23
|
}
|
|
15
24
|
return null;
|
|
16
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Is this a well-formed *access* token payload?
|
|
28
|
+
*
|
|
29
|
+
* A valid signature only proves we minted the token, not that we minted it for
|
|
30
|
+
* this purpose — a refresh token is signed with the same secret. Without the
|
|
31
|
+
* `type` check a refresh token would authenticate a request.
|
|
32
|
+
*
|
|
33
|
+
* `iat` is required because DB-backed consumers compare it against
|
|
34
|
+
* `passwordChangedAt` to invalidate tokens issued before a password change.
|
|
35
|
+
*
|
|
36
|
+
* Exported alongside `extractToken` for auth-service's own middleware, which
|
|
37
|
+
* needs the same guard but reports failure with its own message.
|
|
38
|
+
*/
|
|
39
|
+
function isValidAccessPayload(decoded) {
|
|
40
|
+
return Boolean(decoded &&
|
|
41
|
+
decoded.type === "access" &&
|
|
42
|
+
decoded.sub &&
|
|
43
|
+
decoded.sessionId &&
|
|
44
|
+
decoded.iat);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Which roles a role stands in for.
|
|
48
|
+
*
|
|
49
|
+
* `authorize()` was an exact string match, and every admin route in the
|
|
50
|
+
* platform is written `authorize(["ADMIN"])` — so `SUPER_ADMIN`, which
|
|
51
|
+
* auth-service's `admin-seed.ts` grants the bootstrap operator by default,
|
|
52
|
+
* could not call a single one of them. The seeded account was locked out of
|
|
53
|
+
* the surface it exists to reach.
|
|
54
|
+
*
|
|
55
|
+
* Deliberately ONE entry. `ADMIN` does not imply `USER`: nothing calls
|
|
56
|
+
* `authorize(["USER"])` today, and adding that edge would silently widen every
|
|
57
|
+
* future customer route to staff — the kind of grant nobody re-reads.
|
|
58
|
+
*
|
|
59
|
+
* Widening only, which is what makes the 2.1.0 release safe to roll out one
|
|
60
|
+
* service at a time: a service still on 2.0.0 keeps behaving exactly as it did.
|
|
61
|
+
*/
|
|
62
|
+
const ROLE_IMPLIES = {
|
|
63
|
+
SUPER_ADMIN: ["ADMIN"],
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* The roles a caller holds, plus everything those roles stand in for.
|
|
67
|
+
*
|
|
68
|
+
* Exported for tests and for any service that needs the same expansion outside
|
|
69
|
+
* a middleware — auth-service's own DB-backed guard, in particular, which does
|
|
70
|
+
* not go through `createAuthMiddleware`.
|
|
71
|
+
*/
|
|
72
|
+
function effectiveRoles(roles) {
|
|
73
|
+
const effective = new Set(roles);
|
|
74
|
+
for (const role of roles) {
|
|
75
|
+
for (const implied of ROLE_IMPLIES[role] ?? []) {
|
|
76
|
+
effective.add(implied);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return effective;
|
|
80
|
+
}
|
|
17
81
|
function attachClaims(req, decoded) {
|
|
18
82
|
req.user = {
|
|
19
83
|
id: decoded.sub,
|
|
@@ -51,23 +115,16 @@ function createAuthMiddleware(config) {
|
|
|
51
115
|
catch {
|
|
52
116
|
return null;
|
|
53
117
|
}
|
|
54
|
-
|
|
55
|
-
decoded.type !== "access" ||
|
|
56
|
-
!decoded.sub ||
|
|
57
|
-
!decoded.sessionId ||
|
|
58
|
-
!decoded.iat) {
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
return decoded;
|
|
118
|
+
return isValidAccessPayload(decoded) ? decoded : null;
|
|
62
119
|
}
|
|
63
120
|
const authenticate = (req, _res, next) => {
|
|
64
121
|
const token = extractToken(req);
|
|
65
122
|
if (!token) {
|
|
66
|
-
throw new
|
|
123
|
+
throw new errors_1.NotAuthorizedError();
|
|
67
124
|
}
|
|
68
125
|
const decoded = decodeAccessToken(token);
|
|
69
126
|
if (!decoded) {
|
|
70
|
-
throw new
|
|
127
|
+
throw new errors_1.NotAuthorizedError();
|
|
71
128
|
}
|
|
72
129
|
attachClaims(req, decoded);
|
|
73
130
|
next();
|
|
@@ -81,11 +138,18 @@ function createAuthMiddleware(config) {
|
|
|
81
138
|
}
|
|
82
139
|
next();
|
|
83
140
|
};
|
|
141
|
+
/**
|
|
142
|
+
* NOTE the status: `NotAuthorizedError` is 401, so a signed-in caller with
|
|
143
|
+
* the wrong role gets the same answer as an anonymous one. That is a quirk
|
|
144
|
+
* of this package rather than a decision, and every service's http tests pin
|
|
145
|
+
* it as-is — changing it here would turn eight suites red at once. A caller
|
|
146
|
+
* that needs to tell the two apart should check the role itself.
|
|
147
|
+
*/
|
|
84
148
|
const authorize = (allowedRoles) => {
|
|
85
149
|
return (req, _res, next) => {
|
|
86
|
-
const
|
|
87
|
-
if (!
|
|
88
|
-
throw new
|
|
150
|
+
const held = effectiveRoles(req.user?.roles ?? []);
|
|
151
|
+
if (!allowedRoles.some((r) => held.has(r))) {
|
|
152
|
+
throw new errors_1.NotAuthorizedError("Insufficient role");
|
|
89
153
|
}
|
|
90
154
|
next();
|
|
91
155
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authenticate.js","sourceRoot":"","sources":["../../src/middleware/authenticate.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"authenticate.js","sourceRoot":"","sources":["../../src/middleware/authenticate.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@easyweb/authentication",
|
|
3
|
-
"version": "1.0
|
|
4
|
-
"description": "Shared authentication primitives for Easyweb microservices: stateless JWT middleware, request context, and
|
|
3
|
+
"version": "2.1.0",
|
|
4
|
+
"description": "Shared authentication primitives for Easyweb microservices: stateless JWT middleware, request context, and token verification helpers",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"exports": {
|
|
@@ -16,18 +16,20 @@
|
|
|
16
16
|
"README.md"
|
|
17
17
|
],
|
|
18
18
|
"scripts": {
|
|
19
|
-
"build": "tsc",
|
|
19
|
+
"build": "npm run clean && tsc",
|
|
20
20
|
"build:watch": "tsc --watch",
|
|
21
21
|
"prepublishOnly": "npm run build",
|
|
22
|
-
"clean": "rimraf dist"
|
|
22
|
+
"clean": "rimraf dist",
|
|
23
|
+
"test": "jest",
|
|
24
|
+
"typecheck": "tsc --noEmit",
|
|
25
|
+
"typecheck:test": "tsc -p tsconfig.test.json --noEmit"
|
|
23
26
|
},
|
|
24
27
|
"keywords": [
|
|
25
28
|
"microservices",
|
|
26
29
|
"express",
|
|
27
30
|
"middleware",
|
|
28
31
|
"authentication",
|
|
29
|
-
"jwt"
|
|
30
|
-
"error-handling"
|
|
32
|
+
"jwt"
|
|
31
33
|
],
|
|
32
34
|
"author": "Easy Web Team",
|
|
33
35
|
"license": "MIT",
|
|
@@ -37,13 +39,20 @@
|
|
|
37
39
|
"directory": "common-auth"
|
|
38
40
|
},
|
|
39
41
|
"peerDependencies": {
|
|
42
|
+
"@easyweb/errors": "^1.0.0",
|
|
40
43
|
"express": "^5.0.0",
|
|
41
44
|
"jsonwebtoken": "^9.0.0"
|
|
42
45
|
},
|
|
43
46
|
"devDependencies": {
|
|
47
|
+
"@easyweb/errors": "^1.0.0",
|
|
48
|
+
"@swc/core": "^1.15.47",
|
|
49
|
+
"@swc/jest": "^0.2.39",
|
|
44
50
|
"@types/express": "^5.0.6",
|
|
51
|
+
"@types/jest": "^30.0.0",
|
|
45
52
|
"@types/jsonwebtoken": "^9.0.10",
|
|
46
53
|
"@types/node": "^26.0.1",
|
|
54
|
+
"jest": "^30.4.2",
|
|
55
|
+
"jsonwebtoken": "^9.0.3",
|
|
47
56
|
"rimraf": "^6.1.3",
|
|
48
57
|
"typescript": "^6.0.3"
|
|
49
58
|
},
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { CustomError } from "./custom-error";
|
|
2
|
-
declare class BadRequestError extends CustomError {
|
|
3
|
-
statusCode: number;
|
|
4
|
-
constructor(message: string);
|
|
5
|
-
serializeErrors(): {
|
|
6
|
-
message: string;
|
|
7
|
-
}[];
|
|
8
|
-
}
|
|
9
|
-
export { BadRequestError };
|
|
10
|
-
//# sourceMappingURL=bad-request-error.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bad-request-error.d.ts","sourceRoot":"","sources":["../../src/errors/bad-request-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,cAAM,eAAgB,SAAQ,WAAW;IACvC,UAAU,SAAO;gBAEL,OAAO,EAAE,MAAM;IAK3B,eAAe;;;CAGhB;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BadRequestError = void 0;
|
|
4
|
-
const custom_error_1 = require("./custom-error");
|
|
5
|
-
class BadRequestError extends custom_error_1.CustomError {
|
|
6
|
-
constructor(message) {
|
|
7
|
-
super(message);
|
|
8
|
-
this.statusCode = 400;
|
|
9
|
-
Object.setPrototypeOf(this, BadRequestError.prototype);
|
|
10
|
-
}
|
|
11
|
-
serializeErrors() {
|
|
12
|
-
return [{ message: this.message }];
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
exports.BadRequestError = BadRequestError;
|
|
16
|
-
//# sourceMappingURL=bad-request-error.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bad-request-error.js","sourceRoot":"","sources":["../../src/errors/bad-request-error.ts"],"names":[],"mappings":";;;AAAA,iDAA6C;AAE7C,MAAM,eAAgB,SAAQ,0BAAW;IAGvC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QAHjB,eAAU,GAAG,GAAG,CAAC;QAIf,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC;IACzD,CAAC;IAED,eAAe;QACb,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IACrC,CAAC;CACF;AAEQ,0CAAe"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"custom-error.d.ts","sourceRoot":"","sources":["../../src/errors/custom-error.ts"],"names":[],"mappings":"AAAA,8BAAsB,WAAY,SAAQ,KAAK;IAC7C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;gBAEhB,OAAO,EAAE,MAAM;IAK3B,QAAQ,CAAC,eAAe,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE;CAClE"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CustomError = void 0;
|
|
4
|
-
class CustomError extends Error {
|
|
5
|
-
constructor(message) {
|
|
6
|
-
super(message);
|
|
7
|
-
Object.setPrototypeOf(this, CustomError.prototype);
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
exports.CustomError = CustomError;
|
|
11
|
-
//# sourceMappingURL=custom-error.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"custom-error.js","sourceRoot":"","sources":["../../src/errors/custom-error.ts"],"names":[],"mappings":";;;AAAA,MAAsB,WAAY,SAAQ,KAAK;IAG7C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACrD,CAAC;CAGF;AATD,kCASC"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { CustomError } from "./custom-error";
|
|
2
|
-
export declare class DatabaseConnectionError extends CustomError {
|
|
3
|
-
statusCode: number;
|
|
4
|
-
reason: string;
|
|
5
|
-
constructor();
|
|
6
|
-
serializeErrors(): {
|
|
7
|
-
message: string;
|
|
8
|
-
}[];
|
|
9
|
-
}
|
|
10
|
-
//# sourceMappingURL=database-connection-error.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"database-connection-error.d.ts","sourceRoot":"","sources":["../../src/errors/database-connection-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,qBAAa,uBAAwB,SAAQ,WAAW;IACtD,UAAU,SAAO;IACjB,MAAM,SAAkC;;IAQxC,eAAe;;;CAGhB"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DatabaseConnectionError = void 0;
|
|
4
|
-
const custom_error_1 = require("./custom-error");
|
|
5
|
-
class DatabaseConnectionError extends custom_error_1.CustomError {
|
|
6
|
-
constructor() {
|
|
7
|
-
super("Error connecting to database");
|
|
8
|
-
this.statusCode = 500;
|
|
9
|
-
this.reason = "Error connecting to database";
|
|
10
|
-
Object.setPrototypeOf(this, DatabaseConnectionError.prototype);
|
|
11
|
-
}
|
|
12
|
-
serializeErrors() {
|
|
13
|
-
return [{ message: this.reason }];
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
exports.DatabaseConnectionError = DatabaseConnectionError;
|
|
17
|
-
//# sourceMappingURL=database-connection-error.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"database-connection-error.js","sourceRoot":"","sources":["../../src/errors/database-connection-error.ts"],"names":[],"mappings":";;;AAAA,iDAA6C;AAE7C,MAAa,uBAAwB,SAAQ,0BAAW;IAItD;QACE,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAJxC,eAAU,GAAG,GAAG,CAAC;QACjB,WAAM,GAAG,8BAA8B,CAAC;QAKtC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,uBAAuB,CAAC,SAAS,CAAC,CAAC;IACjE,CAAC;IAED,eAAe;QACb,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACpC,CAAC;CACF;AAbD,0DAaC"}
|
package/dist/errors/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,6BAA6B,CAAC"}
|
package/dist/errors/index.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
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("./custom-error"), exports);
|
|
18
|
-
__exportStar(require("./bad-request-error"), exports);
|
|
19
|
-
__exportStar(require("./not-authorized-error"), exports);
|
|
20
|
-
__exportStar(require("./not-found-error"), exports);
|
|
21
|
-
__exportStar(require("./database-connection-error"), exports);
|
|
22
|
-
//# sourceMappingURL=index.js.map
|
package/dist/errors/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iDAA+B;AAC/B,sDAAoC;AACpC,yDAAuC;AACvC,oDAAkC;AAClC,8DAA4C"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { CustomError } from "./custom-error";
|
|
2
|
-
export declare class NotAuthorizedError extends CustomError {
|
|
3
|
-
statusCode: number;
|
|
4
|
-
constructor(message?: string);
|
|
5
|
-
serializeErrors(): {
|
|
6
|
-
message: string;
|
|
7
|
-
}[];
|
|
8
|
-
}
|
|
9
|
-
//# sourceMappingURL=not-authorized-error.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"not-authorized-error.d.ts","sourceRoot":"","sources":["../../src/errors/not-authorized-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,qBAAa,kBAAmB,SAAQ,WAAW;IACjD,UAAU,SAAO;gBAEL,OAAO,GAAE,MAAyB;IAK9C,eAAe;;;CAGhB"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.NotAuthorizedError = void 0;
|
|
4
|
-
const custom_error_1 = require("./custom-error");
|
|
5
|
-
class NotAuthorizedError extends custom_error_1.CustomError {
|
|
6
|
-
constructor(message = "Not authorized") {
|
|
7
|
-
super(message);
|
|
8
|
-
this.statusCode = 401;
|
|
9
|
-
Object.setPrototypeOf(this, NotAuthorizedError.prototype);
|
|
10
|
-
}
|
|
11
|
-
serializeErrors() {
|
|
12
|
-
return [{ message: this.message }];
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
exports.NotAuthorizedError = NotAuthorizedError;
|
|
16
|
-
//# sourceMappingURL=not-authorized-error.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"not-authorized-error.js","sourceRoot":"","sources":["../../src/errors/not-authorized-error.ts"],"names":[],"mappings":";;;AAAA,iDAA6C;AAE7C,MAAa,kBAAmB,SAAQ,0BAAW;IAGjD,YAAY,UAAkB,gBAAgB;QAC5C,KAAK,CAAC,OAAO,CAAC,CAAC;QAHjB,eAAU,GAAG,GAAG,CAAC;QAIf,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC5D,CAAC;IAED,eAAe;QACb,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IACrC,CAAC;CACF;AAXD,gDAWC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"not-found-error.d.ts","sourceRoot":"","sources":["../../src/errors/not-found-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,qBAAa,aAAc,SAAQ,WAAW;IAC5C,UAAU,SAAO;;IAOjB,eAAe;;;CAGhB"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.NotFoundError = void 0;
|
|
4
|
-
const custom_error_1 = require("./custom-error");
|
|
5
|
-
class NotFoundError extends custom_error_1.CustomError {
|
|
6
|
-
constructor() {
|
|
7
|
-
super("Route not found");
|
|
8
|
-
this.statusCode = 404;
|
|
9
|
-
Object.setPrototypeOf(this, NotFoundError.prototype);
|
|
10
|
-
}
|
|
11
|
-
serializeErrors() {
|
|
12
|
-
return [{ message: "Not Found" }];
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
exports.NotFoundError = NotFoundError;
|
|
16
|
-
//# sourceMappingURL=not-found-error.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"not-found-error.js","sourceRoot":"","sources":["../../src/errors/not-found-error.ts"],"names":[],"mappings":";;;AAAA,iDAA6C;AAE7C,MAAa,aAAc,SAAQ,0BAAW;IAG5C;QACE,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAH3B,eAAU,GAAG,GAAG,CAAC;QAIf,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACvD,CAAC;IAED,eAAe;QACb,OAAO,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;IACpC,CAAC;CACF;AAXD,sCAWC"}
|