Skip to content

Commit

Permalink
WIP - #305
Browse files Browse the repository at this point in the history
  • Loading branch information
tegefaulkes committed Feb 17, 2022
1 parent e9ae9aa commit ff4d516
Show file tree
Hide file tree
Showing 10 changed files with 156 additions and 79 deletions.
2 changes: 1 addition & 1 deletion src/agent/service/vaultsGitInfoGet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ function vaultsGitInfoGet({
if (!vaultId) {
try {
vaultId = validationUtils.parseVaultId(vaultNameOrId);
vaultName = (await vaultManager.getVaultMeta(vaultId)).name;
vaultName = (await vaultManager.getVaultMeta(vaultId))?.vaultName;
} catch (err) {
await genWritable.throw(new vaultsErrors.ErrorVaultsVaultUndefined());
return;
Expand Down
2 changes: 1 addition & 1 deletion src/client/service/vaultsClone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ function vaultsClone({
// Vault id
let vaultId;
const vaultNameOrId = vaultMessage.getNameOrId();
vaultId = vaultManager.getVaultId(vaultNameOrId)
vaultId = vaultManager.getVaultId(vaultNameOrId);
vaultId = vaultId ?? vaultsUtils.decodeVaultId(vaultNameOrId);
if (vaultId == null) throw new vaultsErrors.ErrorVaultsVaultUndefined();
// Node id
Expand Down
52 changes: 34 additions & 18 deletions src/vaults/VaultInternal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import type { ReadCommitResult } from 'isomorphic-git';
import type { EncryptedFS } from 'encryptedfs';
import type { DB, DBDomain, DBLevel } from '@matrixai/db';
import type {
VaultId,
VaultName,
VaultRef,
CommitId,
CommitLog,
FileSystemReadable,
FileSystemWritable,
VaultId,
VaultIdEncoded,
VaultName,
VaultRef,
} from './types';
import type { KeyManager } from '../keys';
import type { NodeId, NodeIdEncoded } from '../nodes/types';
Expand All @@ -23,7 +23,6 @@ import {
CreateDestroyStartStop,
ready,
} from '@matrixai/async-init/dist/CreateDestroyStartStop';
import { IdInternal, utils as idUtils } from '@matrixai/id';
import * as vaultsUtils from './utils';
import * as vaultsErrors from './errors';
import { withF, withG } from '../utils';
Expand Down Expand Up @@ -242,13 +241,16 @@ class VaultInternal {
this.logger.info(
`Starting ${this.constructor.name} - ${this.vaultIdEncoded}`,
);
const vaultDbDomain = [...this.vaultsDbDomain, this.vaultIdEncoded];
const vaultsNamesDomain = [...this.vaultsDbDomain, 'names'];
const vaultDb = await this.db.level(this.vaultIdEncoded, this.vaultsDb);
this.vaultMetadataDbDomain = [...this.vaultsDbDomain, this.vaultIdEncoded];
this.vaultsNamesDomain = [...this.vaultsDbDomain, 'names'];
this.vaultMetadataDb = await this.db.level(
this.vaultIdEncoded,
this.vaultsDb,
);
// Let's backup any metadata.

if (fresh) {
await vaultDb.clear();
await this.vaultMetadataDb.clear();
try {
await this.efs.rmdir(this.vaultIdEncoded, {
recursive: true,
Expand All @@ -259,21 +261,27 @@ class VaultInternal {
}
}
}
await this.efs.mkdir(this.vaultIdEncoded, { recursive: true });
await this.efs.mkdir(this.vaultDataDir, { recursive: true });
await this.efs.mkdir(this.vaultGitDir, { recursive: true });
await this.mkdirExists(this.vaultIdEncoded);
await this.mkdirExists(this.vaultDataDir);
await this.mkdirExists(this.vaultGitDir);
await this.setupMeta({ vaultName });
await this.setupGit();
const efsVault = await this.efs.chroot(this.vaultDataDir);
this.vaultMetadataDbDomain = vaultDbDomain;
this.vaultsNamesDomain = vaultsNamesDomain;
this.vaultMetadataDb = vaultDb;
this.efsVault = efsVault;
this.efsVault = await this.efs.chroot(this.vaultDataDir);
this.logger.info(
`Started ${this.constructor.name} - ${this.vaultIdEncoded}`,
);
}

private async mkdirExists(directory: string) {
try {
await this.efs.mkdir(directory, { recursive: true });
} catch (e) {
if (e.code !== 'EEXIST') {
throw e;
}
}
}

public async stop(): Promise<void> {
this.logger.info(
`Stopping ${this.constructor.name} - ${this.vaultIdEncoded}`,
Expand Down Expand Up @@ -714,7 +722,11 @@ class VaultInternal {
VaultInternal.dirtyKey,
)) == null
) {
await this.db.put(this.vaultsDbDomain, VaultInternal.dirtyKey, true);
await this.db.put(
this.vaultMetadataDbDomain,
VaultInternal.dirtyKey,
true,
);
}

// Set up vault Name
Expand All @@ -725,7 +737,11 @@ class VaultInternal {
)) == null &&
vaultName != null
) {
await this.db.put(this.vaultsDbDomain, VaultInternal.nameKey, vaultName);
await this.db.put(
this.vaultMetadataDbDomain,
VaultInternal.nameKey,
vaultName,
);
}

// Remote: [NodeId, VaultId] | undefined
Expand Down
10 changes: 8 additions & 2 deletions src/vaults/VaultManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -347,10 +347,12 @@ class VaultManager {
this.vaultMap.set(vaultId, { lock });
return await this.transact(async () => {
// Adding vault to name map
console.log(vaultId.toBuffer());
await this.db.put(
this.vaultsNamesDbDomain,
vaultName,
vaultId.toBuffer(),
true,
);
// Creating vault
const vault = await VaultInternal.createVaultInternal({
Expand Down Expand Up @@ -450,8 +452,11 @@ class VaultManager {
// Stream of vaultName VaultId key value pairs
for await (const o of this.vaultsNamesDb.createReadStream()) {
const obj = o as any;
const vaultId = IdInternal.fromBuffer<VaultId>(obj.value);
vaults.set(obj.key as VaultName, vaultId);
console.log(obj.key.toString());
console.log(obj.value as Buffer);
const vaultId = IdInternal.fromBuffer<VaultId>(obj.value as Buffer);
console.log(vaultId);
vaults.set(obj.key.toString() as VaultName, vaultId);
}
return vaults;
}
Expand Down Expand Up @@ -540,6 +545,7 @@ class VaultManager {
@ready(new vaultsErrors.ErrorVaultManagerNotRunning())
public async shareVault(vaultId: VaultId, nodeId: NodeId): Promise<void> {
const vaultMeta = await this.getVaultMeta(vaultId);
console.log(vaultId, vaultMeta);
if (!vaultMeta) throw new vaultsErrors.ErrorVaultsVaultUndefined();
await this.transact(async () => {
await this.gestaltGraph._transaction(async () => {
Expand Down
5 changes: 5 additions & 0 deletions src/vaults/VaultOps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ import path from 'path';
import * as vaultsErrors from './errors';
import * as vaultsUtils from './utils';

// TODO: remove?
type FileOptions = {
recursive?: boolean;
};

// TODO: tests
// - add succeeded
// - secret exists
Expand Down
27 changes: 15 additions & 12 deletions src/vaults/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,18 +80,20 @@ function commitAuthor(nodeId: NodeId): { name: string; email: string } {
// return true;
// }

// async function* readdirRecursively(fs, dir = '.') {
// const dirents = await fs.promises.readdir(dir);
// for (const dirent of dirents) {
// const res = path.join(dir, dirent.toString());
// const stat = await fs.promises.stat(res);
// if (stat.isDirectory()) {
// yield* readdirRecursively(fs, res);
// } else if (stat.isFile()) {
// yield res;
// }
// }
// }
// TODO: remove or move?
async function* readdirRecursively(fs, dir = '.') {
throw Error('Not Implemented');
// Const dirents = await fs.promises.readdir(dir);
// for (const dirent of dirents) {
// const res = path.join(dir, dirent.toString());
// const stat = await fs.promises.stat(res);
// if (stat.isDirectory()) {
// yield* readdirRecursively(fs, res);
// } else if (stat.isFile()) {
// yield res;
// }
// }
}

// TODO: Is this being removed or moved?
async function request(
Expand Down Expand Up @@ -206,4 +208,5 @@ export {
commitAuthor,
isVaultAction,
request,
readdirRecursively,
};
82 changes: 59 additions & 23 deletions tests/vaults/VaultInternal.test.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import type { VaultId } from '@/vaults/types';
import type { Vault } from '@/vaults/Vault';
import type { KeyManager } from '@/keys';
import type { DBDomain, DBLevel } from '@matrixai/db';
import os from 'os';
import path from 'path';
import fs from 'fs';
import Logger, { LogLevel, StreamHandler } from '@matrixai/logger';
import { EncryptedFS } from 'encryptedfs';
import { DB } from '@matrixai/db';
import { VaultInternal } from '@/vaults';
import { generateVaultId } from '@/vaults/utils';
import * as vaultsErrors from '@/vaults/errors';
import { sleep } from '@/utils';
import { utils as keysUtils } from '@/keys';
import * as vaultsUtils from '@/vaults/utils';
import * as testsUtils from '../utils';

jest.mock('@/keys/utils', () => ({
Expand All @@ -20,14 +23,19 @@ jest.mock('@/keys/utils', () => ({
}));

describe('VaultInternal', () => {
const logger = new Logger('Vault', LogLevel.WARN, [new StreamHandler()]);

let dataDir: string;
let dbPath: string;
let efsDbPath: string;

let vault: VaultInternal;
let dbKey: Buffer;
let vaultId: VaultId;
let efs: EncryptedFS;
const logger = new Logger('Vault', LogLevel.WARN, [new StreamHandler()]);

let db: DB;
let vaultsDb: DBLevel;
let vaultsDbDomain: DBDomain;

const fakeKeyManager = {
getNodeId: () => {
Expand All @@ -37,33 +45,56 @@ describe('VaultInternal', () => {
const secret1 = { name: 'secret-1', content: 'secret-content-1' };
const secret2 = { name: 'secret-2', content: 'secret-content-2' };

beforeAll(async () => {
beforeAll(async () => {});

beforeEach(async () => {
dataDir = await fs.promises.mkdtemp(
path.join(os.tmpdir(), 'polykey-test-'),
);
dbKey = await keysUtils.generateKey();
dbPath = path.join(dataDir, 'db');
await fs.promises.mkdir(dbPath);
efsDbPath = path.join(dataDir, 'efsDb');
await fs.promises.mkdir(efsDbPath);
efs = await EncryptedFS.createEncryptedFS({
dbPath,
dbPath: efsDbPath,
dbKey,
logger,
});
await efs.start();
});

beforeEach(async () => {
db = await DB.createDB({
crypto: {
key: await keysUtils.generateKey(),
ops: {
encrypt: keysUtils.encryptWithKey,
decrypt: keysUtils.decryptWithKey,
},
},
dbPath: path.join(dataDir, 'db'),
fs: fs,
logger: logger,
});
vaultsDbDomain = ['vaults'];
vaultsDb = await db.level(vaultsDbDomain[0]);

vaultId = generateVaultId();
vault = await VaultInternal.create({
vault = await VaultInternal.createVaultInternal({
vaultId,
keyManager: fakeKeyManager,
efs,
logger,
fresh: true,
db,
vaultsDb,
vaultsDbDomain,
vaultName: 'testVault',
});
});

afterAll(async () => {
afterEach(async () => {
await vault.stop();
await vault.destroy();
await db.stop();
await db.destroy();
await efs.stop();
await efs.destroy();
await fs.promises.rm(dataDir, {
Expand All @@ -73,9 +104,13 @@ describe('VaultInternal', () => {
});

test('VaultInternal readiness', async () => {
await vault.destroy();
await vault.stop();
await expect(async () => {
await vault.log();
}).rejects.toThrow(vaultsErrors.ErrorVaultNotRunning);
await vault.destroy();
await expect(async () => {
await vault.start();
}).rejects.toThrow(vaultsErrors.ErrorVaultDestroyed);
});
test('is type correct', async () => {
Expand All @@ -99,13 +134,17 @@ describe('VaultInternal', () => {
await vault.writeF(async (efs) => {
await efs.writeFile('secret-1', 'secret-content');
});
await vault.destroy();
vault = await VaultInternal.create({
await vault.stop();
vault = await VaultInternal.createVaultInternal({
vaultId,
keyManager: fakeKeyManager,
efs,
logger,
fresh: false,
db,
vaultName: 'testVault2',
vaultsDb,
vaultsDbDomain,
});
await vault.readF(async (efs) => {
expect((await efs.readFile('secret-1')).toString()).toStrictEqual(
Expand Down Expand Up @@ -155,7 +194,7 @@ describe('VaultInternal', () => {
});
test('does not allow changing to an unrecognised commit', async () => {
await expect(() => vault.version('unrecognisedcommit')).rejects.toThrow(
vaultsErrors.ErrorVaultReferenceMissing,
vaultsErrors.ErrorVaultReferenceInvalid,
);
await vault.writeF(async (efs) => {
await efs.writeFile('test1', 'testdata1');
Expand Down Expand Up @@ -598,15 +637,12 @@ describe('VaultInternal', () => {
expect(vaultNormal.destroy).toBeTruthy(); // This exists again.
});
test('cannot commit when the remote field is set', async () => {
await vault.destroy();
vault = await VaultInternal.create({
vaultId,
keyManager: fakeKeyManager,
efs,
logger,
remote: true,
fresh: true,
});
// Write remote metadata
await db.put(
[...vaultsDbDomain, vaultsUtils.encodeVaultId(vaultId)],
VaultInternal.remoteKey,
{ remoteNode: '', remoteVault: '' },
);
const commit = (await vault.log(undefined, 1))[0];
await vault.version(commit.commitId);
const files = await vault.readF(async (efs) => {
Expand Down
Loading

0 comments on commit ff4d516

Please sign in to comment.