@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.
- package/dist/constants/algorithm.constants.d.ts +4 -0
- package/dist/constants/algorithm.constants.js +7 -0
- package/dist/constants/index.d.ts +1 -0
- package/dist/constants/index.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/interfaces/ jwt.interface.d.ts +5 -0
- package/dist/interfaces/ jwt.interface.js +2 -0
- package/dist/interfaces/passport-options.interface.d.ts +2 -0
- package/dist/interfaces/token.interface.d.ts +9 -2
- package/dist/passport.service.d.ts +4 -7
- package/dist/passport.service.js +8 -39
- package/dist/strategies/hs256.strategy.d.ts +12 -0
- package/dist/strategies/hs256.strategy.js +47 -0
- package/dist/strategies/index.d.ts +2 -0
- package/dist/strategies/index.js +18 -0
- package/dist/strategies/rs256.strategy.d.ts +13 -0
- package/dist/strategies/rs256.strategy.js +51 -0
- package/dist/utils/checks.d.ts +3 -0
- package/dist/utils/checks.js +13 -0
- package/dist/utils/crypto.d.ts +3 -0
- package/dist/utils/crypto.js +8 -0
- package/dist/utils/date.d.ts +1 -0
- package/dist/utils/date.js +6 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/jwt.d.ts +6 -0
- package/dist/utils/jwt.js +26 -0
- package/package.json +1 -1
package/dist/constants/index.js
CHANGED
package/dist/index.d.ts
CHANGED
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);
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
export interface
|
|
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?:
|
|
14
|
+
payload?: IPayload;
|
|
8
15
|
}
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import { IPassportOptions,
|
|
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
|
|
6
|
-
private
|
|
5
|
+
private readonly PUBLIC_KEY;
|
|
6
|
+
private readonly strategy;
|
|
7
7
|
constructor(options: IPassportOptions);
|
|
8
|
-
|
|
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
|
}
|
package/dist/passport.service.js
CHANGED
|
@@ -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
|
-
|
|
26
|
-
|
|
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
|
-
|
|
32
|
-
return
|
|
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
|
-
|
|
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 =
|
|
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,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,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
|
+
}
|
package/dist/utils/crypto.d.ts
CHANGED
package/dist/utils/crypto.js
CHANGED
|
@@ -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;
|
package/dist/utils/index.d.ts
CHANGED
package/dist/utils/index.js
CHANGED
|
@@ -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,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
|
+
}
|