@alexdevco/passport 1.0.3 → 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.
@@ -0,0 +1,4 @@
1
+ export declare const JWTStrategy: {
2
+ readonly HS256: "HS256";
3
+ readonly RS256: "RS256";
4
+ };
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JWTStrategy = void 0;
4
+ exports.JWTStrategy = {
5
+ HS256: 'HS256',
6
+ RS256: 'RS256'
7
+ };
@@ -1 +1,2 @@
1
1
  export * from './passport.constants';
2
+ export * from './algorithm.constants';
@@ -15,3 +15,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./passport.constants"), exports);
18
+ __exportStar(require("./algorithm.constants"), exports);
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './interfaces';
2
2
  export * from './passport.module';
3
3
  export * from './passport.service';
4
+ export * from './constants';
package/dist/index.js CHANGED
@@ -17,3 +17,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./interfaces"), exports);
18
18
  __exportStar(require("./passport.module"), exports);
19
19
  __exportStar(require("./passport.service"), exports);
20
+ __exportStar(require("./constants"), exports);
@@ -0,0 +1,5 @@
1
+ import type { IPayload, IVerifyResult } from './token.interface';
2
+ export interface IJWTStrategy {
3
+ generate(payload: IPayload): string;
4
+ verify(token: string): IVerifyResult;
5
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,3 +1,5 @@
1
1
  export interface IPassportOptions {
2
2
  secretKey: string;
3
+ publicKey?: string;
4
+ strategy: string;
3
5
  }
@@ -1,8 +1,15 @@
1
- export interface ITokenPayload {
1
+ export interface IPayload {
2
2
  sub: string | number;
3
+ name: string;
4
+ iat: number;
5
+ exp: number;
6
+ }
7
+ export interface IHeader {
8
+ alg: string;
9
+ typ: string;
3
10
  }
4
11
  export interface IVerifyResult {
5
12
  valid: boolean;
6
13
  reason?: string;
7
- payload?: ITokenPayload;
14
+ payload?: IPayload;
8
15
  }
@@ -1,13 +1,10 @@
1
- import { IPassportOptions, ITokenPayload, IVerifyResult } from './interfaces';
1
+ import { IPassportOptions, IPayload, IVerifyResult } from './interfaces';
2
2
  export declare class PassportService {
3
3
  private readonly options;
4
4
  private readonly SECRET_KEY;
5
- private static readonly HMAC_DOMAIN;
6
- private static readonly INTERNAL_SEPARATOR;
5
+ private readonly PUBLIC_KEY;
6
+ private readonly strategy;
7
7
  constructor(options: IPassportOptions);
8
- private now;
9
- private serialize;
10
- private computeHmac;
11
- generate(payload: ITokenPayload, ttl: number): string;
8
+ generate(payload: IPayload): string;
12
9
  verify(token: string): IVerifyResult;
13
10
  }
@@ -11,62 +11,31 @@ var __metadata = (this && this.__metadata) || function (k, v) {
11
11
  var __param = (this && this.__param) || function (paramIndex, decorator) {
12
12
  return function (target, key) { decorator(target, key, paramIndex); }
13
13
  };
14
- var PassportService_1;
15
14
  Object.defineProperty(exports, "__esModule", { value: true });
16
15
  exports.PassportService = void 0;
17
16
  const common_1 = require("@nestjs/common");
18
- const crypto_1 = require("crypto");
19
17
  const constants_1 = require("./constants");
20
18
  const utils_1 = require("./utils");
21
19
  let PassportService = class PassportService {
22
- static { PassportService_1 = this; }
23
20
  options;
24
21
  SECRET_KEY;
25
- static HMAC_DOMAIN = 'PassportTokenAuth/v1';
26
- static INTERNAL_SEPARATOR = '|';
22
+ PUBLIC_KEY;
23
+ strategy;
27
24
  constructor(options) {
28
25
  this.options = options;
29
26
  this.SECRET_KEY = options.secretKey;
27
+ this.PUBLIC_KEY = options.publicKey;
28
+ this.strategy = (0, utils_1.getStrategy)(options.strategy, this.SECRET_KEY, this.PUBLIC_KEY);
30
29
  }
31
- now() {
32
- return Math.floor(Date.now() / 1000);
33
- }
34
- serialize(user, iat, exp) {
35
- return [PassportService_1.HMAC_DOMAIN, user, iat, exp].join(PassportService_1.INTERNAL_SEPARATOR);
36
- }
37
- computeHmac(data) {
38
- return (0, crypto_1.createHmac)('sha256', this.SECRET_KEY).update(data).digest('hex');
39
- }
40
- generate(payload, ttl) {
41
- const issuedAt = this.now();
42
- const expiresAt = issuedAt + ttl;
43
- const userPart = (0, utils_1.base64UrlEncode)(JSON.stringify(payload));
44
- const iatPart = (0, utils_1.base64UrlEncode)(String(issuedAt));
45
- const expPart = (0, utils_1.base64UrlEncode)(String(expiresAt));
46
- const serialized = this.serialize(userPart, iatPart, expPart);
47
- const mac = this.computeHmac(serialized);
48
- return [userPart, iatPart, expPart, mac].join('.');
30
+ generate(payload) {
31
+ return this.strategy.generate(payload);
49
32
  }
50
33
  verify(token) {
51
- const parts = token.split('.');
52
- if (parts.length !== 4)
53
- return { valid: false, reason: 'Invalid format' };
54
- const [userPart, iatPart, expPart, mac] = parts;
55
- const serialized = this.serialize(userPart, iatPart, expPart);
56
- const expectedMac = this.computeHmac(serialized);
57
- if (!(0, utils_1.constantTimeEqual)(expectedMac, mac))
58
- return { valid: false, reason: 'Invalid signature' };
59
- const expNumber = Number((0, utils_1.base64UrlDecode)(expPart));
60
- if (!Number.isFinite(expNumber))
61
- return { valid: false, reason: 'Error' };
62
- if (this.now() > expNumber)
63
- return { valid: false, reason: 'Expired' };
64
- const payload = JSON.parse((0, utils_1.base64UrlDecode)(userPart));
65
- return { valid: true, payload };
34
+ return this.strategy.verify(token);
66
35
  }
67
36
  };
68
37
  exports.PassportService = PassportService;
69
- exports.PassportService = PassportService = PassportService_1 = __decorate([
38
+ exports.PassportService = PassportService = __decorate([
70
39
  (0, common_1.Injectable)(),
71
40
  __param(0, (0, common_1.Inject)(constants_1.PASSPORT_OPTIONS)),
72
41
  __metadata("design:paramtypes", [Object])
@@ -0,0 +1,12 @@
1
+ import { IPayload, IVerifyResult } from '../interfaces';
2
+ import { IJWTStrategy } from '../interfaces/ jwt.interface';
3
+ export declare class HS256Strategy implements IJWTStrategy {
4
+ private readonly SECRET_KEY;
5
+ private static readonly INTERNAL_SEPARATOR;
6
+ private static readonly JWT_ALG;
7
+ private static readonly PARTS_LENGTH;
8
+ constructor(secret: string);
9
+ generate(payload: IPayload): string;
10
+ verify(token: string): IVerifyResult;
11
+ private computeHmac;
12
+ }
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HS256Strategy = void 0;
4
+ const crypto_1 = require("crypto");
5
+ const utils_1 = require("../utils");
6
+ class HS256Strategy {
7
+ SECRET_KEY;
8
+ static INTERNAL_SEPARATOR = '.';
9
+ static JWT_ALG = 'HS256';
10
+ static PARTS_LENGTH = 3;
11
+ constructor(secret) {
12
+ this.SECRET_KEY = secret;
13
+ }
14
+ generate(payload) {
15
+ const header = { alg: HS256Strategy.JWT_ALG, typ: 'JWT' };
16
+ const headerB64 = (0, utils_1.base64UrlEncode)(JSON.stringify(header));
17
+ const payloadB64 = (0, utils_1.base64UrlEncode)(JSON.stringify(payload));
18
+ const serialized = (0, utils_1.serialize)([headerB64, payloadB64], HS256Strategy.INTERNAL_SEPARATOR);
19
+ const mac = this.computeHmac(serialized);
20
+ return (0, utils_1.serialize)([serialized, mac], HS256Strategy.INTERNAL_SEPARATOR);
21
+ }
22
+ verify(token) {
23
+ const parts = token.split(HS256Strategy.INTERNAL_SEPARATOR);
24
+ if (parts.length !== HS256Strategy.PARTS_LENGTH) {
25
+ return { valid: false, reason: 'Invalid format' };
26
+ }
27
+ const [headerB64, payloadB64, mac] = parts;
28
+ const serialized = (0, utils_1.serialize)([headerB64, payloadB64], HS256Strategy.INTERNAL_SEPARATOR);
29
+ const expectedMac = this.computeHmac(serialized);
30
+ if (!(0, utils_1.constantTimeEqual)(expectedMac, mac)) {
31
+ return { valid: false, reason: 'Invalid signature' };
32
+ }
33
+ const parsed = JSON.parse((0, utils_1.base64UrlDecode)(payloadB64));
34
+ if (!(0, utils_1.isPayload)(parsed))
35
+ return { valid: false, reason: 'Invalid payload stucture' };
36
+ const payload = parsed;
37
+ if (!Number.isFinite(payload.exp))
38
+ return { valid: false, reason: 'Expired error format' };
39
+ if ((0, utils_1.now)() > payload.exp)
40
+ return { valid: false, reason: 'Token is expired' };
41
+ return { valid: true, payload };
42
+ }
43
+ computeHmac(data) {
44
+ return (0, crypto_1.createHmac)('sha256', this.SECRET_KEY).update(data).digest('hex');
45
+ }
46
+ }
47
+ exports.HS256Strategy = HS256Strategy;
@@ -0,0 +1,2 @@
1
+ export * from './hs256.strategy';
2
+ export * from './rs256.strategy';
@@ -0,0 +1,18 @@
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("./hs256.strategy"), exports);
18
+ __exportStar(require("./rs256.strategy"), exports);
@@ -0,0 +1,13 @@
1
+ import { IPayload, IVerifyResult } from '../interfaces';
2
+ import { IJWTStrategy } from '../interfaces/ jwt.interface';
3
+ export declare class RS256Strategy implements IJWTStrategy {
4
+ private readonly SECRET_KEY;
5
+ private readonly PUBLIC_KEY;
6
+ private static readonly INTERNAL_SEPARATOR;
7
+ private static readonly JWT_ALG;
8
+ private static readonly PARTS_LENGTH;
9
+ constructor(secretKey: string, publicKey: string);
10
+ generate(payload: IPayload): string;
11
+ verify(token: string): IVerifyResult;
12
+ private computeRSA;
13
+ }
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RS256Strategy = void 0;
4
+ const crypto_1 = require("crypto");
5
+ const utils_1 = require("../utils");
6
+ class RS256Strategy {
7
+ SECRET_KEY;
8
+ PUBLIC_KEY;
9
+ static INTERNAL_SEPARATOR = '.';
10
+ static JWT_ALG = 'RSA-SHA256';
11
+ static PARTS_LENGTH = 3;
12
+ constructor(secretKey, publicKey) {
13
+ this.SECRET_KEY = secretKey;
14
+ this.PUBLIC_KEY = publicKey;
15
+ }
16
+ generate(payload) {
17
+ const header = { alg: RS256Strategy.JWT_ALG, typ: 'JWT' };
18
+ const headerB64 = (0, utils_1.base64UrlEncode)(JSON.stringify(header));
19
+ const payloadB64 = (0, utils_1.base64UrlEncode)(JSON.stringify(payload));
20
+ const serialized = (0, utils_1.serialize)([headerB64, payloadB64], RS256Strategy.INTERNAL_SEPARATOR);
21
+ const mac = this.computeRSA(serialized);
22
+ return (0, utils_1.serialize)([serialized, mac], RS256Strategy.INTERNAL_SEPARATOR);
23
+ }
24
+ verify(token) {
25
+ const parts = token.split(RS256Strategy.INTERNAL_SEPARATOR);
26
+ if (parts.length !== RS256Strategy.PARTS_LENGTH)
27
+ return { valid: false, reason: 'Invalid format' };
28
+ const [header64, payload64, mac] = parts;
29
+ const serialized = (0, utils_1.serialize)([header64, payload64], RS256Strategy.INTERNAL_SEPARATOR);
30
+ const expectedMac = this.computeRSA(serialized);
31
+ const verify = (0, crypto_1.createVerify)(RS256Strategy.JWT_ALG).update(serialized);
32
+ if (!verify.verify(this.PUBLIC_KEY, expectedMac))
33
+ return { valid: false, reason: 'Invalid signature' };
34
+ const parsed = JSON.parse((0, utils_1.base64UrlDecode)(payload64));
35
+ if (!(0, utils_1.isPayload)(parsed))
36
+ return { valid: false, reason: 'Invalid payload stucture' };
37
+ const payload = parsed;
38
+ if (!Number.isFinite(payload.exp))
39
+ return { valid: false, reason: 'Expired error format' };
40
+ if ((0, utils_1.now)() > payload.exp)
41
+ return { valid: false, reason: 'Token is expired' };
42
+ return { valid: true, payload };
43
+ }
44
+ computeRSA(data) {
45
+ const sign = (0, crypto_1.createSign)(RS256Strategy.JWT_ALG)
46
+ .update(data)
47
+ .sign(this.SECRET_KEY);
48
+ return (0, utils_1.base64UrlEncode)(sign);
49
+ }
50
+ }
51
+ exports.RS256Strategy = RS256Strategy;
@@ -0,0 +1,3 @@
1
+ import { IHeader, IPayload } from '../interfaces';
2
+ export declare function isPayload(data: any): data is IPayload;
3
+ export declare function isHeader(data: any): data is IHeader;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isPayload = isPayload;
4
+ exports.isHeader = isHeader;
5
+ function isPayload(data) {
6
+ return ((typeof data.sub === 'string' || typeof data.sub === 'number') &&
7
+ typeof data.name === 'string' &&
8
+ typeof data.iat === 'number' &&
9
+ typeof data.exp === 'number');
10
+ }
11
+ function isHeader(data) {
12
+ return typeof data.alg === 'string' && typeof data.typ === 'string';
13
+ }
@@ -1 +1,4 @@
1
+ import { Verify } from 'crypto';
1
2
  export declare function constantTimeEqual(a: string, b: string): boolean;
3
+ export declare function getVerifyRSA(data: string): Verify;
4
+ export declare function serialize(arr: string[], separator: string): string;
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.constantTimeEqual = constantTimeEqual;
4
+ exports.getVerifyRSA = getVerifyRSA;
5
+ exports.serialize = serialize;
4
6
  const crypto_1 = require("crypto");
5
7
  function constantTimeEqual(a, b) {
6
8
  const bufA = Buffer.from(a);
@@ -9,3 +11,9 @@ function constantTimeEqual(a, b) {
9
11
  return false;
10
12
  return (0, crypto_1.timingSafeEqual)(bufA, bufB);
11
13
  }
14
+ function getVerifyRSA(data) {
15
+ return (0, crypto_1.createVerify)('RSA-SHA256').update(data);
16
+ }
17
+ function serialize(arr, separator) {
18
+ return arr.join(separator);
19
+ }
@@ -0,0 +1 @@
1
+ export declare function now(): number;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.now = now;
4
+ function now() {
5
+ return Math.floor(Date.now() / 1000);
6
+ }
@@ -1,2 +1,5 @@
1
1
  export * from './base64';
2
2
  export * from './crypto';
3
+ export * from './jwt';
4
+ export * from './date';
5
+ export * from './checks';
@@ -16,3 +16,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./base64"), exports);
18
18
  __exportStar(require("./crypto"), exports);
19
+ __exportStar(require("./jwt"), exports);
20
+ __exportStar(require("./date"), exports);
21
+ __exportStar(require("./checks"), exports);
@@ -0,0 +1,6 @@
1
+ import { IJWTStrategy } from '../interfaces/ jwt.interface';
2
+ export declare function JwtDecode(token: string): {
3
+ header: any;
4
+ payload: any;
5
+ };
6
+ export declare function getStrategy(type: string, secretKey: string, publicKey: string | null): IJWTStrategy;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JwtDecode = JwtDecode;
4
+ exports.getStrategy = getStrategy;
5
+ const constants_1 = require("../constants");
6
+ const strategies_1 = require("../strategies");
7
+ const base64_1 = require("./base64");
8
+ function JwtDecode(token) {
9
+ const [header, payload] = token.split('.');
10
+ return {
11
+ header: JSON.parse((0, base64_1.base64UrlDecode)(header)),
12
+ payload: JSON.parse((0, base64_1.base64UrlDecode)(payload))
13
+ };
14
+ }
15
+ function getStrategy(type, secretKey, publicKey) {
16
+ switch (type) {
17
+ case constants_1.JWTStrategy.HS256:
18
+ return new strategies_1.HS256Strategy(secretKey);
19
+ case constants_1.JWTStrategy.RS256:
20
+ if (!publicKey)
21
+ throw new Error('For RS256 need Public key');
22
+ return new strategies_1.RS256Strategy(secretKey, publicKey);
23
+ default:
24
+ throw new Error('Undefined strategy');
25
+ }
26
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexdevco/passport",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Lightweight AlexDevCo authentication library",
5
5
  "homepage": "https://github.com/alexdevcoru/passport#readme",
6
6
  "bugs": {