@binsky/passman-client-ts 0.1.0-7

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 (91) hide show
  1. package/README.md +9 -0
  2. package/lib/BrowserStorage.d.ts +39 -0
  3. package/lib/BrowserStorage.js +137 -0
  4. package/lib/Exception/ConfigurationError.d.ts +6 -0
  5. package/lib/Exception/ConfigurationError.js +11 -0
  6. package/lib/Exception/FormFieldError.d.ts +4 -0
  7. package/lib/Exception/FormFieldError.js +2 -0
  8. package/lib/Interfaces/Credential/CredentialInterface.d.ts +33 -0
  9. package/lib/Interfaces/Credential/CredentialInterface.js +2 -0
  10. package/lib/Interfaces/Credential/CustomFieldInterface.d.ts +6 -0
  11. package/lib/Interfaces/Credential/CustomFieldInterface.js +2 -0
  12. package/lib/Interfaces/Credential/EncryptedCredentialInterface.d.ts +31 -0
  13. package/lib/Interfaces/Credential/EncryptedCredentialInterface.js +2 -0
  14. package/lib/Interfaces/Credential/IconInterface.d.ts +4 -0
  15. package/lib/Interfaces/Credential/IconInterface.js +2 -0
  16. package/lib/Interfaces/Credential/OTPConfigInterface.d.ts +14 -0
  17. package/lib/Interfaces/Credential/OTPConfigInterface.js +2 -0
  18. package/lib/Interfaces/Credential/TagInterface.d.ts +3 -0
  19. package/lib/Interfaces/Credential/TagInterface.js +2 -0
  20. package/lib/Interfaces/CredentialFilterService/FilterStatsInterface.d.ts +10 -0
  21. package/lib/Interfaces/CredentialFilterService/FilterStatsInterface.js +2 -0
  22. package/lib/Interfaces/File/DeleteFilesRequestBodyInterface.d.ts +3 -0
  23. package/lib/Interfaces/File/DeleteFilesRequestBodyInterface.js +2 -0
  24. package/lib/Interfaces/File/DeleteFilesResponseInterface.d.ts +4 -0
  25. package/lib/Interfaces/File/DeleteFilesResponseInterface.js +2 -0
  26. package/lib/Interfaces/File/FileInterface.d.ts +9 -0
  27. package/lib/Interfaces/File/FileInterface.js +2 -0
  28. package/lib/Interfaces/File/FileUploadResponseInterface.d.ts +9 -0
  29. package/lib/Interfaces/File/FileUploadResponseInterface.js +2 -0
  30. package/lib/Interfaces/LoggingHandlerInterface.d.ts +9 -0
  31. package/lib/Interfaces/LoggingHandlerInterface.js +2 -0
  32. package/lib/Interfaces/NextcloudServer/NextcloudServerInterface.d.ts +6 -0
  33. package/lib/Interfaces/NextcloudServer/NextcloudServerInterface.js +2 -0
  34. package/lib/Interfaces/PassmanCrypto/GenerateKeypairResponseInterface.d.ts +5 -0
  35. package/lib/Interfaces/PassmanCrypto/GenerateKeypairResponseInterface.js +2 -0
  36. package/lib/Interfaces/PassmanCrypto/PEMRSAKeypairInterface.d.ts +4 -0
  37. package/lib/Interfaces/PassmanCrypto/PEMRSAKeypairInterface.js +2 -0
  38. package/lib/Interfaces/PassmanCrypto/RSAKeypairInterface.d.ts +5 -0
  39. package/lib/Interfaces/PassmanCrypto/RSAKeypairInterface.js +2 -0
  40. package/lib/Interfaces/PasswordGeneratorService/PasswordGeneratorConfigurationInterface.d.ts +9 -0
  41. package/lib/Interfaces/PasswordGeneratorService/PasswordGeneratorConfigurationInterface.js +2 -0
  42. package/lib/Interfaces/ReEncryptionService/ReEncryptionProgressInterface.d.ts +7 -0
  43. package/lib/Interfaces/ReEncryptionService/ReEncryptionProgressInterface.js +2 -0
  44. package/lib/Interfaces/ReEncryptionService/ReEncryptionStageProgressInterface.d.ts +5 -0
  45. package/lib/Interfaces/ReEncryptionService/ReEncryptionStageProgressInterface.js +2 -0
  46. package/lib/Interfaces/Revision/RevisionInterface.d.ts +8 -0
  47. package/lib/Interfaces/Revision/RevisionInterface.js +2 -0
  48. package/lib/Interfaces/ShareService/ACLInterface.d.ts +15 -0
  49. package/lib/Interfaces/ShareService/ACLInterface.js +2 -0
  50. package/lib/Interfaces/ShareService/CredentialShareRequestInterface.d.ts +16 -0
  51. package/lib/Interfaces/ShareService/CredentialShareRequestInterface.js +2 -0
  52. package/lib/Interfaces/Vault/VaultInterface.d.ts +15 -0
  53. package/lib/Interfaces/Vault/VaultInterface.js +2 -0
  54. package/lib/Interfaces/Vault/VaultResponseInterface.d.ts +15 -0
  55. package/lib/Interfaces/Vault/VaultResponseInterface.js +2 -0
  56. package/lib/LocalPassmanStore.d.ts +4 -0
  57. package/lib/LocalPassmanStore.js +14 -0
  58. package/lib/Model/Credential.d.ts +173 -0
  59. package/lib/Model/Credential.js +594 -0
  60. package/lib/Model/File.d.ts +15 -0
  61. package/lib/Model/File.js +55 -0
  62. package/lib/Model/NextcloudServer.d.ts +27 -0
  63. package/lib/Model/NextcloudServer.js +108 -0
  64. package/lib/Model/Revision.d.ts +21 -0
  65. package/lib/Model/Revision.js +33 -0
  66. package/lib/Model/SharingACL.d.ts +28 -0
  67. package/lib/Model/SharingACL.js +48 -0
  68. package/lib/Model/Vault.d.ts +38 -0
  69. package/lib/Model/Vault.js +265 -0
  70. package/lib/PassmanClient.d.ts +20 -0
  71. package/lib/PassmanClient.js +80 -0
  72. package/lib/Service/CredentialFilterService.d.ts +24 -0
  73. package/lib/Service/CredentialFilterService.js +209 -0
  74. package/lib/Service/CustomMathsService.d.ts +7 -0
  75. package/lib/Service/CustomMathsService.js +52 -0
  76. package/lib/Service/DefaultLoggingService.d.ts +10 -0
  77. package/lib/Service/DefaultLoggingService.js +27 -0
  78. package/lib/Service/DownloadService.d.ts +12 -0
  79. package/lib/Service/DownloadService.js +121 -0
  80. package/lib/Service/OTPService.d.ts +22 -0
  81. package/lib/Service/OTPService.js +134 -0
  82. package/lib/Service/PassmanCrypto.d.ts +10 -0
  83. package/lib/Service/PassmanCrypto.js +57 -0
  84. package/lib/Service/PasswordGeneratorService.d.ts +6 -0
  85. package/lib/Service/PasswordGeneratorService.js +73 -0
  86. package/lib/Service/ReEncryptionService.d.ts +23 -0
  87. package/lib/Service/ReEncryptionService.js +318 -0
  88. package/lib/Service/ShareService.d.ts +15 -0
  89. package/lib/Service/ShareService.js +56 -0
  90. package/lib/tsconfig.tsbuildinfo +1 -0
  91. package/package.json +36 -0
@@ -0,0 +1,108 @@
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
+ const ConfigurationError_1 = __importDefault(require("../Exception/ConfigurationError"));
7
+ class NextcloudServer {
8
+ serverData;
9
+ logger;
10
+ constructor(serverData, logger) {
11
+ this.serverData = serverData;
12
+ this.logger = logger;
13
+ if (!serverData.baseUrl.startsWith('https://') && !serverData.baseUrl.startsWith('http://')) {
14
+ this.logger.onThrow(new ConfigurationError_1.default('Base URL (or protocol) is invalid'));
15
+ }
16
+ if (serverData.token.length < 3) {
17
+ this.logger.onThrow(new ConfigurationError_1.default('Password or token is invalid'));
18
+ }
19
+ }
20
+ getBaseUrl() {
21
+ return this.serverData.baseUrl;
22
+ }
23
+ setBaseUrl(value) {
24
+ if (!value.startsWith('https://')) {
25
+ this.logger.onThrow(new ConfigurationError_1.default('Base URL is invalid'));
26
+ }
27
+ return this.serverData.baseUrl = value;
28
+ }
29
+ getUser() {
30
+ return this.serverData.user;
31
+ }
32
+ setUser(value) {
33
+ return this.serverData.user = value;
34
+ }
35
+ getToken() {
36
+ return this.serverData.token;
37
+ }
38
+ setToken(value) {
39
+ return this.serverData.token = value;
40
+ }
41
+ getApiUrl() {
42
+ return `${this.getBaseUrl()}/index.php/apps/passman/api/v2/`;
43
+ }
44
+ getEncodedLogin() {
45
+ return btoa(this.getUser() + ":" + this.getToken());
46
+ }
47
+ get = async (endpoint, errorCallback) => {
48
+ return await fetch(this.getApiUrl() + endpoint, {
49
+ headers: {
50
+ Authorization: `Basic ${this.getEncodedLogin()}`
51
+ }
52
+ }).catch((err) => errorCallback(err));
53
+ };
54
+ getJson = async (endpoint, errorCallback) => {
55
+ const res = await fetch(this.getApiUrl() + endpoint, {
56
+ headers: {
57
+ Accept: 'application/json',
58
+ Authorization: `Basic ${this.getEncodedLogin()}`
59
+ }
60
+ }).catch((err) => errorCallback(err));
61
+ if (!res) {
62
+ return;
63
+ }
64
+ if (res.status >= 400) {
65
+ const data = await res.json();
66
+ this.logger.onError(data.message);
67
+ return;
68
+ }
69
+ return (await res.json());
70
+ };
71
+ delete = async (endpoint, errorCallback) => {
72
+ return await fetch(this.getApiUrl() + endpoint, {
73
+ method: 'DELETE',
74
+ headers: {
75
+ Authorization: `Basic ${this.getEncodedLogin()}`
76
+ }
77
+ }).catch((err) => errorCallback(err));
78
+ };
79
+ /**
80
+ * Do a post request.
81
+ *
82
+ * @param endpoint
83
+ * @param data will be converted to a json string
84
+ * @param errorCallback
85
+ * @param method
86
+ */
87
+ postJson = async (endpoint, data, errorCallback, method = 'POST') => {
88
+ const res = await fetch(this.getApiUrl() + endpoint, {
89
+ method: method,
90
+ headers: {
91
+ Accept: 'application/json',
92
+ Authorization: `Basic ${this.getEncodedLogin()}`,
93
+ "Content-Type": "application/json",
94
+ },
95
+ body: JSON.stringify(data),
96
+ }).catch((err) => errorCallback(err));
97
+ if (!res) {
98
+ return;
99
+ }
100
+ if (res.status >= 400) {
101
+ const data = await res.json();
102
+ this.logger.onError(data.message);
103
+ return;
104
+ }
105
+ return (await res.json());
106
+ };
107
+ }
108
+ exports.default = NextcloudServer;
@@ -0,0 +1,21 @@
1
+ import Credential from "./Credential";
2
+ import NextcloudServer from "./NextcloudServer";
3
+ import type Vault from "./Vault";
4
+ import { EncryptedCredentialInterface } from "../Interfaces/Credential/EncryptedCredentialInterface";
5
+ import { FileUploadResponseInterface } from "../Interfaces/File/FileUploadResponseInterface";
6
+ import { RevisionInterface } from "../Interfaces/Revision/RevisionInterface";
7
+ export default class Revision extends Credential {
8
+ ENCRYPTED_FIELDS: string[];
9
+ static updateRevision(revision: RevisionInterface, server: NextcloudServer): Promise<void | FileUploadResponseInterface>;
10
+ /**
11
+ * Create a revision object based on its encrypted data.
12
+ * @param data
13
+ * @param vault
14
+ * @param server
15
+ */
16
+ static fromData(data: EncryptedCredentialInterface, vault: Vault, server: NextcloudServer): Promise<Revision>;
17
+ /**
18
+ * Creates a local 100% clone of the current credential.
19
+ */
20
+ clone(): Revision;
21
+ }
@@ -0,0 +1,33 @@
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
+ const Credential_1 = __importDefault(require("./Credential"));
7
+ class Revision extends Credential_1.default {
8
+ ENCRYPTED_FIELDS = ['description', 'username', 'password', 'files', 'custom_fields', 'otp', 'email', 'tags', 'url', 'compromised'];
9
+ static updateRevision(revision, server) {
10
+ const credentialGUID = revision.credential_data.guid;
11
+ revision.credential_data = window.btoa(JSON.stringify(revision.credential_data));
12
+ return server.postJson('/credentials/' + credentialGUID + '/revision/' + revision.revision_id, revision, () => {
13
+ }, 'PATCH');
14
+ }
15
+ /**
16
+ * Create a revision object based on its encrypted data.
17
+ * @param data
18
+ * @param vault
19
+ * @param server
20
+ */
21
+ static async fromData(data, vault, server) {
22
+ return new Revision(vault, server, data);
23
+ }
24
+ /**
25
+ * Creates a local 100% clone of the current credential.
26
+ */
27
+ clone() {
28
+ const newCredential = new Revision(this.vault, this.server, this.encryptedData);
29
+ newCredential.sharedCredentialEncryptionKey = this.sharedCredentialEncryptionKey;
30
+ return newCredential;
31
+ }
32
+ }
33
+ exports.default = Revision;
@@ -0,0 +1,28 @@
1
+ export declare class SharingACL {
2
+ private permission;
3
+ constructor(permission: number);
4
+ static readonly permissions: {
5
+ READ: number;
6
+ WRITE: number;
7
+ FILES: number;
8
+ HISTORY: number;
9
+ OWNER: number;
10
+ };
11
+ /**
12
+ * Checks if a user has the given permission/s
13
+ * @param permission
14
+ */
15
+ hasPermission(permission: any): boolean;
16
+ /**
17
+ * Adds a permission to a user, leaving any other permissions intact
18
+ * @param permission
19
+ */
20
+ addPermission(permission: any): void;
21
+ /**
22
+ * Removes a given permission from the item, leaving any other intact
23
+ * @param permission
24
+ */
25
+ removePermission(permission: any): void;
26
+ togglePermission(permission: any): void;
27
+ getAccessLevel(): number;
28
+ }
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SharingACL = void 0;
4
+ class SharingACL {
5
+ permission;
6
+ constructor(permission) {
7
+ this.permission = permission;
8
+ }
9
+ static permissions = {
10
+ READ: 0x01,
11
+ WRITE: 0x02,
12
+ FILES: 0x04,
13
+ HISTORY: 0x08,
14
+ OWNER: 0x80,
15
+ };
16
+ /**
17
+ * Checks if a user has the given permission/s
18
+ * @param permission
19
+ */
20
+ hasPermission(permission) {
21
+ return permission === (this.permission & permission);
22
+ }
23
+ ;
24
+ /**
25
+ * Adds a permission to a user, leaving any other permissions intact
26
+ * @param permission
27
+ */
28
+ addPermission(permission) {
29
+ this.permission = this.permission | permission;
30
+ }
31
+ ;
32
+ /**
33
+ * Removes a given permission from the item, leaving any other intact
34
+ * @param permission
35
+ */
36
+ removePermission(permission) {
37
+ this.permission = this.permission & ~permission;
38
+ }
39
+ ;
40
+ togglePermission(permission) {
41
+ this.permission ^= permission;
42
+ }
43
+ ;
44
+ getAccessLevel() {
45
+ return this.permission;
46
+ }
47
+ }
48
+ exports.SharingACL = SharingACL;
@@ -0,0 +1,38 @@
1
+ import NextcloudServer from "./NextcloudServer";
2
+ import Credential from "./Credential";
3
+ import { VaultInterface } from "../Interfaces/Vault/VaultInterface";
4
+ export default class Vault {
5
+ private data;
6
+ private server;
7
+ private _vaultKey;
8
+ constructor(data: VaultInterface, server: NextcloudServer);
9
+ static create(vaultName: string, vaultPassword: string, server: NextcloudServer): Promise<Vault>;
10
+ refresh(): Promise<boolean>;
11
+ update(): Promise<boolean>;
12
+ delete(currentPassword: string): Promise<boolean>;
13
+ lock(): void;
14
+ updateSharingKeys(public_sharing_key: string, private_sharing_key: string): Promise<void>;
15
+ testVaultKey(vaultKey: string): boolean;
16
+ private getChallengingFieldValue;
17
+ private getFirstOwnedCredential;
18
+ getCredentialByGuid(guid: string): Credential | undefined;
19
+ getServer(): NextcloudServer;
20
+ get vaultId(): number | null;
21
+ get vaultKey(): string;
22
+ set vaultKey(value: string);
23
+ get guid(): string;
24
+ get name(): string;
25
+ set name(value: string);
26
+ get created(): number;
27
+ get public_sharing_key(): string;
28
+ get private_sharing_key(): string;
29
+ get sharing_keys_generated(): number;
30
+ set sharing_keys_generated(value: number);
31
+ get last_access(): number;
32
+ get challenge_password(): string;
33
+ get delete_request_pending(): boolean;
34
+ set delete_request_pending(value: boolean);
35
+ get vault_settings(): null;
36
+ set vault_settings(value: null);
37
+ get credentials(): Credential[];
38
+ }
@@ -0,0 +1,265 @@
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
+ const Credential_1 = __importDefault(require("./Credential"));
7
+ const PassmanCrypto_1 = require("../Service/PassmanCrypto");
8
+ const ShareService_1 = require("../Service/ShareService");
9
+ const File_1 = require("./File");
10
+ const BrowserStorage_1 = require("../BrowserStorage");
11
+ class Vault {
12
+ data;
13
+ server;
14
+ _vaultKey;
15
+ constructor(data, server) {
16
+ this.data = data;
17
+ this.server = server;
18
+ }
19
+ static async create(vaultName, vaultPassword, server) {
20
+ let vaultResponse = await server.postJson('/vaults', { vault_name: vaultName }, (response) => {
21
+ server.logger.onError(response.message);
22
+ });
23
+ if (vaultResponse) {
24
+ const vault = new Vault(vaultResponse, server);
25
+ vault._vaultKey = vaultPassword;
26
+ await PassmanCrypto_1.PassmanCrypto.generateRSAKeypair(2048).then(async (value) => {
27
+ if (value.keypair) {
28
+ const pemKeyPair = PassmanCrypto_1.PassmanCrypto.rsaKeyPairToPEM(value.keypair);
29
+ await vault.updateSharingKeys(pemKeyPair.publicKey, pemKeyPair.privateKey);
30
+ // todo: create hidden test credential
31
+ let testCredential = new Credential_1.default(vault, server);
32
+ testCredential.label = 'Test key for vault ' + vaultName;
33
+ testCredential.hidden = true;
34
+ testCredential.password = 'lorum ipsum';
35
+ if (await testCredential.save()) {
36
+ // todo: refresh / log in to the new vault
37
+ server.logger.onSuccess('Vault successfully created');
38
+ }
39
+ else {
40
+ server.logger.onError('Failed saving test credential in new vault');
41
+ }
42
+ }
43
+ else {
44
+ server.logger.onError('Failed to create a new vault rsa key-pair');
45
+ }
46
+ });
47
+ return vault;
48
+ }
49
+ }
50
+ async refresh() {
51
+ let vaultResponse = await this.server.getJson('/vaults/' + this.guid, (response) => {
52
+ this.server.logger.onError(response.message);
53
+ });
54
+ if (vaultResponse) {
55
+ const credentials = [];
56
+ for (const credentialData of vaultResponse.credentials) {
57
+ try {
58
+ credentials.push(await Credential_1.default.fromData(credentialData, this, this.server));
59
+ }
60
+ catch (e) {
61
+ this.server.logger.anyError(e);
62
+ this.server.logger.onError('Failed to decrypt credential: ' + credentialData.label);
63
+ }
64
+ }
65
+ const credentialsSharedWithUs = await ShareService_1.ShareService.getCredentialsSharedWithUs(this, this.server);
66
+ for (const credential of credentialsSharedWithUs) {
67
+ credentials.push(credential);
68
+ }
69
+ // todo: check if a creation of vault.private_sharing_key for old vaults is required
70
+ this.data = {
71
+ challenge_password: vaultResponse.challenge_password,
72
+ created: vaultResponse.created,
73
+ credentials: credentials,
74
+ delete_request_pending: vaultResponse.delete_request_pending,
75
+ guid: vaultResponse.guid,
76
+ last_access: vaultResponse.last_access,
77
+ name: vaultResponse.name,
78
+ private_sharing_key: vaultResponse.private_sharing_key,
79
+ public_sharing_key: vaultResponse.public_sharing_key,
80
+ sharing_keys_generated: vaultResponse.sharing_keys_generated,
81
+ vault_id: vaultResponse.vault_id,
82
+ vault_settings: vaultResponse.vault_settings,
83
+ };
84
+ return true;
85
+ }
86
+ return false;
87
+ }
88
+ async update() {
89
+ const result = await this.server.postJson('/vaults/' + this.data.guid, {
90
+ guid: this.data.guid,
91
+ vault_id: this.data.vault_id,
92
+ name: this.data.name,
93
+ created: this.data.created,
94
+ public_sharing_key: this.data.public_sharing_key,
95
+ last_access: this.data.last_access,
96
+ delete_request_pending: this.data.delete_request_pending,
97
+ sharing_keys_generated: this.data.sharing_keys_generated,
98
+ vault_settings: this.data.vault_settings
99
+ }, (response) => {
100
+ this.server.logger.onError(response.message);
101
+ }, 'PATCH');
102
+ return result === null;
103
+ }
104
+ async delete(currentPassword) {
105
+ if (!this.testVaultKey(currentPassword)) {
106
+ this.server.logger.onError('Invalid password!');
107
+ return false;
108
+ }
109
+ let fileIds = [];
110
+ for (const credential of this.credentials) {
111
+ for (const file of credential.files) {
112
+ if (file.file_id) {
113
+ fileIds.push(file.file_id);
114
+ }
115
+ }
116
+ }
117
+ const deleteFilesResponse = await File_1.File.deleteFiles({ file_ids: JSON.stringify(fileIds) }, this.server);
118
+ if (!deleteFilesResponse) {
119
+ // void response should "never" happen with a working server side
120
+ this.server.logger.onError('Abort! Failed to request files deletion.');
121
+ return false;
122
+ }
123
+ if (!deleteFilesResponse.ok) {
124
+ // minor file deletion issues; continue vault deletion
125
+ this.server.logger.onError('Failed to delete files: ' + deleteFilesResponse.failed.toString());
126
+ }
127
+ let deleteVaultResponse = await this.server.delete('/vaults/' + this.guid, (response) => {
128
+ this.server.logger.onError(response.message);
129
+ });
130
+ if (!deleteVaultResponse) {
131
+ // void response should "never" happen with a working server side
132
+ this.server.logger.onError('Abort! Failed to request vault deletion.');
133
+ return false;
134
+ }
135
+ if (deleteVaultResponse.status === 200) {
136
+ BrowserStorage_1.BrowserStorage.clearAllStorageTypesForVaultGUID(this.guid);
137
+ // todo: delete from local/memory vaults store
138
+ /*let passmanClient = get<PassmanClient>(passmanStore);
139
+ for (let i = 0; i < passmanClient.vaults.length; i++) {
140
+ if (passmanClient.vaults[i].guid === this.guid) {
141
+ passmanClient.vaults.splice(i, 1);
142
+ }
143
+ }*/
144
+ return true;
145
+ }
146
+ return false;
147
+ }
148
+ lock() {
149
+ this.vaultKey = null;
150
+ // clear decrypted credential cache from memory
151
+ for (const credential of this.data.credentials) {
152
+ credential.clearDecryptedDataCache();
153
+ }
154
+ BrowserStorage_1.BrowserStorage.ensureDeleteKeyForAllStorageTypes('vault-' + this.guid, 'vaultKey');
155
+ }
156
+ async updateSharingKeys(public_sharing_key, private_sharing_key) {
157
+ return await this.server.postJson('/vaults/' + this.data.guid + '/sharing-keys', {
158
+ guid: this.data.guid,
159
+ public_sharing_key: public_sharing_key,
160
+ private_sharing_key: PassmanCrypto_1.PassmanCrypto.encryptString(private_sharing_key, this.vaultKey),
161
+ }, (response) => {
162
+ this.server.logger.onError(response.message);
163
+ });
164
+ }
165
+ testVaultKey(vaultKey) {
166
+ try {
167
+ if (this.challenge_password) {
168
+ PassmanCrypto_1.PassmanCrypto.decryptString(this.challenge_password, vaultKey);
169
+ return true;
170
+ }
171
+ else if (this.credentials.length > 0) {
172
+ PassmanCrypto_1.PassmanCrypto.decryptString(this.getChallengingFieldValue(), vaultKey);
173
+ return true;
174
+ }
175
+ }
176
+ catch (e) {
177
+ }
178
+ return false;
179
+ }
180
+ getChallengingFieldValue() {
181
+ const testCredential = this.getFirstOwnedCredential();
182
+ if (testCredential.getEncrypted().username != null) {
183
+ return testCredential.getEncrypted().username;
184
+ }
185
+ else if (testCredential.getEncrypted().password != null) {
186
+ return testCredential.getEncrypted().password;
187
+ }
188
+ else if (testCredential.getEncrypted().email != null) {
189
+ return testCredential.getEncrypted().email;
190
+ }
191
+ return null;
192
+ }
193
+ getFirstOwnedCredential() {
194
+ for (let credential of this.credentials) {
195
+ if (!credential.hasValidSharedKey() && credential.sharedCredentialEncryptionKey === undefined) {
196
+ return credential;
197
+ }
198
+ }
199
+ }
200
+ getCredentialByGuid(guid) {
201
+ for (let credential of this.credentials) {
202
+ if (credential.guid === guid) {
203
+ return credential;
204
+ }
205
+ }
206
+ }
207
+ getServer() {
208
+ return this.server;
209
+ }
210
+ get vaultId() {
211
+ return this.data.vault_id;
212
+ }
213
+ get vaultKey() {
214
+ return this._vaultKey;
215
+ }
216
+ set vaultKey(value) {
217
+ this._vaultKey = value;
218
+ }
219
+ get guid() {
220
+ return this.data.guid;
221
+ }
222
+ get name() {
223
+ return this.data.name;
224
+ }
225
+ set name(value) {
226
+ this.data.name = value;
227
+ }
228
+ get created() {
229
+ return this.data.created;
230
+ }
231
+ get public_sharing_key() {
232
+ return this.data.public_sharing_key;
233
+ }
234
+ get private_sharing_key() {
235
+ return PassmanCrypto_1.PassmanCrypto.decryptString(this.data.private_sharing_key, this.vaultKey);
236
+ }
237
+ get sharing_keys_generated() {
238
+ return this.data.sharing_keys_generated;
239
+ }
240
+ set sharing_keys_generated(value) {
241
+ this.data.sharing_keys_generated = value;
242
+ }
243
+ get last_access() {
244
+ return this.data.last_access;
245
+ }
246
+ get challenge_password() {
247
+ return this.data.challenge_password;
248
+ }
249
+ get delete_request_pending() {
250
+ return this.data.delete_request_pending;
251
+ }
252
+ set delete_request_pending(value) {
253
+ this.data.delete_request_pending = value;
254
+ }
255
+ get vault_settings() {
256
+ return this.data.vault_settings;
257
+ }
258
+ set vault_settings(value) {
259
+ this.data.vault_settings = value;
260
+ }
261
+ get credentials() {
262
+ return this.data.credentials ?? [];
263
+ }
264
+ }
265
+ exports.default = Vault;
@@ -0,0 +1,20 @@
1
+ import NextcloudServer from "./Model/NextcloudServer";
2
+ import Vault from "./Model/Vault";
3
+ import type { LoggingHandlerInterface } from "./Interfaces/LoggingHandlerInterface";
4
+ import { NextcloudServerInterface } from "./Interfaces/NextcloudServer/NextcloudServerInterface";
5
+ export declare class PassmanClient {
6
+ readonly server: NextcloudServer;
7
+ private logger;
8
+ vaults: Vault[];
9
+ constructor(serverData: NextcloudServerInterface, logger?: LoggingHandlerInterface);
10
+ refreshVaults(throwError?: boolean, preserveInMemoryVaultKeys?: boolean): Promise<boolean>;
11
+ createVault(vaultName: string, vaultPassword: string): Promise<void | Vault>;
12
+ getVaultByGuid(guid: string): Promise<Vault>;
13
+ /**
14
+ * Make sure that this.vaults is an array and not undefined, before using this method.
15
+ * @param guid
16
+ * @private
17
+ */
18
+ private _getVaultByGuid;
19
+ getTranslation(lang?: string): Promise<void | object>;
20
+ }
@@ -0,0 +1,80 @@
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.PassmanClient = void 0;
7
+ const NextcloudServer_1 = __importDefault(require("./Model/NextcloudServer"));
8
+ const Vault_1 = __importDefault(require("./Model/Vault"));
9
+ const DefaultLoggingService_1 = require("./Service/DefaultLoggingService");
10
+ class PassmanClient {
11
+ server;
12
+ logger;
13
+ vaults;
14
+ constructor(serverData, logger = undefined) {
15
+ this.logger = logger ?? new DefaultLoggingService_1.DefaultLoggingService();
16
+ this.server = new NextcloudServer_1.default(serverData, this.logger);
17
+ }
18
+ async refreshVaults(throwError = false, preserveInMemoryVaultKeys = true) {
19
+ let newVaults = [];
20
+ const vaults = await this.server.getJson('/vaults', (error) => {
21
+ console.error(error);
22
+ if (throwError) {
23
+ this.logger.onThrow(error);
24
+ }
25
+ });
26
+ if (vaults) {
27
+ vaults.forEach((vaultData) => {
28
+ const vault = new Vault_1.default(vaultData, this.server);
29
+ if (this.vaults !== undefined && preserveInMemoryVaultKeys) {
30
+ const oldVaultInstance = this._getVaultByGuid(vault.guid);
31
+ if (oldVaultInstance && oldVaultInstance.vaultKey && vault.testVaultKey(oldVaultInstance.vaultKey)) {
32
+ vault.vaultKey = oldVaultInstance.vaultKey;
33
+ }
34
+ }
35
+ newVaults.push(vault);
36
+ });
37
+ this.vaults = newVaults;
38
+ return true;
39
+ }
40
+ return false;
41
+ }
42
+ async createVault(vaultName, vaultPassword) {
43
+ let newVault = await Vault_1.default.create(vaultName, vaultPassword, this.server);
44
+ if (newVault) {
45
+ this.vaults.push(newVault);
46
+ return newVault;
47
+ }
48
+ }
49
+ async getVaultByGuid(guid) {
50
+ if (this.vaults === undefined) {
51
+ if (!await this.refreshVaults()) {
52
+ this.logger.onError("failed to refresh vaults");
53
+ return;
54
+ }
55
+ }
56
+ const foundVault = this._getVaultByGuid(guid);
57
+ if (foundVault) {
58
+ return foundVault;
59
+ }
60
+ this.logger.onError(`vault with guid ${guid} not found`);
61
+ }
62
+ /**
63
+ * Make sure that this.vaults is an array and not undefined, before using this method.
64
+ * @param guid
65
+ * @private
66
+ */
67
+ _getVaultByGuid(guid) {
68
+ for (const element of this.vaults) {
69
+ if (element.guid === guid) {
70
+ return element;
71
+ }
72
+ }
73
+ }
74
+ async getTranslation(lang = 'en') {
75
+ return await this.server.getJson('/language?lang=' + lang, (response) => {
76
+ this.logger.onError(response.message);
77
+ });
78
+ }
79
+ }
80
+ exports.PassmanClient = PassmanClient;
@@ -0,0 +1,24 @@
1
+ import type Credential from "../Model/Credential";
2
+ import { FilterStatsInterface } from "../Interfaces/CredentialFilterService/FilterStatsInterface";
3
+ export declare enum FILTERS {
4
+ SHOW_ALL = 0,
5
+ COMPROMISED = 1,
6
+ STRENGTH_LOW = 2,
7
+ STRENGTH_MEDIUM = 3,
8
+ STRENGTH_GOOD = 4,
9
+ EXPIRED = 5,
10
+ DELETED = 6,
11
+ ENCRYPTION_BROKEN = 7
12
+ }
13
+ export declare class CredentialFilterService {
14
+ static getFilteredCredentials: (allCredentials: Credential[], filter: FILTERS, additionalFilterText?: string) => Credential[];
15
+ static getFilterStats: (allCredentials: Credential[]) => FilterStatsInterface;
16
+ static isHidden(credential: Credential): boolean;
17
+ static isDeleted(credential: Credential): boolean;
18
+ static isCompromised(credential: Credential): boolean;
19
+ static isExpired(credential: Credential, now?: number): boolean;
20
+ static hasLowStrength(credential: Credential): boolean;
21
+ static hasMediumStrength(credential: Credential): boolean;
22
+ static hasGoodStrength(credential: Credential): boolean;
23
+ static matchesFilterText(credential: Credential, filterText: string): boolean;
24
+ }