mybase 1.1.42 → 1.1.44

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