@teacinema-example/passport 1.0.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/dist/constans/index.d.ts +1 -0
- package/dist/constans/index.js +5 -0
- package/dist/constans/passport.constans.d.ts +1 -0
- package/dist/constans/passport.constans.js +4 -0
- package/dist/lib/index.d.ts +3 -0
- package/dist/lib/index.js +19 -0
- package/dist/lib/passport.module.d.ts +6 -0
- package/dist/lib/passport.module.js +38 -0
- package/dist/lib/passport.provider.d.ts +4 -0
- package/dist/lib/passport.provider.js +27 -0
- package/dist/lib/passport.service.d.ts +21 -0
- package/dist/lib/passport.service.js +72 -0
- package/dist/lib/types/index.d.ts +3 -0
- package/dist/lib/types/index.js +2 -0
- package/dist/lib/types/passport-async-options.type.d.ts +6 -0
- package/dist/lib/types/passport-async-options.type.js +2 -0
- package/dist/lib/types/passport-options.type.d.ts +3 -0
- package/dist/lib/types/passport-options.type.js +2 -0
- package/dist/lib/types/token.type.d.ts +13 -0
- package/dist/lib/types/token.type.js +2 -0
- package/dist/lib/utils/base64.d.ts +2 -0
- package/dist/lib/utils/base64.js +19 -0
- package/dist/lib/utils/crypto.d.ts +1 -0
- package/dist/lib/utils/crypto.js +12 -0
- package/dist/lib/utils/index.d.ts +2 -0
- package/dist/lib/utils/index.js +8 -0
- package/package.json +31 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { PASSPORT_OPTIONS } from './passport.constans';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PASSPORT_OPTIONS = void 0;
|
|
4
|
+
var passport_constans_1 = require("./passport.constans");
|
|
5
|
+
Object.defineProperty(exports, "PASSPORT_OPTIONS", { enumerable: true, get: function () { return passport_constans_1.PASSPORT_OPTIONS; } });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const PASSPORT_OPTIONS: unique symbol;
|
|
@@ -0,0 +1,19 @@
|
|
|
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("./types"), exports);
|
|
18
|
+
__exportStar(require("./passport.module"), exports);
|
|
19
|
+
__exportStar(require("./passport.service"), exports);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type DynamicModule } from '@nestjs/common';
|
|
2
|
+
import type { PassportAsyncOptions, PassportOptions } from './types';
|
|
3
|
+
export declare class PassportModule {
|
|
4
|
+
static register(options: PassportOptions): DynamicModule;
|
|
5
|
+
static registerAsync(options: PassportAsyncOptions): Promise<DynamicModule>;
|
|
6
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var PassportModule_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.PassportModule = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const constans_1 = require("../constans");
|
|
13
|
+
const passport_provider_1 = require("./passport.provider");
|
|
14
|
+
const passport_service_1 = require("./passport.service");
|
|
15
|
+
let PassportModule = PassportModule_1 = class PassportModule {
|
|
16
|
+
static register(options) {
|
|
17
|
+
const provider = (0, passport_provider_1.passportProvider)(options);
|
|
18
|
+
return {
|
|
19
|
+
module: PassportModule_1,
|
|
20
|
+
providers: [provider, passport_service_1.PassportService],
|
|
21
|
+
exports: [passport_service_1.PassportService, constans_1.PASSPORT_OPTIONS]
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
static async registerAsync(options) {
|
|
25
|
+
const provider = await (0, passport_provider_1.passportAsyncProvider)(options);
|
|
26
|
+
return {
|
|
27
|
+
module: PassportModule_1,
|
|
28
|
+
imports: options.imports ?? [],
|
|
29
|
+
providers: [provider, passport_service_1.PassportService],
|
|
30
|
+
exports: [passport_service_1.PassportService, constans_1.PASSPORT_OPTIONS]
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
exports.PassportModule = PassportModule;
|
|
35
|
+
exports.PassportModule = PassportModule = PassportModule_1 = __decorate([
|
|
36
|
+
(0, common_1.Global)(),
|
|
37
|
+
(0, common_1.Module)({})
|
|
38
|
+
], PassportModule);
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Provider } from '@nestjs/common';
|
|
2
|
+
import type { PassportAsyncOptions, PassportOptions } from './types';
|
|
3
|
+
export declare const passportProvider: (options: PassportOptions) => Provider;
|
|
4
|
+
export declare const passportAsyncProvider: (options: PassportAsyncOptions) => Promise<Provider>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.passportAsyncProvider = exports.passportProvider = void 0;
|
|
4
|
+
const constans_1 = require("../constans");
|
|
5
|
+
const passportProvider = (options) => {
|
|
6
|
+
return {
|
|
7
|
+
provide: constans_1.PASSPORT_OPTIONS,
|
|
8
|
+
useValue: Object.freeze(options)
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
exports.passportProvider = passportProvider;
|
|
12
|
+
const passportAsyncProvider = async (options) => {
|
|
13
|
+
return {
|
|
14
|
+
provide: constans_1.PASSPORT_OPTIONS,
|
|
15
|
+
useFactory: async (...args) => {
|
|
16
|
+
const resolved = await options.useFactory(...args);
|
|
17
|
+
if (!resolved ||
|
|
18
|
+
!resolved.secretKey ||
|
|
19
|
+
typeof resolved.secretKey !== 'string') {
|
|
20
|
+
throw new Error('[PassportModule] "secretKey" is required and must be string');
|
|
21
|
+
}
|
|
22
|
+
return Object.freeze({ ...resolved });
|
|
23
|
+
},
|
|
24
|
+
inject: options.inject ?? []
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
exports.passportAsyncProvider = passportAsyncProvider;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { PassportOptions } from './types';
|
|
2
|
+
export declare class PassportService {
|
|
3
|
+
private readonly options;
|
|
4
|
+
private readonly SECRET_KEY;
|
|
5
|
+
private static readonly HMAC_DOMAIN;
|
|
6
|
+
private static readonly INTERNAL_SEPARATOR;
|
|
7
|
+
constructor(options: PassportOptions);
|
|
8
|
+
private now;
|
|
9
|
+
private serialize;
|
|
10
|
+
private computedHMAC;
|
|
11
|
+
generate: (userId: string, ttl: number) => string;
|
|
12
|
+
verify: (secretKey: string, token: string) => {
|
|
13
|
+
valid: boolean;
|
|
14
|
+
reason: string;
|
|
15
|
+
userId?: undefined;
|
|
16
|
+
} | {
|
|
17
|
+
valid: boolean;
|
|
18
|
+
userId: string;
|
|
19
|
+
reason?: undefined;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var PassportService_1;
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.PassportService = void 0;
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const node_crypto_1 = require("node:crypto");
|
|
19
|
+
const constans_1 = require("../constans");
|
|
20
|
+
const utils_1 = require("./utils");
|
|
21
|
+
let PassportService = class PassportService {
|
|
22
|
+
static { PassportService_1 = this; }
|
|
23
|
+
options;
|
|
24
|
+
SECRET_KEY;
|
|
25
|
+
static HMAC_DOMAIN = 'PassportTokenAuth/v1';
|
|
26
|
+
static INTERNAL_SEPARATOR = '|';
|
|
27
|
+
constructor(options) {
|
|
28
|
+
this.options = options;
|
|
29
|
+
this.SECRET_KEY = options.secretKey;
|
|
30
|
+
}
|
|
31
|
+
now = () => Math.floor(Date.now() / 1000);
|
|
32
|
+
serialize = (user, iat, exp) => {
|
|
33
|
+
return [PassportService_1.HMAC_DOMAIN, user, iat, exp].join(PassportService_1.INTERNAL_SEPARATOR);
|
|
34
|
+
};
|
|
35
|
+
computedHMAC = (payload) => {
|
|
36
|
+
return (0, node_crypto_1.createHmac)('sha256', this.SECRET_KEY)
|
|
37
|
+
.update(payload)
|
|
38
|
+
.digest('base64');
|
|
39
|
+
};
|
|
40
|
+
generate = (userId, ttl) => {
|
|
41
|
+
const iat = this.now();
|
|
42
|
+
const exp = iat + ttl;
|
|
43
|
+
const userPart = (0, utils_1.base64UrlEncode)(userId);
|
|
44
|
+
const iatPart = (0, utils_1.base64UrlEncode)(String(iat));
|
|
45
|
+
const expPart = (0, utils_1.base64UrlEncode)(String(exp));
|
|
46
|
+
const payload = this.serialize(userPart, iatPart, expPart);
|
|
47
|
+
const hmac = this.computedHMAC(payload);
|
|
48
|
+
return `${userPart}.${iatPart}.${expPart}.${hmac}`;
|
|
49
|
+
};
|
|
50
|
+
verify = (secretKey, token) => {
|
|
51
|
+
const parts = token.split('.');
|
|
52
|
+
if (parts.length !== 4)
|
|
53
|
+
return { valid: false, reason: 'Invalid format' };
|
|
54
|
+
const [userPart, iatPart, expPart, hmac] = parts;
|
|
55
|
+
const payload = this.serialize(userPart, iatPart, expPart);
|
|
56
|
+
const expectedMac = this.computedHMAC(payload);
|
|
57
|
+
if (!(0, utils_1.constantTimeEqual)(expectedMac, hmac))
|
|
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
|
+
return { valid: true, userId: (0, utils_1.base64UrlDecode)(userPart) };
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
exports.PassportService = PassportService;
|
|
68
|
+
exports.PassportService = PassportService = PassportService_1 = __decorate([
|
|
69
|
+
(0, common_1.Injectable)(),
|
|
70
|
+
__param(0, (0, common_1.Inject)(constans_1.PASSPORT_OPTIONS)),
|
|
71
|
+
__metadata("design:paramtypes", [Object])
|
|
72
|
+
], PassportService);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { FactoryProvider, ModuleMetadata } from '@nestjs/common';
|
|
2
|
+
import type { PassportOptions } from './passport-options.type';
|
|
3
|
+
export type PassportAsyncOptions = Pick<ModuleMetadata, 'imports'> & {
|
|
4
|
+
useFactory: (...args: any[]) => Promise<PassportOptions> | PassportOptions;
|
|
5
|
+
inject?: FactoryProvider['inject'];
|
|
6
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type TokenPayload = {
|
|
2
|
+
sub: number | string;
|
|
3
|
+
};
|
|
4
|
+
type VerifySusses = {
|
|
5
|
+
valid: true;
|
|
6
|
+
userId: string;
|
|
7
|
+
};
|
|
8
|
+
type VerifyError = {
|
|
9
|
+
valid: false;
|
|
10
|
+
reason: string;
|
|
11
|
+
};
|
|
12
|
+
export type VerifyResult = VerifySusses | VerifyError;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.base64UrlDecode = exports.base64UrlEncode = void 0;
|
|
4
|
+
const base64UrlEncode = (buf) => {
|
|
5
|
+
const s = typeof buf === 'string' ? Buffer.from(buf) : buf;
|
|
6
|
+
return s
|
|
7
|
+
.toString('base64')
|
|
8
|
+
.replace(/\+/g, '-')
|
|
9
|
+
.replace(/\//g, '_')
|
|
10
|
+
.replace(/=+$/, '');
|
|
11
|
+
};
|
|
12
|
+
exports.base64UrlEncode = base64UrlEncode;
|
|
13
|
+
const base64UrlDecode = (str) => {
|
|
14
|
+
str = str.replace(/-/g, '+').replace(/_/g, '/');
|
|
15
|
+
while (str.length % 4)
|
|
16
|
+
str += '=';
|
|
17
|
+
return Buffer.from(str, 'base64').toString();
|
|
18
|
+
};
|
|
19
|
+
exports.base64UrlDecode = base64UrlDecode;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const constantTimeEqual: (a: string, b: string) => boolean;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.constantTimeEqual = void 0;
|
|
4
|
+
const node_crypto_1 = require("node:crypto");
|
|
5
|
+
const constantTimeEqual = (a, b) => {
|
|
6
|
+
const bufA = Buffer.from(a);
|
|
7
|
+
const bufB = Buffer.from(b);
|
|
8
|
+
if (bufA.length !== bufB.length)
|
|
9
|
+
return false;
|
|
10
|
+
return (0, node_crypto_1.timingSafeEqual)(bufA, bufB);
|
|
11
|
+
};
|
|
12
|
+
exports.constantTimeEqual = constantTimeEqual;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.constantTimeEqual = exports.base64UrlDecode = exports.base64UrlEncode = void 0;
|
|
4
|
+
var base64_1 = require("./base64");
|
|
5
|
+
Object.defineProperty(exports, "base64UrlEncode", { enumerable: true, get: function () { return base64_1.base64UrlEncode; } });
|
|
6
|
+
Object.defineProperty(exports, "base64UrlDecode", { enumerable: true, get: function () { return base64_1.base64UrlDecode; } });
|
|
7
|
+
var crypto_1 = require("./crypto");
|
|
8
|
+
Object.defineProperty(exports, "constantTimeEqual", { enumerable: true, get: function () { return crypto_1.constantTimeEqual; } });
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@teacinema-example/passport",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Lightweight Teacinema authentication library",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"files": ["dist"],
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc -p tsconfig.build.json",
|
|
13
|
+
"format": "prettier --write \"lib/**/*.ts\""
|
|
14
|
+
},
|
|
15
|
+
"keywords": [],
|
|
16
|
+
"author": "",
|
|
17
|
+
"license": "ISC",
|
|
18
|
+
"type": "commonjs",
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@teacinema-example/core": "^1.0.3",
|
|
21
|
+
"@types/node": "^25.3.0",
|
|
22
|
+
"prettier": "^3.8.1",
|
|
23
|
+
"typescript": "^5.9.3"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@nestjs/common": "^11.1.14",
|
|
27
|
+
"@nestjs/core": "^11.1.14",
|
|
28
|
+
"reflect-metadata": "^0.2.2",
|
|
29
|
+
"rxjs": "^7.8.2"
|
|
30
|
+
}
|
|
31
|
+
}
|