@lockerpm/desktop-service 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.
Files changed (158) hide show
  1. package/README.md +98 -0
  2. package/lib/cjs/abstractions/api.service.js +2 -0
  3. package/lib/cjs/abstractions/crypto.service.js +147 -0
  4. package/lib/cjs/abstractions/errors.js +99 -0
  5. package/lib/cjs/abstractions/event.service.js +2 -0
  6. package/lib/cjs/abstractions/index.js +2 -0
  7. package/lib/cjs/abstractions/socket.service.js +11 -0
  8. package/lib/cjs/abstractions/storage.service.js +2 -0
  9. package/lib/cjs/index.js +243 -0
  10. package/lib/cjs/misc/config.js +15 -0
  11. package/lib/cjs/misc/utils.js +37 -0
  12. package/lib/cjs/proto/google/api/annotations.js +2 -0
  13. package/lib/cjs/proto/google/api/http.js +477 -0
  14. package/lib/cjs/proto/google/protobuf/descriptor.js +4873 -0
  15. package/lib/cjs/proto/locker-service-grpc.js +1915 -0
  16. package/lib/cjs/services/api.service.js +182 -0
  17. package/lib/cjs/services/cache.service.js +50 -0
  18. package/lib/cjs/services/core-crypto.service.js +193 -0
  19. package/lib/cjs/services/crypto.service.js +101 -0
  20. package/lib/cjs/services/event.service.js +31 -0
  21. package/lib/cjs/services/fido.service.js +136 -0
  22. package/lib/cjs/services/grpc.service.js +130 -0
  23. package/lib/cjs/services/log.service.js +30 -0
  24. package/lib/cjs/services/pairing.service.js +122 -0
  25. package/lib/cjs/services/socket.service.js +280 -0
  26. package/lib/cjs/services/user.service.js +134 -0
  27. package/lib/cjs/types/abstractions/api.service.d.ts +40 -0
  28. package/lib/cjs/types/abstractions/api.service.d.ts.map +1 -0
  29. package/lib/cjs/types/abstractions/crypto.service.d.ts +46 -0
  30. package/lib/cjs/types/abstractions/crypto.service.d.ts.map +1 -0
  31. package/lib/cjs/types/abstractions/errors.d.ts +73 -0
  32. package/lib/cjs/types/abstractions/errors.d.ts.map +1 -0
  33. package/lib/cjs/types/abstractions/event.service.d.ts +23 -0
  34. package/lib/cjs/types/abstractions/event.service.d.ts.map +1 -0
  35. package/lib/cjs/types/abstractions/index.d.ts +56 -0
  36. package/lib/cjs/types/abstractions/index.d.ts.map +1 -0
  37. package/lib/cjs/types/abstractions/socket.service.d.ts +52 -0
  38. package/lib/cjs/types/abstractions/socket.service.d.ts.map +1 -0
  39. package/lib/cjs/types/abstractions/storage.service.d.ts +6 -0
  40. package/lib/cjs/types/abstractions/storage.service.d.ts.map +1 -0
  41. package/lib/cjs/types/index.d.ts +164 -0
  42. package/lib/cjs/types/index.d.ts.map +1 -0
  43. package/lib/cjs/types/misc/config.d.ts +6 -0
  44. package/lib/cjs/types/misc/config.d.ts.map +1 -0
  45. package/lib/cjs/types/misc/utils.d.ts +21 -0
  46. package/lib/cjs/types/misc/utils.d.ts.map +1 -0
  47. package/lib/cjs/types/proto/google/api/annotations.d.ts +2 -0
  48. package/lib/cjs/types/proto/google/api/annotations.d.ts.map +1 -0
  49. package/lib/cjs/types/proto/google/api/http.d.ts +195 -0
  50. package/lib/cjs/types/proto/google/api/http.d.ts.map +1 -0
  51. package/lib/cjs/types/proto/google/protobuf/descriptor.d.ts +3409 -0
  52. package/lib/cjs/types/proto/google/protobuf/descriptor.d.ts.map +1 -0
  53. package/lib/cjs/types/proto/locker-service-grpc.d.ts +622 -0
  54. package/lib/cjs/types/proto/locker-service-grpc.d.ts.map +1 -0
  55. package/lib/cjs/types/services/api.service.d.ts +37 -0
  56. package/lib/cjs/types/services/api.service.d.ts.map +1 -0
  57. package/lib/cjs/types/services/cache.service.d.ts +10 -0
  58. package/lib/cjs/types/services/cache.service.d.ts.map +1 -0
  59. package/lib/cjs/types/services/core-crypto.service.d.ts +17 -0
  60. package/lib/cjs/types/services/core-crypto.service.d.ts.map +1 -0
  61. package/lib/cjs/types/services/crypto.service.d.ts +23 -0
  62. package/lib/cjs/types/services/crypto.service.d.ts.map +1 -0
  63. package/lib/cjs/types/services/event.service.d.ts +14 -0
  64. package/lib/cjs/types/services/event.service.d.ts.map +1 -0
  65. package/lib/cjs/types/services/fido.service.d.ts +40 -0
  66. package/lib/cjs/types/services/fido.service.d.ts.map +1 -0
  67. package/lib/cjs/types/services/grpc.service.d.ts +34 -0
  68. package/lib/cjs/types/services/grpc.service.d.ts.map +1 -0
  69. package/lib/cjs/types/services/log.service.d.ts +13 -0
  70. package/lib/cjs/types/services/log.service.d.ts.map +1 -0
  71. package/lib/cjs/types/services/pairing.service.d.ts +37 -0
  72. package/lib/cjs/types/services/pairing.service.d.ts.map +1 -0
  73. package/lib/cjs/types/services/socket.service.d.ts +39 -0
  74. package/lib/cjs/types/services/socket.service.d.ts.map +1 -0
  75. package/lib/cjs/types/services/user.service.d.ts +32 -0
  76. package/lib/cjs/types/services/user.service.d.ts.map +1 -0
  77. package/lib/cjs/types/usecases/fido.d.ts +54 -0
  78. package/lib/cjs/types/usecases/fido.d.ts.map +1 -0
  79. package/lib/cjs/usecases/fido.js +227 -0
  80. package/lib/esm/abstractions/api.service.js +2 -0
  81. package/lib/esm/abstractions/crypto.service.js +165 -0
  82. package/lib/esm/abstractions/errors.js +100 -0
  83. package/lib/esm/abstractions/event.service.js +2 -0
  84. package/lib/esm/abstractions/index.js +2 -0
  85. package/lib/esm/abstractions/socket.service.js +11 -0
  86. package/lib/esm/abstractions/storage.service.js +2 -0
  87. package/lib/esm/index.mjs +227 -0
  88. package/lib/esm/misc/config.js +15 -0
  89. package/lib/esm/misc/utils.js +37 -0
  90. package/lib/esm/proto/google/api/annotations.js +2 -0
  91. package/lib/esm/proto/google/api/http.js +468 -0
  92. package/lib/esm/proto/google/protobuf/descriptor.js +4830 -0
  93. package/lib/esm/proto/locker-service-grpc.js +1892 -0
  94. package/lib/esm/services/api.service.js +177 -0
  95. package/lib/esm/services/cache.service.js +52 -0
  96. package/lib/esm/services/core-crypto.service.js +164 -0
  97. package/lib/esm/services/crypto.service.js +83 -0
  98. package/lib/esm/services/event.service.js +33 -0
  99. package/lib/esm/services/fido.service.js +139 -0
  100. package/lib/esm/services/grpc.service.js +119 -0
  101. package/lib/esm/services/log.service.js +31 -0
  102. package/lib/esm/services/pairing.service.js +107 -0
  103. package/lib/esm/services/socket.service.js +265 -0
  104. package/lib/esm/services/user.service.js +116 -0
  105. package/lib/esm/types/abstractions/api.service.d.ts +40 -0
  106. package/lib/esm/types/abstractions/api.service.d.ts.map +1 -0
  107. package/lib/esm/types/abstractions/crypto.service.d.ts +46 -0
  108. package/lib/esm/types/abstractions/crypto.service.d.ts.map +1 -0
  109. package/lib/esm/types/abstractions/errors.d.ts +73 -0
  110. package/lib/esm/types/abstractions/errors.d.ts.map +1 -0
  111. package/lib/esm/types/abstractions/event.service.d.ts +23 -0
  112. package/lib/esm/types/abstractions/event.service.d.ts.map +1 -0
  113. package/lib/esm/types/abstractions/index.d.ts +56 -0
  114. package/lib/esm/types/abstractions/index.d.ts.map +1 -0
  115. package/lib/esm/types/abstractions/socket.service.d.ts +52 -0
  116. package/lib/esm/types/abstractions/socket.service.d.ts.map +1 -0
  117. package/lib/esm/types/abstractions/storage.service.d.ts +6 -0
  118. package/lib/esm/types/abstractions/storage.service.d.ts.map +1 -0
  119. package/lib/esm/types/index.d.ts +164 -0
  120. package/lib/esm/types/index.d.ts.map +1 -0
  121. package/lib/esm/types/misc/config.d.ts +6 -0
  122. package/lib/esm/types/misc/config.d.ts.map +1 -0
  123. package/lib/esm/types/misc/utils.d.ts +21 -0
  124. package/lib/esm/types/misc/utils.d.ts.map +1 -0
  125. package/lib/esm/types/proto/google/api/annotations.d.ts +2 -0
  126. package/lib/esm/types/proto/google/api/annotations.d.ts.map +1 -0
  127. package/lib/esm/types/proto/google/api/http.d.ts +195 -0
  128. package/lib/esm/types/proto/google/api/http.d.ts.map +1 -0
  129. package/lib/esm/types/proto/google/protobuf/descriptor.d.ts +3409 -0
  130. package/lib/esm/types/proto/google/protobuf/descriptor.d.ts.map +1 -0
  131. package/lib/esm/types/proto/locker-service-grpc.d.ts +622 -0
  132. package/lib/esm/types/proto/locker-service-grpc.d.ts.map +1 -0
  133. package/lib/esm/types/services/api.service.d.ts +37 -0
  134. package/lib/esm/types/services/api.service.d.ts.map +1 -0
  135. package/lib/esm/types/services/cache.service.d.ts +10 -0
  136. package/lib/esm/types/services/cache.service.d.ts.map +1 -0
  137. package/lib/esm/types/services/core-crypto.service.d.ts +17 -0
  138. package/lib/esm/types/services/core-crypto.service.d.ts.map +1 -0
  139. package/lib/esm/types/services/crypto.service.d.ts +23 -0
  140. package/lib/esm/types/services/crypto.service.d.ts.map +1 -0
  141. package/lib/esm/types/services/event.service.d.ts +14 -0
  142. package/lib/esm/types/services/event.service.d.ts.map +1 -0
  143. package/lib/esm/types/services/fido.service.d.ts +40 -0
  144. package/lib/esm/types/services/fido.service.d.ts.map +1 -0
  145. package/lib/esm/types/services/grpc.service.d.ts +34 -0
  146. package/lib/esm/types/services/grpc.service.d.ts.map +1 -0
  147. package/lib/esm/types/services/log.service.d.ts +13 -0
  148. package/lib/esm/types/services/log.service.d.ts.map +1 -0
  149. package/lib/esm/types/services/pairing.service.d.ts +37 -0
  150. package/lib/esm/types/services/pairing.service.d.ts.map +1 -0
  151. package/lib/esm/types/services/socket.service.d.ts +39 -0
  152. package/lib/esm/types/services/socket.service.d.ts.map +1 -0
  153. package/lib/esm/types/services/user.service.d.ts +32 -0
  154. package/lib/esm/types/services/user.service.d.ts.map +1 -0
  155. package/lib/esm/types/usecases/fido.d.ts +54 -0
  156. package/lib/esm/types/usecases/fido.d.ts.map +1 -0
  157. package/lib/esm/usecases/fido.js +201 -0
  158. package/package.json +55 -0
