Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

autho

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

autho - npm Package Compare versions

Comparing version 0.0.3 to 0.0.4

src/cli/wizards/getEncryptionKey.js

2

package.json
{
"name": "autho",
"version": "0.0.3",
"version": "0.0.4",
"main": "index.js",

@@ -5,0 +5,0 @@ "type": "module",

@@ -6,5 +6,7 @@ #!/usr/bin/env node

import { prompt, ask } from "./utils.js";
import Config from "../sdk/config.js";
import DB from "../sdk/db.js";
import Cipher from "../sdk/cipher.js";
import createSecret from "./wizards/createSecret.js";
import getEncryptionKey from "./wizards/getEncryptionKey.js";
import getSecret from "./wizards/getSecret.js";
import Secrets from "../sdk/secrets.js";

@@ -15,31 +17,25 @@ import OTP from "../sdk/otp.js";

const getSecret = async (config) => {
const existingSecrets = config.get("secrets", []);
//type AppOptions = {
// masterPasswordHash?: string;
// masterPassword?: string;
// appFolder?: string;
// };
if (existingSecrets.length === 0) {
throw new Error("No secrets found");
class App {
constructor(options = {}) {
let masterPasswordHash =
options.masterPasswordHash || process.env.AUTHO_MASTER_PASSWORD_HASH;
const masterPassword = options.masterPassword || process.env.AUTHO_MASTER_PASSWORD;
if (!masterPasswordHash && !masterPassword) {
throw new Error("Master password or master password hash is required")
}
masterPasswordHash =
masterPasswordHash ||
Cipher.hash(masterPassword);
this.db = new DB({ encryptionKey: masterPasswordHash });
this.secrets = new Secrets(this);
}
const choices = existingSecrets.map((secret) => ({
value: secret.id,
name: `${secret.name} (${secret.typeOptions.username || secret.id})`,
}));
}
const { id: secretId } = await prompt({
name: "id",
message: "Secrets:",
type: "list",
choices,
required: true,
});
const secrets = new Secrets(config);
const secret = await secrets.get(secretId);
if (!secret) {
throw new Error("Secret not found");
}
return secret;
};
program

@@ -60,5 +56,5 @@ .name("autho")

});
const masterPasswordHash = Cipher.hash(masterPassword);
const config = new Config({ encryptionKey: masterPasswordHash });
const app = new App({ masterPassword });
let choices = [

@@ -76,11 +72,21 @@ { value: "create", name: "Create new secret" },

});
switch (action) {
case "create":
await createSecret(config, masterPasswordHash);
await createSecret(app);
break;
case "read":
const readSecret = await getSecret(config);
readSecret.value = Cipher.decrypt(readSecret.value, readSecret.publicKey, masterPasswordHash)
const readSecret = await getSecret(app);
let encryptionKey = app.db.encryptionKey
if (readSecret.protected) {
encryptionKey = await getEncryptionKey()
}
readSecret.value = Cipher.decrypt(
readSecret.value,
readSecret.publicKey,
encryptionKey,
readSecret.signature
);
switch (readSecret.type) {

@@ -106,8 +112,9 @@ case "password":

case "delete":
const deleteSecret = await getSecret(config);
const secrets = new Secrets(config);
await secrets.remove(deleteSecret.id)
const deleteSecret = await getSecret(app);
await app.secrets.remove(deleteSecret.id);
console.log("Removed");
process.exit(0);
break;
default:
console.log("Unknown action:", action);
process.exit(1);
}

@@ -114,0 +121,0 @@ } catch (error) {

import { prompt } from "../utils.js";
import Secrets from "../../sdk/secrets.js";
import getEncryptionKey from "./getEncryptionKey.js";
const wizard = async (config, masterPasswordHash) => {
const wizard = async (app) => {
const secrets = app.secrets;
const info = await prompt([

@@ -19,2 +20,9 @@ {

required: true,
},
{
name: "protected",
message: "protected:",
type: "confirm",
default: false,
required: true,
}

@@ -24,3 +32,8 @@ ]);

let newSecret = {};
let encryptionKey = app.db.encryptionKey
if (info.protected) {
encryptionKey = await getEncryptionKey(true)
}
switch (info.type) {

@@ -43,4 +56,3 @@ case "password":

newSecret = {
name: info.name,
type: info.type,
...info,
value: password.value,

@@ -62,4 +74,3 @@ typeOptions: {

newSecret = {
name: info.name,
type: info.type,
...info,
value: note.value,

@@ -87,4 +98,3 @@ typeOptions: {

newSecret = {
name: info.name,
type: info.type,
...info,
value: otp.value,

@@ -98,6 +108,5 @@ typeOptions: {

const secrets = new Secrets(config);
await secrets.add(newSecret, masterPasswordHash);
await secrets.add(newSecret, encryptionKey);
};
export default wizard;
import crypto from "crypto";
const algorithm = "aes-256-ctr";
const IV_LENGTH = 16;
export default class Cipher {
constructor() { }
static hash(text) {
const hash = crypto.createHash("sha256");
static hash(text, algorithm = "sha256") {
const hash = crypto.createHash(algorithm);
hash.update(text);

@@ -16,3 +12,3 @@

static random(size = IV_LENGTH) {
static random(size = 16) {
const rnd = crypto.randomBytes(size);

@@ -29,7 +25,20 @@

static encrypt(text, password) {
static sign(text) {
const hash = Cipher.hash(text)
const signature = `${hash.substring(0, 10)}:${hash.substring(hash.length - 10)}`;
return signature;
}
static verify(text, signature) {
const expectedSignature = Cipher.sign(text)
return expectedSignature === signature;
}
static encrypt(text, encryptionKey, algorithm = "aes-256-ctr") {
const publicKey = Cipher.randomString();
let cipher = crypto.createCipheriv(
algorithm,
Buffer.from(password, "hex"),
Buffer.from(encryptionKey, "hex"),
Buffer.from(publicKey, "hex"),

@@ -41,17 +50,24 @@ );

return { publicKey, encrypted };
return { publicKey, encrypted, algorithm, signature: Cipher.sign(text) };
}
static decrypt(encryptedText, publicKey, password) {
static decrypt(encryptedText, publicKey, encryptionKey, signature, algorithm = "aes-256-ctr") {
encryptedText = Buffer.from(encryptedText, "hex");
let decipher = crypto.createDecipheriv(
algorithm,
Buffer.from(password, "hex"),
Buffer.from(encryptionKey, "hex"),
Buffer.from(publicKey, "hex")
);
let decrypted = decipher.update(encryptedText);
decrypted = Buffer.concat([decrypted, decipher.final()]);
decrypted = decrypted.toString();
return decrypted.toString();
if (!Cipher.verify(decrypted, signature)) {
throw new Error("Invalid signature")
}
return decrypted;
}
}
import { createSecretSchema } from "../models/Secret.js";
import Cipher from "./cipher.js";
import Cipher from "../sdk/cipher.js";
export default class Secrets {
constructor(config) {
this.config = config;
constructor(app) {
this.db = app.db;
}
get secrets() {
return this.config.get("secrets", []);
return this.db.get("secrets", []);
}
set secrets(value) {
this.config.set("secrets", value);
this.db.set("secrets", value);
}

@@ -21,3 +21,3 @@

async add(secret, password) {
async add(secret, encryptionKey) {
const { value, error } = createSecretSchema.validate(secret);

@@ -28,7 +28,5 @@ if (error) {

const { publicKey, encrypted } = Cipher.encrypt(value.value, password);
value.value = encrypted;
value.publicKey = publicKey;
const { encrypted, ...encryption } = Cipher.encrypt(value.value, encryptionKey);
this.secrets = [...this.secrets, value];
this.secrets = [...this.secrets, { ...value, ...encryption, value: encrypted }];
}

@@ -35,0 +33,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc