urchin-vault 0.2.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.
- package/LICENSE +21 -0
- package/README.md +217 -0
- package/dist/cli.js +1206 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/auth.js +111 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/config.js +53 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/files.js +406 -0
- package/dist/commands/files.js.map +1 -0
- package/dist/commands/keys.js +159 -0
- package/dist/commands/keys.js.map +1 -0
- package/dist/lib/cifer.js +190 -0
- package/dist/lib/cifer.js.map +1 -0
- package/dist/lib/storage.js +108 -0
- package/dist/lib/storage.js.map +1 -0
- package/dist/lib/store.js +49 -0
- package/dist/lib/store.js.map +1 -0
- package/dist/lib/ui.js +250 -0
- package/dist/lib/ui.js.map +1 -0
- package/package.json +65 -0
- package/urchin.png +0 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CIFER SDK wrapper — handles both web2 and web3 modes.
|
|
3
|
+
*
|
|
4
|
+
* Hybrid encryption approach:
|
|
5
|
+
* 1. CIFER payload API (ML-KEM-768) encrypts a random AES-256 key
|
|
6
|
+
* 2. File content is encrypted locally with AES-256-GCM
|
|
7
|
+
*
|
|
8
|
+
* This bypasses the /encrypt-file endpoint which doesn't support
|
|
9
|
+
* web2 chain (-1) on the current blackbox server.
|
|
10
|
+
*/
|
|
11
|
+
import { createCiferSdk, web2, } from 'cifer-sdk';
|
|
12
|
+
import * as ed from '@noble/ed25519';
|
|
13
|
+
import crypto from 'crypto';
|
|
14
|
+
import { loadStore } from './store.js';
|
|
15
|
+
let sdkInstance = null;
|
|
16
|
+
let currentSession = null;
|
|
17
|
+
export async function getSdk() {
|
|
18
|
+
if (!sdkInstance) {
|
|
19
|
+
const { settings } = loadStore();
|
|
20
|
+
sdkInstance = await createCiferSdk({ blackboxUrl: settings.blackboxUrl });
|
|
21
|
+
}
|
|
22
|
+
return sdkInstance;
|
|
23
|
+
}
|
|
24
|
+
function getBlackboxUrl() {
|
|
25
|
+
return loadStore().settings.blackboxUrl;
|
|
26
|
+
}
|
|
27
|
+
async function getReadClient() {
|
|
28
|
+
const sdk = await getSdk();
|
|
29
|
+
return sdk.readClient;
|
|
30
|
+
}
|
|
31
|
+
// ─── Web2 Auth ──────────────────────────────────────────
|
|
32
|
+
export async function registerWeb2(email, password) {
|
|
33
|
+
const bbUrl = getBlackboxUrl();
|
|
34
|
+
const reg = await web2.auth.register({ email, password, blackboxUrl: bbUrl });
|
|
35
|
+
return reg;
|
|
36
|
+
}
|
|
37
|
+
export async function verifyWeb2(email, otp) {
|
|
38
|
+
const bbUrl = getBlackboxUrl();
|
|
39
|
+
await web2.auth.verifyEmail({ email, otp, blackboxUrl: bbUrl });
|
|
40
|
+
}
|
|
41
|
+
function makeEd25519Signer(privateKey, publicKey) {
|
|
42
|
+
return {
|
|
43
|
+
async sign(message) {
|
|
44
|
+
return ed.signAsync(message, privateKey);
|
|
45
|
+
},
|
|
46
|
+
getPublicKey() {
|
|
47
|
+
return publicKey;
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export async function loginWeb2(email, password) {
|
|
52
|
+
const sdk = await getSdk();
|
|
53
|
+
const bbUrl = getBlackboxUrl();
|
|
54
|
+
const privateKey = ed.utils.randomPrivateKey();
|
|
55
|
+
const publicKey = await ed.getPublicKeyAsync(privateKey);
|
|
56
|
+
const ed25519Signer = makeEd25519Signer(privateKey, publicKey);
|
|
57
|
+
// Look up principal
|
|
58
|
+
const principal = await web2.principal.getByEmail(email, bbUrl);
|
|
59
|
+
// Register Ed25519 key
|
|
60
|
+
await web2.auth.registerKey({
|
|
61
|
+
principalId: principal.principalId,
|
|
62
|
+
password,
|
|
63
|
+
ed25519Signer,
|
|
64
|
+
blackboxUrl: bbUrl,
|
|
65
|
+
});
|
|
66
|
+
// Create a session (stateless approach)
|
|
67
|
+
currentSession = await web2.session.createManagedSession({
|
|
68
|
+
principalId: principal.principalId,
|
|
69
|
+
ed25519Signer,
|
|
70
|
+
blackboxUrl: bbUrl,
|
|
71
|
+
});
|
|
72
|
+
return {
|
|
73
|
+
principalId: principal.principalId,
|
|
74
|
+
ed25519PrivateKey: Buffer.from(privateKey).toString('hex'),
|
|
75
|
+
ed25519PublicKey: Buffer.from(publicKey).toString('hex'),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export async function restoreWeb2Session(session) {
|
|
79
|
+
if (session.mode !== 'web2' || !session.ed25519PrivateKey || !session.principalId) {
|
|
80
|
+
throw new Error('Invalid web2 session data');
|
|
81
|
+
}
|
|
82
|
+
const bbUrl = getBlackboxUrl();
|
|
83
|
+
const privateKey = new Uint8Array(Buffer.from(session.ed25519PrivateKey, 'hex'));
|
|
84
|
+
const publicKey = new Uint8Array(Buffer.from(session.ed25519PublicKey, 'hex'));
|
|
85
|
+
const ed25519Signer = makeEd25519Signer(privateKey, publicKey);
|
|
86
|
+
currentSession = await web2.session.createManagedSession({
|
|
87
|
+
principalId: session.principalId,
|
|
88
|
+
ed25519Signer,
|
|
89
|
+
blackboxUrl: bbUrl,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
function requireSession() {
|
|
93
|
+
if (!currentSession)
|
|
94
|
+
throw new Error('Not logged in. Run: urchin login');
|
|
95
|
+
return currentSession;
|
|
96
|
+
}
|
|
97
|
+
// ─── Web2 Secret (Vault) Management ─────────────────────
|
|
98
|
+
export async function createWeb2Secret() {
|
|
99
|
+
const session = requireSession();
|
|
100
|
+
const bbUrl = getBlackboxUrl();
|
|
101
|
+
return web2.secret.createSecret({ session, blackboxUrl: bbUrl });
|
|
102
|
+
}
|
|
103
|
+
export async function listWeb2Secrets() {
|
|
104
|
+
const session = requireSession();
|
|
105
|
+
const bbUrl = getBlackboxUrl();
|
|
106
|
+
return web2.secret.listSecrets({ session, blackboxUrl: bbUrl });
|
|
107
|
+
}
|
|
108
|
+
export async function encryptFileWeb2(secretId, fileBuffer, fileName, onProgress) {
|
|
109
|
+
const session = requireSession();
|
|
110
|
+
const bbUrl = getBlackboxUrl();
|
|
111
|
+
const readClient = await getReadClient();
|
|
112
|
+
onProgress?.(10);
|
|
113
|
+
// Step 1: Generate a random 256-bit AES key
|
|
114
|
+
const aesKey = crypto.randomBytes(32);
|
|
115
|
+
const aesKeyHex = aesKey.toString('hex');
|
|
116
|
+
onProgress?.(20);
|
|
117
|
+
// Step 2: Encrypt the AES key using CIFER payload API (ML-KEM-768)
|
|
118
|
+
// This uses the web2 session and the /encrypt-payload endpoint
|
|
119
|
+
const keyEncrypted = await web2.blackbox.payload.encryptPayload({
|
|
120
|
+
session,
|
|
121
|
+
secretId: BigInt(secretId),
|
|
122
|
+
plaintext: aesKeyHex,
|
|
123
|
+
blackboxUrl: bbUrl,
|
|
124
|
+
readClient,
|
|
125
|
+
outputFormat: 'hex',
|
|
126
|
+
});
|
|
127
|
+
onProgress?.(50);
|
|
128
|
+
// Step 3: Encrypt the file locally with AES-256-GCM
|
|
129
|
+
const iv = crypto.randomBytes(12);
|
|
130
|
+
const cipher = crypto.createCipheriv('aes-256-gcm', aesKey, iv);
|
|
131
|
+
const encrypted = Buffer.concat([cipher.update(fileBuffer), cipher.final()]);
|
|
132
|
+
const authTag = cipher.getAuthTag();
|
|
133
|
+
onProgress?.(80);
|
|
134
|
+
// Step 4: Bundle everything together
|
|
135
|
+
const bundle = {
|
|
136
|
+
version: 1,
|
|
137
|
+
cifer: keyEncrypted.cifer,
|
|
138
|
+
encryptedKey: keyEncrypted.encryptedMessage,
|
|
139
|
+
iv: iv.toString('hex'),
|
|
140
|
+
authTag: authTag.toString('hex'),
|
|
141
|
+
encryptedData: encrypted.toString('base64'),
|
|
142
|
+
originalName: fileName,
|
|
143
|
+
originalSize: fileBuffer.byteLength,
|
|
144
|
+
};
|
|
145
|
+
const bundleJson = JSON.stringify(bundle);
|
|
146
|
+
const encryptedBlob = new Blob([new TextEncoder().encode(bundleJson)]);
|
|
147
|
+
onProgress?.(100);
|
|
148
|
+
return { encryptedBlob };
|
|
149
|
+
}
|
|
150
|
+
export async function decryptFileWeb2(secretId, fileBuffer, _fileName, onProgress) {
|
|
151
|
+
const session = requireSession();
|
|
152
|
+
const bbUrl = getBlackboxUrl();
|
|
153
|
+
const readClient = await getReadClient();
|
|
154
|
+
onProgress?.(10);
|
|
155
|
+
// Step 1: Parse the encrypted bundle
|
|
156
|
+
const bundleJson = fileBuffer.toString('utf-8');
|
|
157
|
+
let bundle;
|
|
158
|
+
try {
|
|
159
|
+
bundle = JSON.parse(bundleJson);
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
throw new Error('Invalid encrypted file format. Expected .cifer.json bundle.');
|
|
163
|
+
}
|
|
164
|
+
if (bundle.version !== 1) {
|
|
165
|
+
throw new Error(`Unsupported bundle version: ${bundle.version}`);
|
|
166
|
+
}
|
|
167
|
+
onProgress?.(20);
|
|
168
|
+
// Step 2: Decrypt the AES key using CIFER payload API
|
|
169
|
+
const keyDecrypted = await web2.blackbox.payload.decryptPayload({
|
|
170
|
+
session,
|
|
171
|
+
secretId: BigInt(secretId),
|
|
172
|
+
encryptedMessage: bundle.encryptedKey,
|
|
173
|
+
cifer: bundle.cifer,
|
|
174
|
+
blackboxUrl: bbUrl,
|
|
175
|
+
readClient,
|
|
176
|
+
inputFormat: 'hex',
|
|
177
|
+
});
|
|
178
|
+
onProgress?.(50);
|
|
179
|
+
const aesKey = Buffer.from(keyDecrypted.decryptedMessage, 'hex');
|
|
180
|
+
const iv = Buffer.from(bundle.iv, 'hex');
|
|
181
|
+
const authTag = Buffer.from(bundle.authTag, 'hex');
|
|
182
|
+
const encryptedData = Buffer.from(bundle.encryptedData, 'base64');
|
|
183
|
+
// Step 3: Decrypt the file locally with AES-256-GCM
|
|
184
|
+
const decipher = crypto.createDecipheriv('aes-256-gcm', aesKey, iv);
|
|
185
|
+
decipher.setAuthTag(authTag);
|
|
186
|
+
const decrypted = Buffer.concat([decipher.update(encryptedData), decipher.final()]);
|
|
187
|
+
onProgress?.(100);
|
|
188
|
+
return new Blob([decrypted]);
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=cifer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cifer.js","sourceRoot":"","sources":["../../src/lib/cifer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EACL,cAAc,EACd,IAAI,GAEL,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAsB,MAAM,YAAY,CAAC;AAE3D,IAAI,WAAW,GAAsD,IAAI,CAAC;AAC1E,IAAI,cAAc,GAAQ,IAAI,CAAC;AAE/B,MAAM,CAAC,KAAK,UAAU,MAAM;IAC1B,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,EAAE,QAAQ,EAAE,GAAG,SAAS,EAAE,CAAC;QACjC,WAAW,GAAG,MAAM,cAAc,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAS,cAAc;IACrB,OAAO,SAAS,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;AAC1C,CAAC;AAED,KAAK,UAAU,aAAa;IAC1B,MAAM,GAAG,GAAG,MAAM,MAAM,EAAE,CAAC;IAC3B,OAAO,GAAG,CAAC,UAAU,CAAC;AACxB,CAAC;AAED,2DAA2D;AAE3D,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAAa,EAAE,QAAgB;IAChE,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;IAC/B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9E,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,KAAa,EAAE,GAAW;IACzD,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;IAC/B,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,iBAAiB,CAAC,UAAsB,EAAE,SAAqB;IACtE,OAAO;QACL,KAAK,CAAC,IAAI,CAAC,OAAmB;YAC5B,OAAO,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QAC3C,CAAC;QACD,YAAY;YACV,OAAO,SAAS,CAAC;QACnB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAa,EAAE,QAAgB;IAC7D,MAAM,GAAG,GAAG,MAAM,MAAM,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;IAE/B,MAAM,UAAU,GAAG,EAAE,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC;IAC/C,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;IACzD,MAAM,aAAa,GAAG,iBAAiB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IAE/D,oBAAoB;IACpB,MAAM,SAAS,GAAG,MAAO,IAAI,CAAC,SAAiB,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAEzE,uBAAuB;IACvB,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC;QAC1B,WAAW,EAAE,SAAS,CAAC,WAAW;QAClC,QAAQ;QACR,aAAa;QACb,WAAW,EAAE,KAAK;KACnB,CAAC,CAAC;IAEH,wCAAwC;IACxC,cAAc,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC;QACvD,WAAW,EAAE,SAAS,CAAC,WAAW;QAClC,aAAa;QACb,WAAW,EAAE,KAAK;KACnB,CAAC,CAAC;IAEH,OAAO;QACL,WAAW,EAAE,SAAS,CAAC,WAAW;QAClC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;QAC1D,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;KACzD,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAsB;IAC7D,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,OAAO,CAAC,iBAAiB,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAClF,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;IAC/B,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC,CAAC;IACjF,MAAM,SAAS,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAiB,EAAE,KAAK,CAAC,CAAC,CAAC;IAChF,MAAM,aAAa,GAAG,iBAAiB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IAE/D,cAAc,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC;QACvD,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,aAAa;QACb,WAAW,EAAE,KAAK;KACnB,CAAC,CAAC;AACL,CAAC;AAED,SAAS,cAAc;IACrB,IAAI,CAAC,cAAc;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACzE,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,2DAA2D;AAE3D,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;IAC/B,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;IAC/B,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;AAClE,CAAC;AA+BD,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAgB,EAChB,UAAkB,EAClB,QAAgB,EAChB,UAAkC;IAElC,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;IAC/B,MAAM,UAAU,GAAG,MAAM,aAAa,EAAE,CAAC;IAEzC,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;IAEjB,4CAA4C;IAC5C,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACtC,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEzC,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;IAEjB,mEAAmE;IACnE,+DAA+D;IAC/D,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC;QAC9D,OAAO;QACP,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;QAC1B,SAAS,EAAE,SAAS;QACpB,WAAW,EAAE,KAAK;QAClB,UAAU;QACV,YAAY,EAAE,KAAK;KACpB,CAAC,CAAC;IAEH,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;IAEjB,oDAAoD;IACpD,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IAChE,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC7E,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;IAEpC,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;IAEjB,qCAAqC;IACrC,MAAM,MAAM,GAAoB;QAC9B,OAAO,EAAE,CAAC;QACV,KAAK,EAAE,YAAY,CAAC,KAAK;QACzB,YAAY,EAAE,YAAY,CAAC,gBAAgB;QAC3C,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;QACtB,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;QAChC,aAAa,EAAE,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC3C,YAAY,EAAE,QAAQ;QACtB,YAAY,EAAE,UAAU,CAAC,UAAU;KACpC,CAAC;IAEF,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,aAAa,GAAG,IAAI,IAAI,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAEvE,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC;IAElB,OAAO,EAAE,aAAa,EAAE,CAAC;AAC3B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAgB,EAChB,UAAkB,EAClB,SAAiB,EACjB,UAAkC;IAElC,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;IAC/B,MAAM,UAAU,GAAG,MAAM,aAAa,EAAE,CAAC;IAEzC,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;IAEjB,qCAAqC;IACrC,MAAM,UAAU,GAAG,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAChD,IAAI,MAAuB,CAAC;IAC5B,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;IACjF,CAAC;IAED,IAAI,MAAM,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,+BAA+B,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;IAEjB,sDAAsD;IACtD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC;QAC9D,OAAO;QACP,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;QAC1B,gBAAgB,EAAE,MAAM,CAAC,YAAY;QACrC,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,WAAW,EAAE,KAAK;QAClB,UAAU;QACV,WAAW,EAAE,KAAK;KACnB,CAAC,CAAC;IAEH,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;IAEjB,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;IACjE,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACnD,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;IAElE,oDAAoD;IACpD,MAAM,QAAQ,GAAG,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IACpE,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAC7B,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAEpF,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC;IAElB,OAAO,IAAI,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage provider abstraction.
|
|
3
|
+
*
|
|
4
|
+
* Supports multiple backends for uploading encrypted files:
|
|
5
|
+
* - storacha (Filecoin/IPFS via Storacha CLI)
|
|
6
|
+
* - local (save encrypted file to a local directory)
|
|
7
|
+
*
|
|
8
|
+
* Extensible: add ipfs-pinning, s3, etc. by implementing StorageProvider.
|
|
9
|
+
*/
|
|
10
|
+
import { execFile } from 'child_process';
|
|
11
|
+
import { promisify } from 'util';
|
|
12
|
+
import fs from 'fs';
|
|
13
|
+
import path from 'path';
|
|
14
|
+
import os from 'os';
|
|
15
|
+
import crypto from 'crypto';
|
|
16
|
+
const exec = promisify(execFile);
|
|
17
|
+
// ─── Storacha (Filecoin/IPFS) ────────────────────────────
|
|
18
|
+
export class StorachaProvider {
|
|
19
|
+
name = 'storacha';
|
|
20
|
+
gateway = 'https://storacha.link/ipfs';
|
|
21
|
+
async check() {
|
|
22
|
+
try {
|
|
23
|
+
await exec('storacha', ['whoami']);
|
|
24
|
+
return { ok: true };
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
if (err.code === 'ENOENT') {
|
|
28
|
+
return { ok: false, error: 'Storacha CLI not found. Install: npm i -g @storacha/cli' };
|
|
29
|
+
}
|
|
30
|
+
return { ok: false, error: `Storacha not ready: ${err.stderr || err.message}` };
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async upload(data, fileName) {
|
|
34
|
+
const tmpDir = path.join(os.tmpdir(), 'cifer-vault');
|
|
35
|
+
if (!fs.existsSync(tmpDir))
|
|
36
|
+
fs.mkdirSync(tmpDir, { recursive: true });
|
|
37
|
+
const tmpFile = path.join(tmpDir, `${fileName}.cifer`);
|
|
38
|
+
fs.writeFileSync(tmpFile, data);
|
|
39
|
+
try {
|
|
40
|
+
const { stdout } = await exec('storacha', ['up', tmpFile, '--no-wrap']);
|
|
41
|
+
const cidMatch = stdout.match(/ipfs\/(baf[a-z0-9]+)/) || stdout.match(/(baf[a-z0-9]{50,})/);
|
|
42
|
+
if (!cidMatch)
|
|
43
|
+
throw new Error(`Could not parse CID from: ${stdout.trim()}`);
|
|
44
|
+
return cidMatch[1];
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
try {
|
|
48
|
+
fs.unlinkSync(tmpFile);
|
|
49
|
+
}
|
|
50
|
+
catch { }
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async download(cid) {
|
|
54
|
+
const url = `${this.gateway}/${cid}`;
|
|
55
|
+
const response = await fetch(url);
|
|
56
|
+
if (!response.ok)
|
|
57
|
+
throw new Error(`Download failed (${response.status}): ${response.statusText}`);
|
|
58
|
+
return Buffer.from(await response.arrayBuffer());
|
|
59
|
+
}
|
|
60
|
+
getUrl(cid) {
|
|
61
|
+
return `${this.gateway}/${cid}`;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// ─── Local filesystem storage ────────────────────────────
|
|
65
|
+
export class LocalProvider {
|
|
66
|
+
name = 'local';
|
|
67
|
+
dir;
|
|
68
|
+
constructor(dir) {
|
|
69
|
+
this.dir = dir || path.join(os.homedir(), '.cifer-vault', 'encrypted');
|
|
70
|
+
if (!fs.existsSync(this.dir))
|
|
71
|
+
fs.mkdirSync(this.dir, { recursive: true });
|
|
72
|
+
}
|
|
73
|
+
async check() {
|
|
74
|
+
return { ok: true };
|
|
75
|
+
}
|
|
76
|
+
async upload(data, fileName) {
|
|
77
|
+
// Use a content-based hash as the "CID"
|
|
78
|
+
const hash = crypto.createHash('sha256').update(data).digest('hex');
|
|
79
|
+
const id = `local-${hash.slice(0, 16)}`;
|
|
80
|
+
const filePath = path.join(this.dir, `${id}.cifer`);
|
|
81
|
+
fs.writeFileSync(filePath, data);
|
|
82
|
+
return id;
|
|
83
|
+
}
|
|
84
|
+
async download(id) {
|
|
85
|
+
const filePath = path.join(this.dir, `${id}.cifer`);
|
|
86
|
+
if (!fs.existsSync(filePath))
|
|
87
|
+
throw new Error(`Local file not found: ${id}`);
|
|
88
|
+
return fs.readFileSync(filePath);
|
|
89
|
+
}
|
|
90
|
+
getUrl(id) {
|
|
91
|
+
return path.join(this.dir, `${id}.cifer`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// ─── Registry ────────────────────────────────────────────
|
|
95
|
+
const providers = {
|
|
96
|
+
storacha: () => new StorachaProvider(),
|
|
97
|
+
local: () => new LocalProvider(),
|
|
98
|
+
};
|
|
99
|
+
export function getProvider(name) {
|
|
100
|
+
const factory = providers[name];
|
|
101
|
+
if (!factory)
|
|
102
|
+
throw new Error(`Unknown storage provider: ${name}. Available: ${Object.keys(providers).join(', ')}`);
|
|
103
|
+
return factory();
|
|
104
|
+
}
|
|
105
|
+
export function listProviders() {
|
|
106
|
+
return Object.keys(providers);
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/lib/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local JSON file store for vault data.
|
|
3
|
+
* Stored at ~/.cifer-vault/data.json
|
|
4
|
+
*/
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import os from 'os';
|
|
8
|
+
const STORE_DIR = path.join(os.homedir(), '.cifer-vault');
|
|
9
|
+
const STORE_FILE = path.join(STORE_DIR, 'data.json');
|
|
10
|
+
const DEFAULT_DATA = {
|
|
11
|
+
session: null,
|
|
12
|
+
vaults: [],
|
|
13
|
+
files: [],
|
|
14
|
+
settings: {
|
|
15
|
+
blackboxUrl: 'https://cifer-blackbox.ternoa.dev:3010',
|
|
16
|
+
chainId: 752025,
|
|
17
|
+
defaultProvider: 'storacha',
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
function ensureDir() {
|
|
21
|
+
if (!fs.existsSync(STORE_DIR)) {
|
|
22
|
+
fs.mkdirSync(STORE_DIR, { recursive: true });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export function loadStore() {
|
|
26
|
+
ensureDir();
|
|
27
|
+
if (!fs.existsSync(STORE_FILE)) {
|
|
28
|
+
return { ...DEFAULT_DATA };
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const raw = fs.readFileSync(STORE_FILE, 'utf-8');
|
|
32
|
+
return { ...DEFAULT_DATA, ...JSON.parse(raw) };
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return { ...DEFAULT_DATA };
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export function saveStore(data) {
|
|
39
|
+
ensureDir();
|
|
40
|
+
fs.writeFileSync(STORE_FILE, JSON.stringify(data, null, 2));
|
|
41
|
+
}
|
|
42
|
+
export function getSession() {
|
|
43
|
+
const data = loadStore();
|
|
44
|
+
if (!data.session) {
|
|
45
|
+
throw new Error('Not logged in. Run: urchin login');
|
|
46
|
+
}
|
|
47
|
+
return data.session;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/lib/store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,CAAC;AAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;AA2CrD,MAAM,YAAY,GAAc;IAC9B,OAAO,EAAE,IAAI;IACb,MAAM,EAAE,EAAE;IACV,KAAK,EAAE,EAAE;IACT,QAAQ,EAAE;QACR,WAAW,EAAE,wCAAwC;QACrD,OAAO,EAAE,MAAM;QACf,eAAe,EAAE,UAAU;KAC5B;CACF,CAAC;AAEF,SAAS,SAAS;IAChB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,SAAS,EAAE,CAAC;IACZ,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,OAAO,EAAE,GAAG,YAAY,EAAE,CAAC;IAC7B,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACjD,OAAO,EAAE,GAAG,YAAY,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,GAAG,YAAY,EAAE,CAAC;IAC7B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAe;IACvC,SAAS,EAAE,CAAC;IACZ,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,IAAI,GAAG,SAAS,EAAE,CAAC;IACzB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,CAAC;AACtB,CAAC"}
|
package/dist/lib/ui.js
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Visual helpers for CLI output — premium terminal UI.
|
|
3
|
+
*/
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import boxen from 'boxen';
|
|
6
|
+
import gradient from 'gradient-string';
|
|
7
|
+
import Table from 'cli-table3';
|
|
8
|
+
import figures from 'figures';
|
|
9
|
+
// ─── Brand palette ──────────────────────────────────────
|
|
10
|
+
const CIFER_GREEN = '#00FF88';
|
|
11
|
+
const CIFER_CYAN = '#00D4FF';
|
|
12
|
+
const CIFER_PURPLE = '#A855F7';
|
|
13
|
+
const CIFER_DARK = '#0A0A0A';
|
|
14
|
+
const ACCENT = chalk.hex(CIFER_GREEN);
|
|
15
|
+
const CYAN = chalk.hex(CIFER_CYAN);
|
|
16
|
+
const PURPLE = chalk.hex(CIFER_PURPLE);
|
|
17
|
+
const DIM = chalk.dim;
|
|
18
|
+
const BOLD = chalk.bold;
|
|
19
|
+
const WARN = chalk.yellow;
|
|
20
|
+
const ERR = chalk.red;
|
|
21
|
+
const OK = chalk.green;
|
|
22
|
+
export { ACCENT, CYAN, PURPLE, DIM, BOLD, WARN, ERR, OK };
|
|
23
|
+
// ─── Gradient presets ───────────────────────────────────
|
|
24
|
+
const ciferGrad = gradient([CIFER_GREEN, CIFER_CYAN]);
|
|
25
|
+
const purpleGrad = gradient([CIFER_CYAN, CIFER_PURPLE]);
|
|
26
|
+
export { ciferGrad, purpleGrad };
|
|
27
|
+
// ─── ASCII Art Banner ───────────────────────────────────
|
|
28
|
+
const LOGO_ART = `
|
|
29
|
+
██╗ ██╗██████╗ ██████╗██╗ ██╗██╗███╗ ██╗
|
|
30
|
+
██║ ██║██╔══██╗██╔════╝██║ ██║██║████╗ ██║
|
|
31
|
+
██║ ██║██████╔╝██║ ███████║██║██╔██╗ ██║
|
|
32
|
+
██║ ██║██╔══██╗██║ ██╔══██║██║██║╚██╗██║
|
|
33
|
+
╚██████╔╝██║ ██║╚██████╗██║ ██║██║██║ ╚████║
|
|
34
|
+
╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝`.trimStart();
|
|
35
|
+
export function banner(compact = false) {
|
|
36
|
+
if (compact) {
|
|
37
|
+
console.log('');
|
|
38
|
+
console.log(ciferGrad.multiline(LOGO_ART));
|
|
39
|
+
console.log('');
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
console.log('');
|
|
43
|
+
console.log(ciferGrad.multiline(LOGO_ART));
|
|
44
|
+
console.log('');
|
|
45
|
+
console.log(chalk.gray(' ') +
|
|
46
|
+
ACCENT.bold('Quantum-Encrypted Vault') +
|
|
47
|
+
chalk.gray(' │ ') +
|
|
48
|
+
DIM('v0.2.0') +
|
|
49
|
+
chalk.gray(' │ ') +
|
|
50
|
+
DIM('ML-KEM-768 + AES-256-GCM'));
|
|
51
|
+
console.log('');
|
|
52
|
+
}
|
|
53
|
+
// ─── Box frame ──────────────────────────────────────────
|
|
54
|
+
export function box(content, title) {
|
|
55
|
+
console.log(boxen(content, {
|
|
56
|
+
padding: { top: 0, bottom: 0, left: 1, right: 1 },
|
|
57
|
+
margin: { top: 0, bottom: 0, left: 1, right: 0 },
|
|
58
|
+
borderStyle: 'round',
|
|
59
|
+
borderColor: 'green',
|
|
60
|
+
title: title ? ` ${title} ` : undefined,
|
|
61
|
+
titleAlignment: 'left',
|
|
62
|
+
}));
|
|
63
|
+
}
|
|
64
|
+
// ─── Section header ─────────────────────────────────────
|
|
65
|
+
export function header(title, subtitle) {
|
|
66
|
+
const line = ACCENT('─'.repeat(3));
|
|
67
|
+
const sub = subtitle ? ` ${DIM(subtitle)}` : '';
|
|
68
|
+
console.log(`\n ${line} ${ACCENT.bold(title)}${sub} ${line}`);
|
|
69
|
+
}
|
|
70
|
+
// ─── Key-value pair ─────────────────────────────────────
|
|
71
|
+
export function kv(key, value, indent = 4) {
|
|
72
|
+
const pad = ' '.repeat(indent);
|
|
73
|
+
console.log(`${pad}${DIM(key)} ${value}`);
|
|
74
|
+
}
|
|
75
|
+
// ─── Status badges ──────────────────────────────────────
|
|
76
|
+
export function badge(label, color = 'green') {
|
|
77
|
+
const colors = {
|
|
78
|
+
green: ACCENT,
|
|
79
|
+
cyan: CYAN,
|
|
80
|
+
purple: PURPLE,
|
|
81
|
+
yellow: WARN,
|
|
82
|
+
red: ERR,
|
|
83
|
+
dim: DIM,
|
|
84
|
+
};
|
|
85
|
+
const c = colors[color] || ACCENT;
|
|
86
|
+
return c(`[${label}]`);
|
|
87
|
+
}
|
|
88
|
+
// ─── Success / Error / Warn messages ────────────────────
|
|
89
|
+
export function success(msg) {
|
|
90
|
+
console.log(` ${ACCENT(figures.tick)} ${msg}`);
|
|
91
|
+
}
|
|
92
|
+
export function error(msg) {
|
|
93
|
+
console.error(` ${ERR(figures.cross)} ${msg}`);
|
|
94
|
+
}
|
|
95
|
+
export function warn(msg) {
|
|
96
|
+
console.log(` ${WARN(figures.warning)} ${msg}`);
|
|
97
|
+
}
|
|
98
|
+
export function info(msg) {
|
|
99
|
+
console.log(` ${CYAN(figures.info)} ${msg}`);
|
|
100
|
+
}
|
|
101
|
+
// ─── Progress bar (static, for dashboard) ───────────────
|
|
102
|
+
export function progressBar(current, total, width = 20) {
|
|
103
|
+
if (total === 0)
|
|
104
|
+
return DIM('░'.repeat(width));
|
|
105
|
+
const ratio = Math.min(current / total, 1);
|
|
106
|
+
const filled = Math.round(ratio * width);
|
|
107
|
+
const empty = width - filled;
|
|
108
|
+
return ACCENT('█'.repeat(filled)) + DIM('░'.repeat(empty));
|
|
109
|
+
}
|
|
110
|
+
// ─── Table-like file listing ────────────────────────────
|
|
111
|
+
export function fileRow(name, size, keyName, provider, date, cid, id) {
|
|
112
|
+
const provIcon = providerEmoji(provider);
|
|
113
|
+
const row = [
|
|
114
|
+
` ${provIcon} ${BOLD(name)}`,
|
|
115
|
+
DIM(size),
|
|
116
|
+
`${ACCENT('⚷')} ${keyName}`,
|
|
117
|
+
DIM(date),
|
|
118
|
+
].join(chalk.gray(' │ '));
|
|
119
|
+
console.log(row);
|
|
120
|
+
console.log(` ${DIM(`${cid}`)}`);
|
|
121
|
+
}
|
|
122
|
+
// ─── Create a clean table ───────────────────────────────
|
|
123
|
+
export function createTable(head, colWidths) {
|
|
124
|
+
const opts = {
|
|
125
|
+
head: head.map(h => ACCENT.bold(h)),
|
|
126
|
+
chars: {
|
|
127
|
+
'top': '─', 'top-mid': '┬', 'top-left': '┌', 'top-right': '┐',
|
|
128
|
+
'bottom': '─', 'bottom-mid': '┴', 'bottom-left': '└', 'bottom-right': '┘',
|
|
129
|
+
'left': '│', 'left-mid': '├', 'mid': '─', 'mid-mid': '┼',
|
|
130
|
+
'right': '│', 'right-mid': '┤', 'middle': '│',
|
|
131
|
+
},
|
|
132
|
+
style: {
|
|
133
|
+
head: [],
|
|
134
|
+
border: ['gray'],
|
|
135
|
+
'padding-left': 1,
|
|
136
|
+
'padding-right': 1,
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
if (colWidths)
|
|
140
|
+
opts.colWidths = colWidths;
|
|
141
|
+
return new Table(opts);
|
|
142
|
+
}
|
|
143
|
+
// ─── Provider display ───────────────────────────────────
|
|
144
|
+
export function providerEmoji(provider) {
|
|
145
|
+
switch (provider) {
|
|
146
|
+
case 'storacha': return '🌐';
|
|
147
|
+
case 'ipfs-pinning': return '📌';
|
|
148
|
+
case 's3': return '☁️';
|
|
149
|
+
case 'local': return '💾';
|
|
150
|
+
default: return '📦';
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
export function providerLabel(name, isDefault) {
|
|
154
|
+
const icon = providerEmoji(name);
|
|
155
|
+
const label = BOLD(name);
|
|
156
|
+
const tag = isDefault ? ACCENT(' ★ default') : '';
|
|
157
|
+
return `${icon} ${label}${tag}`;
|
|
158
|
+
}
|
|
159
|
+
// ─── Key display ────────────────────────────────────────
|
|
160
|
+
export function keyLabel(name, secretId) {
|
|
161
|
+
return `${ACCENT('⚷')} ${BOLD(name)} ${DIM(`#${secretId}`)}`;
|
|
162
|
+
}
|
|
163
|
+
// ─── Separator ──────────────────────────────────────────
|
|
164
|
+
export function sep(width = 50) {
|
|
165
|
+
console.log(` ${DIM('─'.repeat(width))}`);
|
|
166
|
+
}
|
|
167
|
+
// ─── Status dashboard (new premium layout) ──────────────
|
|
168
|
+
export function dashboard(data) {
|
|
169
|
+
// ─── User line ──────────────────────────────────────
|
|
170
|
+
const userLine = `${ACCENT(figures.circleFilled)} ${BOLD(data.user)} ${badge(data.mode, 'cyan')}`;
|
|
171
|
+
console.log(` ${userLine}`);
|
|
172
|
+
console.log('');
|
|
173
|
+
// ─── Providers section ──────────────────────────────
|
|
174
|
+
header('PROVIDERS');
|
|
175
|
+
console.log('');
|
|
176
|
+
for (const p of data.providers) {
|
|
177
|
+
const dot = p.isDefault ? ACCENT(figures.circleFilled) : DIM(figures.circle);
|
|
178
|
+
const icon = providerEmoji(p.name);
|
|
179
|
+
const defTag = p.isDefault ? ACCENT(' ★') : '';
|
|
180
|
+
const files = DIM(`${p.fileCount} file${p.fileCount !== 1 ? 's' : ''}`);
|
|
181
|
+
console.log(` ${dot} ${icon} ${BOLD(p.name)}${defTag} ${DIM('│')} ${DIM(p.desc)} ${DIM('│')} ${files}`);
|
|
182
|
+
}
|
|
183
|
+
console.log('');
|
|
184
|
+
// ─── Keys section ───────────────────────────────────
|
|
185
|
+
header('KEYS', 'CIFER ML-KEM-768');
|
|
186
|
+
console.log('');
|
|
187
|
+
if (data.keys.length === 0) {
|
|
188
|
+
console.log(` ${DIM('No keys yet.')} Run ${ACCENT.bold('urchin key create')}`);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
for (const k of data.keys) {
|
|
192
|
+
const bar = progressBar(k.fileCount, Math.max(k.fileCount, 5), 10);
|
|
193
|
+
console.log(` ${ACCENT('⚷')} ${BOLD(k.name.padEnd(16))}` +
|
|
194
|
+
`${DIM('secret')} ${PURPLE(`#${k.secretId}`)} ` +
|
|
195
|
+
`${DIM('│')} ${bar} ${DIM(`${k.fileCount} files`)} ` +
|
|
196
|
+
`${DIM('│')} ${DIM(formatBytes(k.totalSize))}`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
console.log('');
|
|
200
|
+
// ─── Recent files ───────────────────────────────────
|
|
201
|
+
if (data.recentFiles.length > 0) {
|
|
202
|
+
header('RECENT FILES');
|
|
203
|
+
console.log('');
|
|
204
|
+
const table = createTable(['', 'File', 'Size', 'Key', 'Date']);
|
|
205
|
+
for (const f of data.recentFiles) {
|
|
206
|
+
table.push([
|
|
207
|
+
providerEmoji(f.provider),
|
|
208
|
+
BOLD(f.name),
|
|
209
|
+
DIM(formatBytes(f.size)),
|
|
210
|
+
`${ACCENT('⚷')} ${f.keyName}`,
|
|
211
|
+
DIM(f.date),
|
|
212
|
+
]);
|
|
213
|
+
}
|
|
214
|
+
console.log(table.toString().split('\n').map(l => ' ' + l).join('\n'));
|
|
215
|
+
console.log('');
|
|
216
|
+
}
|
|
217
|
+
// ─── Footer ─────────────────────────────────────────
|
|
218
|
+
sep();
|
|
219
|
+
console.log(` ${DIM(figures.arrowRight)} ${DIM('push')} ${chalk.gray('file')} ${DIM(figures.arrowLeft)} ${DIM('pull')} ${chalk.gray('file')} ${DIM(figures.bullet)} ${DIM('ls')} ${DIM(figures.bullet)} ${DIM('key create')} ${DIM(figures.bullet)} ${DIM('--help')}`);
|
|
220
|
+
console.log(` ${DIM(`Encryption: ML-KEM-768 (post-quantum) + AES-256-GCM`)}`);
|
|
221
|
+
console.log(` ${DIM(`Docs: ${CYAN('https://sdk.cifer-security.com/docs/')}`)}`);
|
|
222
|
+
console.log('');
|
|
223
|
+
}
|
|
224
|
+
// ─── Formatters ─────────────────────────────────────────
|
|
225
|
+
export function formatBytes(bytes) {
|
|
226
|
+
if (bytes < 1024)
|
|
227
|
+
return `${bytes} B`;
|
|
228
|
+
if (bytes < 1024 * 1024)
|
|
229
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
230
|
+
if (bytes < 1024 * 1024 * 1024)
|
|
231
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
232
|
+
return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
|
|
233
|
+
}
|
|
234
|
+
// ─── Help footer ────────────────────────────────────────
|
|
235
|
+
export function helpFooter() {
|
|
236
|
+
sep();
|
|
237
|
+
console.log(` ${DIM(`Encryption: ML-KEM-768 (post-quantum) + AES-256-GCM`)}`);
|
|
238
|
+
console.log(` ${DIM(`Docs: ${CYAN('https://sdk.cifer-security.com/docs/')}`)}`);
|
|
239
|
+
console.log('');
|
|
240
|
+
}
|
|
241
|
+
// ─── Spinner-style step labels (for push/pull flows) ────
|
|
242
|
+
export function step(num, total, label) {
|
|
243
|
+
const counter = DIM(`[${num}/${total}]`);
|
|
244
|
+
console.log(` ${ACCENT(figures.pointer)} ${counter} ${label}`);
|
|
245
|
+
}
|
|
246
|
+
// ─── Flow arrow display (file → key → provider) ────────
|
|
247
|
+
export function flowArrow(file, key, provider) {
|
|
248
|
+
console.log(` ${BOLD(file)} ${ACCENT('→')} ${ACCENT('⚷')} ${BOLD(key)} ${ACCENT('→')} ${providerEmoji(provider)} ${BOLD(provider)}`);
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=ui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/lib/ui.ts"],"names":[],"mappings":"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"}
|