package/README.md ADDED
@@ -0,0 +1,98 @@
1
+ # Locker Desktop Service Supporter for Desktop app
2
+
3
+ ## Installation
4
+
5
+ Install from npm:
6
+
7
+ ```bash
8
+ npm install -S locker-desktop-service
9
+ ```
10
+
11
+ Install from yarn:
12
+
13
+ ```bash
14
+ yarn add locker-desktop-service
15
+ ```
16
+
17
+ ## Usages
18
+
19
+ This supporter service requires Node.js to work -> If you use this service in Electron, it must be running in main process and calling method through `ipcMain.handle()` and `ipcRenderer.invoke()`
20
+
21
+ ```js
22
+ import { DesktopService, StorageService } from 'locker-desktop-service'
23
+ import fs from 'fs'
24
+ import path from 'path'
25
+ import Store from 'electron-store'
26
+
27
+ // Storing data secure data using electron-store, you can use others secure storage
28
+ // or simply keep data in memory only
29
+ class MockStorageService implements StorageService {
30
+ storage: Store
31
+ constructor() {
32
+ this.storage = new Store()
33
+ }
34
+ getSecure(key: string) {
35
+ return Promise.resolve(this.storage.get(key) || null)
36
+ }
37
+ setSecure(key: string, data: any) {
38
+ this.storage.set(key, data)
39
+ return Promise.resolve()
40
+ }
41
+ deleteSecure(key: string) {
42
+ this.storage.delete(key)
43
+ return Promise.resolve()
44
+ }
45
+ }
46
+ const storageService = new MockStorageService()
47
+
48
+ // TLS cert is required to comunicate with the background service
49
+ const rootCert = fs.readFileSync(path.resolve(process.resourcesPath, 'cert', 'ca-cert.pem'))
50
+
51
+ // TLS cert to host WSS
52
+ const cert = fs.readFileSync(path.resolve(process.resourcesPath, 'cert', 'server-cert.pem'))
53
+ const key = fs.readFileSync(path.resolve(process.resourcesPath, 'cert', 'server-key.pem'))
54
+
55
+ // Init service
56
+ export const service = new DesktopService({
57
+ baseApiUrl: process.env.BASE_API_URL,
58
+ storageService,
59
+ ssl: {
60
+ rootCert,
61
+ },
62
+ socketSsl: {
63
+ cert,
64
+ key,
65
+ },
66
+ logLevel: 1, // 1 is error, 2 is debug
67
+ unsafe: true, // set to false to enable checksum validation
68
+ serviceAlias: '' // optional, used to compare with service alias from background service
69
+ })
70
+
71
+ // Setup listners
72
+ service.on('<event-name>', callback)
73
+ ```
74
+
75
+ ## Development
76
+
77
+ Install required packages.
78
+ ```bash
79
+ npm install
80
+ ```
81
+
82
+ ### Run tests
83
+
84
+ Create a .env file with required access keys (refer to `.env.example`)
85
+
86
+ To run all tests, use:
87
+ ```bash
88
+ npm test
89
+ ```
90
+
91
+ Run some tests only, please update `mocharc.js`:
92
+ ```js
93
+ ignore: [
94
+ // './tests/index.spec.ts', // Comment the file you want to test
95
+ './tests/crypto.spec.ts',
96
+ '...'
97
+ ]
98
+ ```
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ // @ts-nocheck
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.EncryptedObject = exports.EncString = exports.SymmetricCryptoKey = exports.EncryptionType = exports.KdfType = exports.AES = exports.ECDH = void 0;
5
+ const utils_1 = require("../misc/utils");
6
+ exports.ECDH = {
7
+ name: 'ECDH',
8
+ namedCurve: 'P-384',
9
+ };
10
+ exports.AES = {
11
+ name: 'AES-CBC',
12
+ };
13
+ // -------------- CORE --------------
14
+ var KdfType;
15
+ (function (KdfType) {
16
+ KdfType[KdfType["PBKDF2_SHA256"] = 0] = "PBKDF2_SHA256";
17
+ })(KdfType || (exports.KdfType = KdfType = {}));
18
+ var EncryptionType;
19
+ (function (EncryptionType) {
20
+ EncryptionType[EncryptionType["AesCbc256_B64"] = 0] = "AesCbc256_B64";
21
+ EncryptionType[EncryptionType["AesCbc128_HmacSha256_B64"] = 1] = "AesCbc128_HmacSha256_B64";
22
+ EncryptionType[EncryptionType["AesCbc256_HmacSha256_B64"] = 2] = "AesCbc256_HmacSha256_B64";
23
+ EncryptionType[EncryptionType["Rsa2048_OaepSha256_B64"] = 3] = "Rsa2048_OaepSha256_B64";
24
+ EncryptionType[EncryptionType["Rsa2048_OaepSha1_B64"] = 4] = "Rsa2048_OaepSha1_B64";
25
+ EncryptionType[EncryptionType["Rsa2048_OaepSha256_HmacSha256_B64"] = 5] = "Rsa2048_OaepSha256_HmacSha256_B64";
26
+ EncryptionType[EncryptionType["Rsa2048_OaepSha1_HmacSha256_B64"] = 6] = "Rsa2048_OaepSha1_HmacSha256_B64";
27
+ })(EncryptionType || (exports.EncryptionType = EncryptionType = {}));
28
+ class SymmetricCryptoKey {
29
+ constructor(key, encType) {
30
+ if (key == null) {
31
+ throw new Error('Must provide key');
32
+ }
33
+ if (encType == null) {
34
+ if (key.byteLength === 32) {
35
+ encType = EncryptionType.AesCbc256_B64;
36
+ }
37
+ else if (key.byteLength === 64) {
38
+ encType = EncryptionType.AesCbc256_HmacSha256_B64;
39
+ }
40
+ else {
41
+ throw new Error('Unable to determine encType.');
42
+ }
43
+ }
44
+ this.key = key;
45
+ this.encType = encType;
46
+ if (encType === EncryptionType.AesCbc256_B64 && key.byteLength === 32) {
47
+ this.encKey = key;
48
+ this.macKey = undefined;
49
+ }
50
+ else if (encType === EncryptionType.AesCbc128_HmacSha256_B64 && key.byteLength === 32) {
51
+ this.encKey = key.slice(0, 16);
52
+ this.macKey = key.slice(16, 32);
53
+ }
54
+ else if (encType === EncryptionType.AesCbc256_HmacSha256_B64 && key.byteLength === 64) {
55
+ this.encKey = key.slice(0, 32);
56
+ this.macKey = key.slice(32, 64);
57
+ }
58
+ else {
59
+ throw new Error('Unsupported encType/key length.');
60
+ }
61
+ if (this.key != null) {
62
+ this.keyB64 = utils_1.Utils.fromBufferToB64(this.key);
63
+ }
64
+ if (this.encKey != null) {
65
+ this.encKeyB64 = utils_1.Utils.fromBufferToB64(this.encKey);
66
+ }
67
+ if (this.macKey != null) {
68
+ this.macKeyB64 = utils_1.Utils.fromBufferToB64(this.macKey);
69
+ }
70
+ }
71
+ }
72
+ exports.SymmetricCryptoKey = SymmetricCryptoKey;
73
+ class EncString {
74
+ constructor(encryptedStringOrType, data, iv, mac) {
75
+ if (data != null) {
76
+ // data and header
77
+ const encType = encryptedStringOrType;
78
+ if (iv != null) {
79
+ this.encryptedString = encType + '.' + iv + '|' + data;
80
+ }
81
+ else {
82
+ this.encryptedString = encType + '.' + data;
83
+ }
84
+ // mac
85
+ if (mac != null) {
86
+ this.encryptedString += '|' + mac;
87
+ }
88
+ this.encryptionType = encType;
89
+ this.data = data;
90
+ this.iv = iv;
91
+ this.mac = mac;
92
+ return;
93
+ }
94
+ this.encryptedString = encryptedStringOrType;
95
+ if (!this.encryptedString) {
96
+ return;
97
+ }
98
+ const headerPieces = this.encryptedString.split('.');
99
+ let encPieces = null;
100
+ if (headerPieces.length === 2) {
101
+ try {
102
+ this.encryptionType = parseInt(headerPieces[0]);
103
+ encPieces = headerPieces[1].split('|');
104
+ }
105
+ catch (e) {
106
+ return;
107
+ }
108
+ }
109
+ else {
110
+ encPieces = this.encryptedString.split('|');
111
+ this.encryptionType =
112
+ encPieces.length === 3
113
+ ? EncryptionType.AesCbc128_HmacSha256_B64
114
+ : EncryptionType.AesCbc256_B64;
115
+ }
116
+ switch (this.encryptionType) {
117
+ case EncryptionType.AesCbc128_HmacSha256_B64:
118
+ case EncryptionType.AesCbc256_HmacSha256_B64:
119
+ if (encPieces.length !== 3) {
120
+ return;
121
+ }
122
+ this.iv = encPieces[0];
123
+ this.data = encPieces[1];
124
+ this.mac = encPieces[2];
125
+ break;
126
+ case EncryptionType.AesCbc256_B64:
127
+ if (encPieces.length !== 2) {
128
+ return;
129
+ }
130
+ this.iv = encPieces[0];
131
+ this.data = encPieces[1];
132
+ break;
133
+ case EncryptionType.Rsa2048_OaepSha256_B64:
134
+ case EncryptionType.Rsa2048_OaepSha1_B64:
135
+ if (encPieces.length !== 1) {
136
+ return;
137
+ }
138
+ this.data = encPieces[0];
139
+ break;
140
+ default:
141
+ }
142
+ }
143
+ }
144
+ exports.EncString = EncString;
145
+ class EncryptedObject {
146
+ }
147
+ exports.EncryptedObject = EncryptedObject;
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ERRORS = exports.ServiceError = void 0;
4
+ class ServiceError extends Error {
5
+ constructor(code, rawError) {
6
+ var _a, _b;
7
+ super(rawError);
8
+ this.rawError = rawError;
9
+ this.code = code;
10
+ const rawMessage = ((_b = (_a = rawError === null || rawError === void 0 ? void 0 : rawError.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.message) ||
11
+ (rawError === null || rawError === void 0 ? void 0 : rawError.message) ||
12
+ (rawError === null || rawError === void 0 ? void 0 : rawError.toString()) ||
13
+ 'Unknown error';
14
+ this.message = code === '0000' ? rawMessage : exports.ERRORS[code].message;
15
+ }
16
+ static fromError(rawError) {
17
+ var _a, _b;
18
+ const message = ((_b = (_a = rawError === null || rawError === void 0 ? void 0 : rawError.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.message) ||
19
+ (rawError === null || rawError === void 0 ? void 0 : rawError.message) ||
20
+ (rawError === null || rawError === void 0 ? void 0 : rawError.toString()) ||
21
+ 'Unknown error';
22
+ const error = ERRORS_LIST.filter((e) => !!e.signatures).find((e) => { var _a; return (_a = e.signatures) === null || _a === void 0 ? void 0 : _a.some((signature) => message.toLowerCase().includes(signature)); });
23
+ if (error) {
24
+ return new ServiceError(error.code, rawError);
25
+ }
26
+ return new ServiceError('0000', rawError);
27
+ }
28
+ }
29
+ exports.ServiceError = ServiceError;
30
+ exports.ERRORS = {
31
+ '0000': {
32
+ message: 'Unspecified error',
33
+ },
34
+ // API
35
+ '1000': {
36
+ message: 'API error',
37
+ },
38
+ '1001': {
39
+ message: 'API token not found',
40
+ },
41
+ '1002': {
42
+ message: 'Passwordless is not enabled',
43
+ },
44
+ // FIDO
45
+ '2001': {
46
+ message: 'Cannot connect to fido key',
47
+ },
48
+ '2002': {
49
+ message: 'Cannot create credential, key return empty secret',
50
+ },
51
+ '2003': {
52
+ message: 'Invalid PIN',
53
+ signatures: ['pin invalid'],
54
+ },
55
+ '2004': {
56
+ message: 'Cannot find relying party',
57
+ signatures: ['no rp'],
58
+ },
59
+ '2005': {
60
+ message: 'Cannot find any valid credential in this key',
61
+ },
62
+ '2006': {
63
+ message: 'Cannot find the required credential in this key',
64
+ signatures: ['no credentials'],
65
+ },
66
+ '2007': {
67
+ message: 'Cannot use fingerprint, please use PIN instead',
68
+ signatures: ['unsupported option', 'pin required'],
69
+ },
70
+ '2008': {
71
+ message: 'PIN validation failed to many times, key is blocked',
72
+ signatures: ['pin auth blocked'],
73
+ },
74
+ '2009': {
75
+ message: 'Failed to verify fingerprint',
76
+ signatures: ['keep alive cancel'],
77
+ },
78
+ '2010': {
79
+ message: 'List credentials is not supported on this key',
80
+ signatures: ['failed to get relying party info: invalid command'],
81
+ },
82
+ '2011': {
83
+ message: 'FIDO action timed out',
84
+ signatures: ['failed to get assertion: action timed out'],
85
+ },
86
+ // PAIRING
87
+ '3001': {
88
+ message: 'Client is not confirmed',
89
+ },
90
+ // SOCKET
91
+ '4001': {
92
+ message: 'Client not found',
93
+ },
94
+ '4002': {
95
+ message: 'Cannot broadcast secure message',
96
+ },
97
+ }; // as { [code: string]: { message: string; signatures?: string[] } }
98
+ // @ts-ignore
99
+ const ERRORS_LIST = Object.keys(exports.ERRORS).map((code) => (Object.assign({ code }, exports.ERRORS[code])));
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildOutgoingSocketMessage = void 0;
4
+ function buildOutgoingSocketMessage(message, data, secure) {
5
+ return {
6
+ message,
7
+ data,
8
+ secure,
9
+ };
10
+ }
11
+ exports.buildOutgoingSocketMessage = buildOutgoingSocketMessage;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,243 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.DesktopService = exports.ServiceErrors = void 0;
13
+ const socket_service_1 = require("./abstractions/socket.service");
14
+ const api_service_1 = require("./services/api.service");
15
+ const user_service_1 = require("./services/user.service");
16
+ const crypto_service_1 = require("./services/crypto.service");
17
+ const event_service_1 = require("./services/event.service");
18
+ const fido_service_1 = require("./services/fido.service");
19
+ const grpc_service_1 = require("./services/grpc.service");
20
+ const log_service_1 = require("./services/log.service");
21
+ const pairing_service_1 = require("./services/pairing.service");
22
+ const socket_service_2 = require("./services/socket.service");
23
+ const errors_1 = require("./abstractions/errors");
24
+ const fido_1 = require("./usecases/fido");
25
+ const cache_service_1 = require("./services/cache.service");
26
+ exports.ServiceErrors = errors_1.ERRORS;
27
+ class DesktopService {
28
+ // Constructor
29
+ constructor(params) {
30
+ this._interval = null;
31
+ const { baseApiUrl, logLevel, storageService, ssl, unsafe, apiHeaders, serviceAlias, socketSsl, } = params;
32
+ this.cryptoService = new crypto_service_1.CryptoService();
33
+ this.storageService = storageService;
34
+ this.logService = new log_service_1.LogService(logLevel);
35
+ this.eventService = new event_service_1.EventService(this.logService);
36
+ this.apiService = new api_service_1.ApiService({
37
+ baseUrl: baseApiUrl,
38
+ logger: this.logService,
39
+ headers: apiHeaders,
40
+ });
41
+ this.grpcService = new grpc_service_1.GRPCService({
42
+ logger: this.logService,
43
+ cryptoService: this.cryptoService,
44
+ apiService: this.apiService,
45
+ }, {
46
+ ssl,
47
+ unsafe,
48
+ serviceAlias: serviceAlias || '',
49
+ });
50
+ this.fidoService = new fido_service_1.FidoService(this.logService, this.eventService, this.grpcService);
51
+ this.pairingService = new pairing_service_1.PairingService({
52
+ cryptoService: this.cryptoService,
53
+ eventService: this.eventService,
54
+ storageService: this.storageService,
55
+ logger: this.logService,
56
+ grpcService: this.grpcService,
57
+ });
58
+ this.userService = new user_service_1.UserService({
59
+ logger: this.logService,
60
+ storageService: this.storageService,
61
+ grpcService: this.grpcService,
62
+ });
63
+ this.socketService = new socket_service_2.SocketService({
64
+ logger: this.logService,
65
+ pairingService: this.pairingService,
66
+ userService: this.userService,
67
+ eventService: this.eventService,
68
+ ssl: socketSsl,
69
+ serviceAlias: serviceAlias || '',
70
+ });
71
+ this.cacheService = new cache_service_1.CacheService(this.logService, this.grpcService);
72
+ this.waitUntilReady();
73
+ }
74
+ // ---------------------- READY STATE ----------------------
75
+ get isReady() {
76
+ const requiredService = [
77
+ this.grpcService,
78
+ this.userService,
79
+ this.pairingService,
80
+ this.socketService,
81
+ ];
82
+ return requiredService.reduce((isReady, service) => isReady && service.isReady, true);
83
+ }
84
+ waitUntilReady() {
85
+ return new Promise((resolve) => {
86
+ const step = 500;
87
+ const timeout = 5000;
88
+ let counter = 0;
89
+ if (this._interval) {
90
+ clearInterval(this._interval);
91
+ }
92
+ this._interval = setInterval(() => {
93
+ if (this.isReady) {
94
+ this.eventService.emit('serviceReady', undefined);
95
+ clearInterval(this._interval);
96
+ resolve(true);
97
+ return;
98
+ }
99
+ counter += step;
100
+ if (counter >= timeout) {
101
+ this.logService.error(`Service not ready after ${timeout} ms`);
102
+ clearInterval(this._interval);
103
+ resolve(false);
104
+ }
105
+ }, step);
106
+ });
107
+ }
108
+ resetSocket() {
109
+ return this.socketService.initSocket();
110
+ }
111
+ resetGRPC() {
112
+ return this.grpcService.initConnection();
113
+ }
114
+ // ---------------------- FIDO ----------------------
115
+ setApiToken(token) {
116
+ this.apiService.setToken(token);
117
+ }
118
+ getFidoDeviceList() {
119
+ return this.fidoService.getDeviceList();
120
+ }
121
+ setNewPasswordless(params) {
122
+ return (0, fido_1.setNewPasswordless)(params, {
123
+ apiService: this.apiService,
124
+ fidoService: this.fidoService,
125
+ });
126
+ }
127
+ deletePasswordless() {
128
+ return this.apiService.deletePasswordlessCredential();
129
+ }
130
+ setBackupPasswordless(params) {
131
+ return (0, fido_1.setBackupPasswordless)(params, {
132
+ apiService: this.apiService,
133
+ fidoService: this.fidoService,
134
+ cryptoService: this.cryptoService,
135
+ });
136
+ }
137
+ listAllPasswordless(email) {
138
+ return __awaiter(this, void 0, void 0, function* () {
139
+ const [mainKey, backupKeys] = yield Promise.all([
140
+ this.apiService.getPasswordlessCredentials(email),
141
+ this.apiService.listBackupPasswordlessCredentials(),
142
+ ]);
143
+ const res = [...backupKeys];
144
+ if (mainKey.credential_id) {
145
+ res.push({
146
+ id: 'primary',
147
+ name: mainKey.name || '',
148
+ creation_date: mainKey.creation_date,
149
+ last_use_date: mainKey.last_use_date,
150
+ master_password_hash: '',
151
+ key: '',
152
+ fd_credential_id: mainKey.credential_id,
153
+ fd_random: mainKey.random || '',
154
+ isPrimary: true,
155
+ type: mainKey.type,
156
+ });
157
+ }
158
+ return res;
159
+ });
160
+ }
161
+ listBackupPasswordless() {
162
+ return __awaiter(this, void 0, void 0, function* () {
163
+ return this.apiService.listBackupPasswordlessCredentials();
164
+ });
165
+ }
166
+ deleteBackupPasswordless(id) {
167
+ return __awaiter(this, void 0, void 0, function* () {
168
+ return this.apiService.deleteBackupPasswordlessCredential(id);
169
+ });
170
+ }
171
+ getPasswordless(params) {
172
+ return (0, fido_1.getPasswordless)(params, {
173
+ apiService: this.apiService,
174
+ fidoService: this.fidoService,
175
+ logService: this.logService,
176
+ });
177
+ }
178
+ // ---------------------- PAIRING ----------------------
179
+ confirmPairingClient(clientId, clientType) {
180
+ return __awaiter(this, void 0, void 0, function* () {
181
+ yield this.pairingService.confirmPairingClient(clientId, clientType === 'extension');
182
+ this.socketService.sendMessageToClient(clientId, (0, socket_service_1.buildOutgoingSocketMessage)('pairingConfirmed', undefined));
183
+ });
184
+ }
185
+ resetPairingCode(clientId) {
186
+ return __awaiter(this, void 0, void 0, function* () {
187
+ this.socketService.sendMessageToClient(clientId, (0, socket_service_1.buildOutgoingSocketMessage)('resetPairing', undefined));
188
+ });
189
+ }
190
+ sendCustomMessage(data) {
191
+ return __awaiter(this, void 0, void 0, function* () {
192
+ this.socketService.broadcastMessageToAll((0, socket_service_1.buildOutgoingSocketMessage)('customMessage', data));
193
+ });
194
+ }
195
+ getCacheData() {
196
+ return this.cacheService.getCache();
197
+ }
198
+ setCacheData(data) {
199
+ return this.cacheService.setCache(data);
200
+ }
201
+ // ---------------------- USER ----------------------
202
+ getCurrentUser() {
203
+ return this.userService.getCurrentUser();
204
+ }
205
+ login(params) {
206
+ return __awaiter(this, void 0, void 0, function* () {
207
+ yield this.userService.login(params);
208
+ this.socketService.broadcastMessageToAll((0, socket_service_1.buildOutgoingSocketMessage)('userLogin', { email: params.email }));
209
+ });
210
+ }
211
+ logout() {
212
+ return __awaiter(this, void 0, void 0, function* () {
213
+ const currentUser = Object.assign({}, this.userService.currentUser);
214
+ if (currentUser === null || currentUser === void 0 ? void 0 : currentUser.email) {
215
+ yield this.userService.logout();
216
+ this.socketService.broadcastMessageToAll((0, socket_service_1.buildOutgoingSocketMessage)('userLogout', { email: currentUser.email }));
217
+ }
218
+ });
219
+ }
220
+ lock() {
221
+ return __awaiter(this, void 0, void 0, function* () {
222
+ const currentUser = Object.assign({}, this.userService.currentUser);
223
+ if (currentUser === null || currentUser === void 0 ? void 0 : currentUser.email) {
224
+ yield this.userService.lock();
225
+ this.socketService.broadcastMessageToAll((0, socket_service_1.buildOutgoingSocketMessage)('userLock', { email: currentUser.email }));
226
+ }
227
+ });
228
+ }
229
+ // ---------------------- EVENTS ----------------------
230
+ on(event, handler) {
231
+ return this.eventService.on(event, handler);
232
+ }
233
+ once(event, handler) {
234
+ return this.eventService.once(event, handler);
235
+ }
236
+ removeListener(event, handler) {
237
+ this.eventService.removeListener(event, handler);
238
+ }
239
+ removeAllListeners() {
240
+ this.eventService.removeAllListeners();
241
+ }
242
+ }
243
+ exports.DesktopService = DesktopService;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GRPC_PING_TIMEOUT = exports.GRPC_CONNECTION_TIMEOUT = exports.WEBSOCKET_SSL_PORTS = exports.WEBSOCKET_PORTS = exports.HTTP_PORTS = void 0;
4
+ exports.HTTP_PORTS = [
5
+ 14411, 14110, 15611, 14412, 16311, 14514, 14515, 14413, 14401, 14100, 15601, 14402, 16301, 14504,
6
+ 14505, 14403,
7
+ ];
8
+ exports.WEBSOCKET_PORTS = [
9
+ 10040, 10124, 10978, 11307, 11792, 21792, 10041, 10125, 10979, 11308, 11793, 21793,
10
+ ];
11
+ exports.WEBSOCKET_SSL_PORTS = [
12
+ 20040, 20124, 20978, 21307, 21792, 22792, 20041, 20125, 20979, 21308, 21793, 22793,
13
+ ];
14
+ exports.GRPC_CONNECTION_TIMEOUT = 1500;
15
+ exports.GRPC_PING_TIMEOUT = 1000;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Utils = void 0;
7
+ const os_1 = __importDefault(require("os"));
8
+ class Utils {
9
+ static fromHexToArray(str) {
10
+ return new Uint8Array(Buffer.from(str, 'hex'));
11
+ }
12
+ static fromBufferToHex(buffer) {
13
+ return Buffer.from(buffer).toString('hex');
14
+ }
15
+ static fromBufferToB64(buffer) {
16
+ return Buffer.from(buffer).toString('base64');
17
+ }
18
+ static fromUtf8ToArray(str) {
19
+ return new Uint8Array(Buffer.from(str, 'utf8'));
20
+ }
21
+ static fromB64ToArray(str) {
22
+ return new Uint8Array(Buffer.from(str, 'base64'));
23
+ }
24
+ static getCurrentOS() {
25
+ const platform = os_1.default.platform();
26
+ const arc = os_1.default.arch();
27
+ let _os = 'linux';
28
+ if (platform === 'darwin') {
29
+ _os = arc === 'x64' ? 'mac-x64' : 'mac-arm64';
30
+ }
31
+ if (platform === 'win32') {
32
+ _os = 'windows';
33
+ }
34
+ return _os;
35
+ }
36
+ }
37
+ exports.Utils = Utils;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });