@mytmpvpn/mytmpvpn-common 2.1.0 → 2.1.2

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,24 @@
1
+ export declare namespace env {
2
+ const browser: boolean;
3
+ const es2021: boolean;
4
+ }
5
+ declare const _extends: string[];
6
+ export { _extends as extends };
7
+ export declare const parser: string;
8
+ export declare const plugins: string[];
9
+ export declare const root: boolean;
10
+ export declare const overrides: {
11
+ env: {
12
+ node: boolean;
13
+ };
14
+ files: string[];
15
+ parserOptions: {
16
+ sourceType: string;
17
+ };
18
+ }[];
19
+ export declare namespace parserOptions {
20
+ const ecmaVersion: string;
21
+ const project: string;
22
+ const sourceType: string;
23
+ }
24
+ export declare const rules: {};
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ module.exports = {
3
+ env: {
4
+ browser: true,
5
+ es2021: true
6
+ },
7
+ extends: ['standard-with-typescript', 'eslint:recommended', 'plugin:@typescript-eslint/recommended'],
8
+ parser: '@typescript-eslint/parser',
9
+ plugins: ['@typescript-eslint'],
10
+ root: true,
11
+ overrides: [
12
+ {
13
+ env: {
14
+ node: true
15
+ },
16
+ files: [
17
+ '.eslintrc.{js,cjs}'
18
+ ],
19
+ parserOptions: {
20
+ sourceType: 'script'
21
+ }
22
+ }
23
+ ],
24
+ parserOptions: {
25
+ ecmaVersion: 'latest',
26
+ project: './tsconfig.json',
27
+ sourceType: 'module'
28
+ },
29
+ rules: {}
30
+ };
@@ -0,0 +1,6 @@
1
+ export const testEnvironment: string;
2
+ export const roots: string[];
3
+ export const testMatch: string[];
4
+ export const transform: {
5
+ '^.+\\.tsx?$': string;
6
+ };
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ module.exports = {
3
+ testEnvironment: 'node',
4
+ roots: ['<rootDir>/test'],
5
+ testMatch: ['**/*.test.ts'],
6
+ transform: {
7
+ '^.+\\.tsx?$': 'ts-jest'
8
+ }
9
+ };
@@ -3,6 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PEANUTS_CONFIG = void 0;
4
4
  const PEANUTS_CONFIG = {
5
5
  min: 5,
6
- max: 100,
6
+ max: 100
7
7
  };
8
8
  exports.PEANUTS_CONFIG = PEANUTS_CONFIG;
@@ -4,20 +4,20 @@ interface UserVpn {
4
4
  version: number;
5
5
  vpn: vpn.Vpn;
6
6
  }
7
- type newUserVpnParams = {
7
+ interface newUserVpnParams {
8
8
  userId: string;
9
9
  region: string;
10
10
  version?: number;
11
- config?: any;
12
- state?: any;
13
- };
14
- type getUserVpnFromParams = {
11
+ config: vpn.VpnConfig;
12
+ state: vpn.VpnState;
13
+ }
14
+ interface getUserVpnFromParams {
15
15
  userId: string;
16
16
  vpnId: string;
17
17
  version?: number;
18
- config?: any;
19
- state?: any;
20
- };
18
+ config: vpn.VpnConfig;
19
+ state: vpn.VpnState;
20
+ }
21
21
  declare function newUserVpn({ userId, region, version, ...rest }: newUserVpnParams): UserVpn;
22
22
  declare function getUserVpnFrom({ userId, vpnId, version, ...rest }: getUserVpnFromParams): UserVpn;
23
- export { UserVpn, newUserVpn, getUserVpnFrom };
23
+ export { type UserVpn, newUserVpn, getUserVpnFrom };
@@ -5,16 +5,16 @@ const vpn = require("./vpn");
5
5
  const INITIAL_VERSION = 0;
6
6
  function newUserVpn({ userId, region, version = INITIAL_VERSION, ...rest }) {
7
7
  return {
8
- userId: userId,
9
- version: version,
8
+ userId,
9
+ version,
10
10
  vpn: vpn.newVpn(region, rest.config, rest.state)
11
11
  };
12
12
  }
13
13
  exports.newUserVpn = newUserVpn;
14
14
  function getUserVpnFrom({ userId, vpnId, version = INITIAL_VERSION, ...rest }) {
15
15
  return {
16
- userId: userId,
17
- version: version,
16
+ userId,
17
+ version,
18
18
  vpn: vpn.getVpnFrom(vpnId, rest.state, rest.config)
19
19
  };
20
20
  }
@@ -10,7 +10,6 @@ declare enum VpnState {
10
10
  }
11
11
  declare function rank(state: VpnState): number;
