@nextage/era-lib 1.0.166 → 1.0.167

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.
@@ -1,6 +1,6 @@
1
1
  export declare const msgWrapper: {
2
2
  client: {
3
- publish: import("vitest").Mock<(...args: any[]) => any>;
3
+ publish: import("vitest").Mock<import("@vitest/spy").Procedure>;
4
4
  };
5
5
  };
6
6
  //# sourceMappingURL=msg-wrapper.d.ts.map
@@ -1,6 +1,6 @@
1
1
  export declare const natsWrapper: {
2
2
  client: {
3
- publish: import("vitest").Mock<(...args: any[]) => any>;
3
+ publish: import("vitest").Mock<import("@vitest/spy").Procedure>;
4
4
  };
5
5
  };
6
6
  //# sourceMappingURL=nats-wrapper.d.ts.map
@@ -1,4 +1,5 @@
1
1
  export * from './express';
2
2
  export * from './functs';
3
+ export * from './jwt';
3
4
  export * from './start-service';
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,OAAO,CAAC;AACtB,cAAc,iBAAiB,CAAC"}
@@ -16,5 +16,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./express"), exports);
18
18
  __exportStar(require("./functs"), exports);
19
+ __exportStar(require("./jwt"), exports);
19
20
  __exportStar(require("./start-service"), exports);
20
21
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4CAA0B;AAC1B,2CAAyB;AACzB,kDAAgC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4CAA0B;AAC1B,2CAAyB;AACzB,wCAAsB;AACtB,kDAAgC"}
@@ -0,0 +1,45 @@
1
+ import { JwtPayload, SignOptions } from 'jsonwebtoken';
2
+ /** Marker claim distinguishing a refresh token from an access token. */
3
+ export declare const REFRESH_TOKEN_TYPE = "refresh";
4
+ /** Default validity used when the matching env var is not set. */
5
+ export declare const DEFAULT_ACCESS_VALIDITY = "15m";
6
+ export declare const DEFAULT_REFRESH_VALIDITY = "7d";
7
+ export interface RefreshTokenPayload extends JwtPayload {
8
+ /** Subject — the user id. */
9
+ sub: string;
10
+ /** JWT id — the `accesses` record id (session id). Mirrors the access token jti. */
11
+ jti: string;
12
+ /** Token type marker. */
13
+ typ: typeof REFRESH_TOKEN_TYPE;
14
+ }
15
+ /**
16
+ * Sign a long-lived REFRESH token for a session.
17
+ *
18
+ * @param sub user id
19
+ * @param jti `accesses` record id (session id) — same value as the access jti
20
+ * @param opts optional sign-option overrides (e.g. a fixed expiresIn for tests)
21
+ */
22
+ export declare function signRefreshToken(sub: string, jti: string, opts?: SignOptions, secret?: string): string;
23
+ /**
24
+ * Verify a REFRESH token and return its payload. Throws (JsonWebTokenError /
25
+ * TokenExpiredError) when the token is malformed, expired or not a refresh token.
26
+ */
27
+ export declare function verifyRefreshToken(token: string, secret?: string): RefreshTokenPayload;
28
+ /**
29
+ * Deterministic sha256 hex digest of a token. Stored on the `accesses` record so
30
+ * the raw refresh token never touches the database and can be rotated / revoked
31
+ * by overwriting (logout) or replacing (rotation) the stored hash.
32
+ */
33
+ export declare function hashToken(token: string): string;
34
+ /**
35
+ * Read the `exp` claim of a signed token and return it as a `Date` (or
36
+ * `undefined` when the token carries no expiry). Used to persist the refresh
37
+ * token expiry on the `accesses` record without re-parsing the duration string.
38
+ */
39
+ export declare function tokenExpiry(token: string): Date | undefined;
40
+ /**
41
+ * Constant-time comparison of a raw token against a stored hash. Prevents timing
42
+ * side-channels when validating a presented refresh token.
43
+ */
44
+ export declare function verifyTokenHash(token: string, hash?: string | null): boolean;
45
+ //# sourceMappingURL=jwt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/utils/jwt.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEvD,wEAAwE;AACxE,eAAO,MAAM,kBAAkB,YAAY,CAAC;AAE5C,kEAAkE;AAClE,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAC9C,eAAO,MAAM,wBAAwB,OAAQ,CAAC;AAE9C,MAAM,WAAW,mBAAoB,SAAQ,UAAU;IACrD,6BAA6B;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,oFAAoF;IACpF,GAAG,EAAE,MAAM,CAAC;IACZ,yBAAyB;IACzB,GAAG,EAAE,OAAO,kBAAkB,CAAC;CAChC;AAyBD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAW1G;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,mBAAmB,CAQtF;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAG/C;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAK3D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAS5E"}
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ // ┌────────────────────────────────────────────────────────────────────────────┐
3
+ // │ JWT — functional token helpers (access + refresh) │
4
+ // │ │
5
+ // │ Pure, side-effect-free helpers built on `jsonwebtoken`. They centralize the │
6
+ // │ token contract of the auth service so the controller stays declarative: │
7
+ // │ │
8
+ // │ • signRefreshToken() → long-lived refresh JWT (REFRESH_VALIDITY) │
9
+ // │ • verifyRefreshToken() → decode + verify a refresh JWT (throws on invalid) │
10
+ // │ • hashToken() → sha256 hex, stored on the `accesses` record so the │
11
+ // │ refresh can be rotated / revoked server-side. │
12
+ // │ │
13
+ // │ The ACCESS token is still signed by nx-frame-be `generateJwt()` (it already │
14
+ // │ honours JWT_VALIDITY). See ADR-0002: the target architecture (Step 2.7) is │
15
+ // │ asymmetric signing (EdDSA/Ed25519 via `jose`, auth-srv sole signer). These │
16
+ // │ helpers keep HS* now with a clean, functional surface to swap later. │
17
+ // └────────────────────────────────────────────────────────────────────────────┘
18
+ var __importDefault = (this && this.__importDefault) || function (mod) {
19
+ return (mod && mod.__esModule) ? mod : { "default": mod };
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.DEFAULT_REFRESH_VALIDITY = exports.DEFAULT_ACCESS_VALIDITY = exports.REFRESH_TOKEN_TYPE = void 0;
23
+ exports.signRefreshToken = signRefreshToken;
24
+ exports.verifyRefreshToken = verifyRefreshToken;
25
+ exports.hashToken = hashToken;
26
+ exports.tokenExpiry = tokenExpiry;
27
+ exports.verifyTokenHash = verifyTokenHash;
28
+ const node_crypto_1 = __importDefault(require("node:crypto"));
29
+ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
30
+ /** Marker claim distinguishing a refresh token from an access token. */
31
+ exports.REFRESH_TOKEN_TYPE = 'refresh';
32
+ /** Default validity used when the matching env var is not set. */
33
+ exports.DEFAULT_ACCESS_VALIDITY = '15m';
34
+ exports.DEFAULT_REFRESH_VALIDITY = '7d';
35
+ /**
36
+ * Resolve the secret used to sign / verify REFRESH tokens.
37
+ *
38
+ * A dedicated `REFRESH_SECRET` is preferred (so a leak of one secret cannot be
39
+ * used to forge the other kind of token); it falls back to `JWT_SECRET` when not
40
+ * configured. Throws when neither is available.
41
+ */
42
+ function refreshSecret(secret) {
43
+ const resolved = secret || process.env.REFRESH_SECRET || process.env.JWT_SECRET;
44
+ if (!resolved)
45
+ throw new Error('Missing refresh token secret (REFRESH_SECRET / JWT_SECRET)');
46
+ return resolved;
47
+ }
48
+ /** Resolve the signing algorithm (defaults to HS512, matching the access token). */
49
+ function signAlgorithm() {
50
+ return (process.env.JWT_ALGORITHM ?? 'HS512');
51
+ }
52
+ /**
53
+ * Sign a long-lived REFRESH token for a session.
54
+ *
55
+ * @param sub user id
56
+ * @param jti `accesses` record id (session id) — same value as the access jti
57
+ * @param opts optional sign-option overrides (e.g. a fixed expiresIn for tests)
58
+ */
59
+ function signRefreshToken(sub, jti, opts = {}, secret) {
60
+ const signOpts = {
61
+ algorithm: signAlgorithm(),
62
+ expiresIn: (process.env.REFRESH_VALIDITY ?? exports.DEFAULT_REFRESH_VALIDITY),
63
+ ...opts
64
+ };
65
+ const payload = { sub, jti, typ: exports.REFRESH_TOKEN_TYPE };
66
+ return jsonwebtoken_1.default.sign(payload, refreshSecret(secret), signOpts);
67
+ }
68
+ /**
69
+ * Verify a REFRESH token and return its payload. Throws (JsonWebTokenError /
70
+ * TokenExpiredError) when the token is malformed, expired or not a refresh token.
71
+ */
72
+ function verifyRefreshToken(token, secret) {
73
+ const payload = jsonwebtoken_1.default.verify(token, refreshSecret(secret), { algorithms: [signAlgorithm()] });
74
+ if (payload?.typ !== exports.REFRESH_TOKEN_TYPE)
75
+ throw new Error('Not a refresh token');
76
+ return payload;
77
+ }
78
+ /**
79
+ * Deterministic sha256 hex digest of a token. Stored on the `accesses` record so
80
+ * the raw refresh token never touches the database and can be rotated / revoked
81
+ * by overwriting (logout) or replacing (rotation) the stored hash.
82
+ */
83
+ function hashToken(token) {
84
+ return node_crypto_1.default.createHash('sha256').update(token).digest('hex');
85
+ }
86
+ /**
87
+ * Read the `exp` claim of a signed token and return it as a `Date` (or
88
+ * `undefined` when the token carries no expiry). Used to persist the refresh
89
+ * token expiry on the `accesses` record without re-parsing the duration string.
90
+ */
91
+ function tokenExpiry(token) {
92
+ const decoded = jsonwebtoken_1.default.decode(token);
93
+ return decoded?.exp ? new Date(decoded.exp * 1000) : undefined;
94
+ }
95
+ /**
96
+ * Constant-time comparison of a raw token against a stored hash. Prevents timing
97
+ * side-channels when validating a presented refresh token.
98
+ */
99
+ function verifyTokenHash(token, hash) {
100
+ if (!hash)
101
+ return false;
102
+ const a = Buffer.from(hashToken(token));
103
+ const b = Buffer.from(hash);
104
+ return a.length === b.length && node_crypto_1.default.timingSafeEqual(a, b);
105
+ }
106
+ //# sourceMappingURL=jwt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../src/utils/jwt.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextage/era-lib",
3
- "version": "1.0.166",
3
+ "version": "1.0.167",
4
4
  "main": "./build/index.js",
5
5
  "types": "./build/index.d.ts",
6
6
  "files": [
@@ -55,6 +55,9 @@
55
55
  "devDependencies": {
56
56
  "del-cli": "^6.0.0",
57
57
  "mongodb-memory-server": "^10.1.4",
58
- "vitest": "^2.1.9"
58
+ "vitest": "^4.1.10"
59
+ },
60
+ "overrides": {
61
+ "uuid": "^11.1.1"
59
62
  }
60
63
  }