Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | 1x 2x 1x 1x 1x 1x 1x 1x 1x 1x | "use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PassmanClient = void 0;
const NextcloudServer_1 = require("./Model/NextcloudServer");
const Vault_1 = __importDefault(require("./Model/Vault"));
const DefaultLoggingService_1 = require("./Service/DefaultLoggingService");
const PreloadedVault_1 = __importDefault(require("./Model/PreloadedVault"));
const DefaultPersistenceService_1 = require("./Service/DefaultPersistenceService");
class PassmanClient {
server;
logger;
/**
* Non-serializable in-memory object cache, useful for long-living instances.
* todo: may add a constructor option to disable this one to save memory (for short-living instances like webextensions)
*/
_fullFeaturedVaultObjectCache;
/**
* Array of available vaults, with just enough metadata for a vault listing and to run testVaultKey('...').
*/
_preloadedVaults;
/**
* Create PassmanClient instance. Deprecated!
* @param serverData
* @param nextcloudServer
* @param logger
* @param persistence
* @throws ConfigurationError from nextcloud server configuration data
* @deprecated use PassmanClient.createInstance() instead in external/public libs
*/
constructor(serverData, nextcloudServer, logger, persistence) {
this.logger = logger ?? new DefaultLoggingService_1.DefaultLoggingService();
this.server = nextcloudServer ?? new NextcloudServer_1.NextcloudServer(serverData, this.logger, persistence ?? new DefaultPersistenceService_1.DefaultPersistenceService());
this._fullFeaturedVaultObjectCache = [];
}
/**
* Create PassmanClient instance.
* To use "auto restore on reconstruction" provide a custom persistence instance. This will never auto-unlock vaults.
* @param serverData
* @param nextcloudServer
* @param logger
* @param persistence
*/
static async createInstance(serverData, nextcloudServer, logger, persistence) {
// automatic probing if backendAppId is not explicitly set
if (!serverData.backendAppId) {
const successfulProbing = await PassmanClient.getServerBackendAppId(serverData);
if (successfulProbing) {
serverData.backendAppId = successfulProbing;
nextcloudServer?.setTemporaryBackendAppId(successfulProbing);
}
}
if (persistence?.autoRestoreOnReconstruction()) {
let passmanClient = new this(serverData, nextcloudServer ?? new NextcloudServer_1.NextcloudServer(serverData, logger, persistence), logger, persistence);
const requestCacheHandler = persistence.getRequestCacheHandler();
if (requestCacheHandler === undefined) {
throw new Error("Request cache handler is unexpectedly undefined. Please find a fix or disable autoRestoreOnReconstruction() from the PersistenceInterface.");
}
await passmanClient.restoreFromCacheHandler(requestCacheHandler);
return passmanClient;
}
else {
return new this(serverData, nextcloudServer, logger, persistence);
}
}
async restoreFromCacheHandler(cache) {
await this.preloadVaults(false, true);
// test for which vaults we have full-feature loading requests cached and hint-load them to be recreated from request cache
const cachePrefix = 'cache-getJson-';
for (const preloadedVault of this.preloadedVaults) {
const cachedValue = await cache.get(cachePrefix + '/vaults/' + preloadedVault.guid);
if (cachedValue && cachedValue !== '') {
await this.getFullVaultByGuid(preloadedVault.guid, true);
}
}
}
/**
* Preloads vaults or refreshes the preloaded vaults array, if getCachedIfPossible = false.
* @param throwError
* @param getCachedIfPossible
*/
async preloadVaults(throwError = false, getCachedIfPossible = false) {
const vaultsResponse = await this.server.getJson('/vaults', (error) => {
console.error(error);
if (throwError) {
this.logger.onThrow(error);
}
}, getCachedIfPossible);
let newPreloadedVaults = PreloadedVault_1.default.parseResponse(vaultsResponse, this.server);
if (newPreloadedVaults) {
this.preloadedVaults = newPreloadedVaults;
return true;
}
return false;
}
/**
* Test and fix the provided NextcloudServerBackendAppId within the serverData
* @param serverData
*/
static async getServerBackendAppId(serverData) {
let testBackendId = serverData.backendAppId ?? 'passman';
try {
const server1 = new NextcloudServer_1.NextcloudServer({
...serverData,
backendAppId: testBackendId
}, new DefaultLoggingService_1.DefaultLoggingService(), new DefaultPersistenceService_1.DefaultPersistenceService());
const vaultsResponse1 = await server1.getJson('/vaults', () => { }, false);
if (vaultsResponse1) {
serverData.backendAppId = testBackendId;
return testBackendId;
}
}
catch (_) {
// handle error case below
}
try {
testBackendId = testBackendId === 'passman-next' ? 'passman' : 'passman-next';
const server2 = new NextcloudServer_1.NextcloudServer({
...serverData,
backendAppId: testBackendId
}, new DefaultLoggingService_1.DefaultLoggingService(), new DefaultPersistenceService_1.DefaultPersistenceService());
const vaultsResponse2 = await server2.getJson('/vaults', () => { }, false);
if (vaultsResponse2) {
serverData.backendAppId = testBackendId;
return testBackendId;
}
}
catch (_) {
// handle error case below
}
return undefined;
}
async createVault(vaultName, vaultPassword) {
let newVault = await Vault_1.default.create(vaultName, vaultPassword, this.server);
if (newVault) {
this._updateFullFeaturedVaultInObjectCache(newVault);
return newVault;
}
}
/**
* @deprecated use getFullVaultByGuid instead
* @param guid
* @param getCachedIfPossible
*/
async getVaultByGuid(guid, getCachedIfPossible = false) {
return this.getFullVaultByGuid(guid, getCachedIfPossible);
}
/**
* Returns full vault from cache, or fetches it from the server (and updates the full-featured vault cache afterward).
* If a vault key is provided, it tries not only to unlock, also to restore decrypted data if getCachedIfPossible is set.
* @param guid
* @param getCachedIfPossible
*/
async getFullVaultByGuid(guid, getCachedIfPossible = false, vaultKey) {
if (getCachedIfPossible) {
const cachedVault = this._getFullFeaturedVaultFromObjectCacheByGuid(guid);
if (cachedVault) {
return cachedVault;
}
}
const freshVault = await Vault_1.default.fetchFullVaultFromServer(this.server, guid, vaultKey, getCachedIfPossible);
if (freshVault) {
this._updateFullFeaturedVaultInObjectCache(freshVault);
return freshVault;
}
this.logger.onError(`vault with guid ${guid} not found`);
}
get preloadedVaults() {
return this._preloadedVaults ?? [];
}
set preloadedVaults(preloadedVaults) {
this._preloadedVaults = preloadedVaults;
}
/**
* Returns the full-featured vault instance from the in-memory object cache, if possible.
* @param guid
* @private
*/
_getFullFeaturedVaultFromObjectCacheByGuid(guid) {
for (const vault of this._fullFeaturedVaultObjectCache) {
if (vault.guid === guid) {
return vault;
}
}
}
/**
* Add or update a full-featured vault instance in the in-memory object cache.
* @param vault
* @private
*/
_updateFullFeaturedVaultInObjectCache(vault) {
for (let i = 0; i < this._fullFeaturedVaultObjectCache.length; i++) {
if (this._fullFeaturedVaultObjectCache[i].guid === vault.guid) {
this._fullFeaturedVaultObjectCache[i] = vault;
return;
}
}
// add if vault was not found in the cache loop above
this._fullFeaturedVaultObjectCache.push(vault);
}
async getTranslation(lang = 'en') {
return await this.server.getJson('/language?lang=' + lang, (response) => {
this.logger.onError(response.message);
});
}
}
exports.PassmanClient = PassmanClient;
|