mybase 1.1.41 → 1.1.43

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mybase",
3
- "version": "1.1.41",
3
+ "version": "1.1.43",
4
4
  "description": "",
5
5
  "main": "mybase.js",
6
6
  "scripts": {
package/ts/index.d.ts CHANGED
@@ -29,3 +29,4 @@ export * from "./funcs/knexConnection";
29
29
  export * from "./models/Unixtime";
30
30
  export * from "./models/Timespan";
31
31
  export * from "./models/IPAddress";
32
+ export * from "./models/OTPGenerator";
package/ts/index.js CHANGED
@@ -46,4 +46,5 @@ __exportStar(require("./funcs/knexConnection"), exports);
46
46
  __exportStar(require("./models/Unixtime"), exports);
47
47
  __exportStar(require("./models/Timespan"), exports);
48
48
  __exportStar(require("./models/IPAddress"), exports);
49
+ __exportStar(require("./models/OTPGenerator"), exports);
49
50
  //# sourceMappingURL=index.js.map
package/ts/index.ts CHANGED
@@ -32,5 +32,6 @@ export * from "./funcs/knexConnection"
32
32
  export * from "./models/Unixtime"
33
33
  export * from "./models/Timespan"
34
34
  export * from "./models/IPAddress"
35
+ export * from "./models/OTPGenerator"
35
36
 
36
37
 
@@ -0,0 +1,12 @@
1
+ import { Timespan } from './Timespan';
2
+ export declare class OTPGenerator {
3
+ private passkey;
4
+ private length;
5
+ constructor(passkey: string, length?: number);
6
+ generateOTP(): string;
7
+ validateOTP(otp: string): boolean;
8
+ age(otp: string): Timespan;
9
+ private generateOTPWithNonce;
10
+ private isValid;
11
+ private extractNonce;
12
+ }
@@ -0,0 +1,69 @@
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.OTPGenerator = void 0;
27
+ const crypto = __importStar(require("crypto"));
28
+ const Timespan_1 = require("./Timespan");
29
+ class OTPGenerator {
30
+ constructor(passkey, length = 4) {
31
+ this.passkey = passkey;
32
+ this.length = length;
33
+ }
34
+ // Generate OTP with the current timestamp as nonce
35
+ generateOTP() {
36
+ return this.generateOTPWithNonce(Date.now());
37
+ }
38
+ // Validate if the OTP matches by extracting the nonce and regenerating OTP
39
+ validateOTP(otp) {
40
+ if (!this.isValid(otp))
41
+ return false; // Validate plausibility of OTP
42
+ const nonce = this.extractNonce(otp);
43
+ return otp === this.generateOTPWithNonce(nonce);
44
+ }
45
+ // Get the age of the OTP compared to now
46
+ age(otp) {
47
+ if (!this.isValid(otp))
48
+ throw new Error('Invalid OTP');
49
+ const nonce = this.extractNonce(otp);
50
+ return new Timespan_1.Timespan(Date.now() - nonce);
51
+ }
52
+ // Helper to generate OTP based on a specific nonce
53
+ generateOTPWithNonce(nonce) {
54
+ const hash = crypto.createHmac('sha256', this.passkey).update(nonce.toString()).digest('hex');
55
+ const otp = [...hash.slice(0, this.length)].map(char => String.fromCharCode((parseInt(char, 16) % 26) + 97)).join('');
56
+ return `${otp}${nonce.toString(16).padStart(13, '0')}`;
57
+ }
58
+ // Private helper to validate plausibility of OTP
59
+ isValid(otp) {
60
+ return otp.length === this.length + 13;
61
+ }
62
+ // Private helper to extract the nonce from the OTP
63
+ extractNonce(otp) {
64
+ const nonceHex = otp.slice(-13);
65
+ return parseInt(nonceHex, 16);
66
+ }
67
+ }
68
+ exports.OTPGenerator = OTPGenerator;
69
+ //# sourceMappingURL=OTPGenerator.js.map
@@ -0,0 +1,42 @@
1
+ import { OTPGenerator } from './OTPGenerator';
2
+ import { wait } from './../funcs/wait';
3
+ import { Timespan } from './Timespan';
4
+
5
+ const passkey = 'hiowi3rmpewr34';
6
+ describe('OTPGenerator', () => {
7
+ it('should generate OTP', () => {
8
+ const otpGenerator = new OTPGenerator(passkey, 5);
9
+ const otp = otpGenerator.generateOTP();
10
+ // length should be 5 + 13
11
+ expect(otp.length).toBe(18);
12
+ console.log(otp);
13
+ })
14
+
15
+ it('should generate different OTPs in milliseconds', async () => {
16
+ const otpGenerator = new OTPGenerator(passkey, 5);
17
+ const otp1 = otpGenerator.generateOTP()
18
+ await wait(1/1000);
19
+ const otp2 = otpGenerator.generateOTP();
20
+ expect(otp1).not.toBe(otp2);
21
+ })
22
+
23
+ it('should generate different OTPs in milliseconds per password', async () => {
24
+ const otpGenerator1 = new OTPGenerator(passkey+'1', 5);
25
+ const otpGenerator2 = new OTPGenerator(passkey+'2', 5);
26
+ for(let i=0; i<10000; i++) {
27
+ const otp1 = otpGenerator1.generateOTP()
28
+ const otp2 = otpGenerator2.generateOTP();
29
+ expect(otp1).not.toBe(otp2);
30
+ }
31
+ })
32
+
33
+ it('age should be milliseconds since generation', async () => {
34
+ const otpGenerator = new OTPGenerator(passkey, 5);
35
+ const otp = otpGenerator.generateOTP();
36
+ await wait(1/1000);
37
+ const age = otpGenerator.age(otp);
38
+ expect(age).toBeInstanceOf(Timespan);
39
+ expect(age.miliseconds).toBeGreaterThan(0);
40
+ expect(age.miliseconds).toBeLessThan(100);
41
+ })
42
+ });
@@ -0,0 +1,44 @@
1
+ import * as crypto from 'crypto';
2
+ import { Timespan } from './Timespan';
3
+
4
+
5
+ export class OTPGenerator {
6
+ constructor(private passkey: string, private length: number = 4) {}
7
+
8
+ // Generate OTP with the current timestamp as nonce
9
+ public generateOTP(): string {
10
+ return this.generateOTPWithNonce(Date.now());
11
+ }
12
+
13
+ // Validate if the OTP matches by extracting the nonce and regenerating OTP
14
+ public validateOTP(otp: string): boolean {
15
+ if (!this.isValid(otp)) return false; // Validate plausibility of OTP
16
+ const nonce = this.extractNonce(otp);
17
+ return otp === this.generateOTPWithNonce(nonce);
18
+ }
19
+
20
+ // Get the age of the OTP compared to now
21
+ public age(otp: string): Timespan {
22
+ if (!this.isValid(otp)) throw new Error('Invalid OTP');
23
+ const nonce = this.extractNonce(otp);
24
+ return new Timespan(Date.now() - nonce)
25
+ }
26
+
27
+ // Helper to generate OTP based on a specific nonce
28
+ private generateOTPWithNonce(nonce: number): string {
29
+ const hash = crypto.createHmac('sha256', this.passkey).update(nonce.toString()).digest('hex');
30
+ const otp = [...hash.slice(0, this.length)].map(char => String.fromCharCode((parseInt(char, 16) % 26) + 97)).join('');
31
+ return `${otp}${nonce.toString(16).padStart(13, '0')}`;
32
+ }
33
+
34
+ // Private helper to validate plausibility of OTP
35
+ private isValid(otp: string): boolean {
36
+ return otp.length === this.length + 13;
37
+ }
38
+
39
+ // Private helper to extract the nonce from the OTP
40
+ private extractNonce(otp: string): number {
41
+ const nonceHex = otp.slice(-13);
42
+ return parseInt(nonceHex, 16);
43
+ }
44
+ }