12
12
  declare enum VpnType {
13
- OpenVpn = "openvpn",
14
13
  WireGuard = "wireguard"
15
14
  }
16
15
  interface VpnConfig {
@@ -32,4 +31,5 @@ interface Vpn {
32
31
  declare function getVpnConfigTypes(): VpnType[];
33
32
  declare function newVpn(region: string, config: VpnConfig, state: VpnState): Vpn;
34
33
  declare function getVpnFrom(vpnId: string, state: VpnState, config: VpnConfig): Vpn;
35
- export { VpnState, VpnMetrics, VpnType, VpnConfig, Vpn, rank, newVpn, getVpnFrom, getVpnConfigTypes };
34
+ declare function vpnIdToWgFileName(vpnId: string): string;
35
+ export { VpnState, type VpnMetrics, VpnType, type VpnConfig, type Vpn, rank, newVpn, getVpnFrom, getVpnConfigTypes, vpnIdToWgFileName };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getVpnConfigTypes = exports.getVpnFrom = exports.newVpn = exports.rank = exports.VpnType = exports.VpnState = void 0;
3
+ exports.vpnIdToWgFileName = exports.getVpnConfigTypes = exports.getVpnFrom = exports.newVpn = exports.rank = exports.VpnType = exports.VpnState = void 0;
4
4
  var VpnState;
5
5
  (function (VpnState) {
6
6
  VpnState["Failed"] = "Failed";
@@ -20,7 +20,6 @@ function rank(state) {
20
20
  exports.rank = rank;
21
21
  var VpnType;
22
22
  (function (VpnType) {
23
- VpnType["OpenVpn"] = "openvpn";
24
23
  VpnType["WireGuard"] = "wireguard";
25
24
  })(VpnType || (VpnType = {}));
26
25
  exports.VpnType = VpnType;
@@ -30,37 +29,51 @@ function getVpnConfigTypes() {
30
29
  });
31
30
  }
32
31
  exports.getVpnConfigTypes = getVpnConfigTypes;
32
+ function throwIfNotValidVpnId(vpnId) {
33
+ // e.g: YYYYMMDDHHmmssmss@az-test-7
34
+ if (!/\d{4}[01]\d[0-3]\d[0-2]\d[0-5]\d[0-5]\d\d{3}@[a-z]{2}-[a-z]+-\d/.test(vpnId)) {
35
+ throw new Error(`Incorrect vpnId: \'${vpnId}\'`);
36
+ }
37
+ }
33
38
  function newVpn(region, config, state) {
39
+ // e.g: ap-northeast-3
40
+ if (!/[a-z]{2}-[a-z]+-[1-9]+/.test(region)) {
41
+ throw new Error(`Incorrect region: \'${region}\'`);
42
+ }
34
43
  const createdAt = new Date();
35
- // Replace ':' in the id as it's forbiden in DDB
36
44
  const vpnId = `${dateToId(createdAt)}@${region}`;
45
+ // Assert we will be able to deserialize later on...
46
+ throwIfNotValidVpnId(vpnId);
37
47
  return {
38
- vpnId: vpnId,
39
- createdAt: createdAt,
40
- region: region,
41
- config: config,
42
- state: state,
48
+ vpnId,
49
+ createdAt,
50
+ region,
51
+ config,
52
+ state
43
53
  };
44
54
  }
45
55
  exports.newVpn = newVpn;
46
56
  function getVpnFrom(vpnId, state, config) {
57
+ throwIfNotValidVpnId(vpnId);
47
58
  const tokens = vpnId.split('@');
48
59
  if (tokens.length !== 2) {
49
- throw new Error(`Bad vpnId format: ${vpnId}`);
60
+ throw new Error(`Incorrect vpnId: ${vpnId}`);
50
61
  }
62
+ /* eslint-disable @typescript-eslint/no-non-null-assertion */
51
63
  const createdAt = idToDate(tokens[0]);
52
64
  const region = tokens[1];
65
+ /* eslint-enable @typescript-eslint/no-non-null-assertion */
53
66
  return {
54
- vpnId: vpnId,
55
- createdAt: createdAt,
56
- region: region,
57
- config: config,
58
- state: state,
67
+ vpnId,
68
+ createdAt,
69
+ region,
70
+ config,
71
+ state
59
72
  };
60
73
  }
61
74
  exports.getVpnFrom = getVpnFrom;
62
- // Using a date from an id is convenient for debugging.
63
- // We can't use Date.toISOString() because some characters are forbidden
75
+ // Using a date from an id is convenient for debugging.
76
+ // We can't use Date.toISOString() because some characters are forbidden
64
77
  // E.g: SFn refuse the ':'
65
78
  // So we need convertor back and forth
66
79
  function dateToId(date) {
@@ -78,3 +91,60 @@ function idToDate(id) {
78
91
  const millis = id.substring(14);
79
92
  return new Date(`${year}-${month}-${day}T${hour}:${minute}:${second}.${millis}Z`);
80
93
  }
94
+ // The WireGuard Mobile Application has requirements for the wireguard configuration file:
95
+ // 1. must have extension '.conf'
96
+ // 2. file name must match the following regexp: "[a-zA-Z0-9_=+.-]{1,15}")
97
+ // https://git.zx2c4.com/wireguard-android/tree/tunnel/src/main/java/com/wireguard/android/backend/Tunnel.java#n19
98
+ // This function is to transform from vpnIn to Wireguard mobile application requirements
99
+ function vpnIdToWgFileName(vpnId) {
100
+ throwIfNotValidVpnId(vpnId);
101
+ // The vpnId is made of YYYYMMDDHHmmssmss@region
102
+ // Let's keep it simple: vpn is mostly temporary, so keeping
103
+ // the year is useless.
104
+ // Also the milliseconds are useless.
105
+ // Finally, the region itself is of the following format: ap-northeast-3
106
+ // We can compressing with something like:
107
+ // MMDDHHmmssapne3.conf
108
+ const ddhhmmss = vpnId.substring(4, 14);
109
+ const seps = vpnId.substring(18).split(/-/);
110
+ const ccld = seps[0];
111
+ let location;
112
+ switch (seps[1]) {
113
+ case 'north':
114
+ location = 'n';
115
+ break;
116
+ case 'northeast':
117
+ location = 'ne';
118
+ break;
119
+ case 'east':
120
+ location = 'e';
121
+ break;
122
+ case 'southeast':
123
+ location = 'se';
124
+ break;
125
+ case 'south':
126
+ location = 's';
127
+ break;
128
+ case 'southwest':
129
+ location = 'sw';
130
+ break;
131
+ case 'west':
132
+ location = 'w';
133
+ break;
134
+ case 'northwest':
135
+ location = 'nw';
136
+ break;
137
+ case 'central':
138
+ location = 'c';
139
+ break;
140
+ default:
141
+ '';
142
+ break;
143
+ }
144
+ const number = seps[2];
145
+ // Let's make sure the end file is of 15 char max
146
+ const result = `${ddhhmmss}${ccld}${location}${number}`.substring(0, 15);
147
+ console.log(`Transforming ${vpnId} to ${result}`);
148
+ return result;
149
+ }
150
+ exports.vpnIdToWgFileName = vpnIdToWgFileName;
@@ -1,4 +1,4 @@
1
1
  declare function getFromEnvOrThrow(env: string): string;
2
2
  declare function choose(choices: any[]): any;
3
- declare function sleep(millis: number): Promise<unknown>;
3
+ declare function sleep(millis: number): Promise<void>;
4
4
  export { getFromEnvOrThrow, choose, sleep };
package/dist/src/utils.js CHANGED
@@ -4,19 +4,20 @@ exports.sleep = exports.choose = exports.getFromEnvOrThrow = void 0;
4
4
  const log = require("loglevel");
5
5
  function getFromEnvOrThrow(env) {
6
6
  const result = process.env[env];
7
- if (!result) {
7
+ if (result === null || result === undefined || result.trim() === '') {
8
8
  throw new Error(`${env} unset in environment!`);
9
9
  }
10
10
  log.debug(`Using ${env} = ${result}`);
11
11
  return result;
12
12
  }
13
13
  exports.getFromEnvOrThrow = getFromEnvOrThrow;
14
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
14
15
  function choose(choices) {
15
- var index = Math.floor(Math.random() * choices.length);
16
+ const index = Math.floor(Math.random() * choices.length);
16
17
  return choices[index];
17
18
  }
18
19
  exports.choose = choose;
19
- function sleep(millis) {
20
- return new Promise(resolve => setTimeout(resolve, millis));
20
+ async function sleep(millis) {
21
+ await new Promise(resolve => setTimeout(resolve, millis));
21
22
  }
22
23
  exports.sleep = sleep;
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const vpn_1 = require("../src/models/vpn");
4
4
  describe('Testing VpnState', () => {
5
- it("should check that all VpnState are ordered properly", async () => {
5
+ it('should check that all VpnState are ordered properly', async () => {
6
6
  expect((0, vpn_1.rank)(vpn_1.VpnState.Creating) <= (0, vpn_1.rank)(vpn_1.VpnState.Created)).toBe(true);
7
7
  expect((0, vpn_1.rank)(vpn_1.VpnState.Created) <= (0, vpn_1.rank)(vpn_1.VpnState.Provisioning)).toBe(true);
8
8
  expect((0, vpn_1.rank)(vpn_1.VpnState.Provisioning) <= (0, vpn_1.rank)(vpn_1.VpnState.Running)).toBe(true);
@@ -11,3 +11,55 @@ describe('Testing VpnState', () => {
11
11
  expect((0, vpn_1.rank)(vpn_1.VpnState.Deprovisioning) <= (0, vpn_1.rank)(vpn_1.VpnState.Deleted)).toBe(true);
12
12
  });
13
13
  });
14
+ describe('Testing Vpn constructors', () => {
15
+ it('Should shout when regions is empty', async () => {
16
+ expect(() => (0, vpn_1.newVpn)('', { maxPeanuts: -1, type: vpn_1.VpnType.WireGuard }, vpn_1.VpnState.Created))
17
+ .toThrow(new Error("Incorrect region: \'\'"));
18
+ });
19
+ it('Should shout when regions is bad format', async () => {
20
+ expect(() => (0, vpn_1.newVpn)('foo', { maxPeanuts: -1, type: vpn_1.VpnType.WireGuard }, vpn_1.VpnState.Created))
21
+ .toThrow(new Error("Incorrect region: \'foo\'"));
22
+ });
23
+ it('Should create vpn with all fields set', async () => {
24
+ const vpn = (0, vpn_1.newVpn)('az-test-7', { maxPeanuts: -1, type: vpn_1.VpnType.WireGuard }, vpn_1.VpnState.Created);
25
+ expect(vpn.createdAt).toBeDefined();
26
+ expect(vpn.region).toEqual('az-test-7');
27
+ expect(vpn.state).toEqual(vpn_1.VpnState.Created);
28
+ expect(vpn.config).toEqual({ maxPeanuts: -1, type: vpn_1.VpnType.WireGuard });
29
+ expect(vpn.vpnId).toBeDefined();
30
+ });
31
+ it('Should deserialize a vpn with all fields set', async () => {
32
+ const vpn = (0, vpn_1.getVpnFrom)('20030902012345678@az-test-7', vpn_1.VpnState.Created, { maxPeanuts: -1, type: vpn_1.VpnType.WireGuard });
33
+ expect(vpn.createdAt).toEqual(new Date('2003-09-02T01:23:45.678Z'));
34
+ expect(vpn.region).toEqual('az-test-7');
35
+ expect(vpn.state).toEqual(vpn_1.VpnState.Created);
36
+ expect(vpn.config).toEqual({ maxPeanuts: -1, type: vpn_1.VpnType.WireGuard });
37
+ expect(vpn.vpnId).toBeDefined();
38
+ });
39
+ it('Should shout when vpnId is empty', async () => {
40
+ expect(() => (0, vpn_1.getVpnFrom)('', vpn_1.VpnState.Created, { maxPeanuts: -1, type: vpn_1.VpnType.WireGuard }))
41
+ .toThrow(new Error("Incorrect vpnId: \'\'"));
42
+ });
43
+ it('Should shout when vpnId has bad format', async () => {
44
+ expect(() => (0, vpn_1.getVpnFrom)('foo', vpn_1.VpnState.Created, { maxPeanuts: -1, type: vpn_1.VpnType.WireGuard }))
45
+ .toThrow(new Error("Incorrect vpnId: \'foo\'"));
46
+ });
47
+ it('Should shout when vpnId does not hold a region in good format', async () => {
48
+ expect(() => (0, vpn_1.getVpnFrom)('20030902012345678@test', vpn_1.VpnState.Created, { maxPeanuts: -1, type: vpn_1.VpnType.WireGuard }))
49
+ .toThrow(new Error("Incorrect vpnId: \'20030902012345678@test\'"));
50
+ });
51
+ });
52
+ describe('Testing vpnId to Wireguard file name functions ', () => {
53
+ it('Should shout when vpnId is empty', async () => {
54
+ expect(() => (0, vpn_1.vpnIdToWgFileName)(''))
55
+ .toThrow(new Error("Incorrect vpnId: \'\'"));
56
+ });
57
+ it('Should shout when vpnId is bad format', async () => {
58
+ expect(() => (0, vpn_1.vpnIdToWgFileName)('foo'))
59
+ .toThrow(new Error("Incorrect vpnId: \'foo\'"));
60
+ });
61
+ it('Should shout when region has bad format', async () => {
62
+ expect(() => (0, vpn_1.vpnIdToWgFileName)('20030902012345678@test'))
63
+ .toThrow(new Error("Incorrect vpnId: \'20030902012345678@test\'"));
64
+ });
65
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mytmpvpn/mytmpvpn-common",
3
- "version": "2.1.0",
3
+ "version": "2.1.2",
4
4
  "description": "Common library for all MyTmpVpn related projects",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [