autho 0.0.3 → 1.0.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/app.js ADDED
@@ -0,0 +1,39 @@
1
+ import Secrets from 'sdk/secrets.js';
2
+ import DB from 'sdk/db.js';
3
+ import Cipher from 'sdk/cipher.js';
4
+ import config from 'shared/config.js';
5
+ import { ask } from './utils.js';
6
+
7
+ export default class App {
8
+ constructor(options = {}) {
9
+ this.encryptionKey = options.encryptionKey || config.masterPasswordHash;
10
+ this.dataFolder = options.dataFolder || config.dataFolder;
11
+ this.name = options.name || 'default';
12
+
13
+ this.db = new DB({
14
+ encryptionKey: this.encryptionKey,
15
+ dataFolder: this.dataFolder,
16
+ name: this.name,
17
+ });
18
+ this.secrets = new Secrets(this.db);
19
+ }
20
+
21
+ static async masterKey(masterPassword, masterPasswordHash) {
22
+ masterPassword = masterPassword || config.masterPassword;
23
+
24
+ if (masterPasswordHash) {
25
+ return masterPasswordHash;
26
+ } else if (!masterPassword) {
27
+ masterPassword = await ask({
28
+ name: 'masterPassword',
29
+ message: 'Password:',
30
+ type: 'password',
31
+ required: true,
32
+ });
33
+ }
34
+
35
+ masterPasswordHash = Cipher.hash(masterPassword);
36
+
37
+ return masterPasswordHash;
38
+ }
39
+ }
package/bin.js ADDED
@@ -0,0 +1,117 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { Command } from 'commander';
4
+ import Path from 'path';
5
+ import { prompt } from './utils.js';
6
+ import App from './app.js';
7
+ import Cipher from 'sdk/cipher.js';
8
+ import createSecret from './wizards/createSecret.js';
9
+ import getEncryptionKey from './wizards/getEncryptionKey.js';
10
+ import getSecret from './wizards/getSecret.js';
11
+ import OTP from 'sdk/otp.js';
12
+ import { Logger } from 'shared/logger.js';
13
+
14
+ const logger = new Logger();
15
+ const program = new Command();
16
+
17
+ const getAuthoAbsolutePath = (path) => {
18
+ if (Path.isAbsolute(path)) {
19
+ return Path.join(path, '.autho');
20
+ }
21
+
22
+ return Path.join(process.cwd(), path, '.autho');
23
+ };
24
+
25
+ program
26
+ .name('autho')
27
+ .description('Secrets manager')
28
+ .version('0.0.1')
29
+ .option('-p, --password <password>', 'Master password')
30
+ .option('-ph, --passwordHash <passwordHash>', 'Master password hash')
31
+ .option('-n, --name <name>', 'Collection name', 'default')
32
+ .option(
33
+ '-d, --dataFolder <folderPath>',
34
+ 'Folder path to store secrets db',
35
+ getAuthoAbsolutePath
36
+ )
37
+ .action(async (args) => {
38
+ try {
39
+ logger.debug('args:', args);
40
+ args.encryptionKey = await App.masterKey(
41
+ args.password,
42
+ args.passwordHash
43
+ );
44
+ const app = new App(args);
45
+ logger.debug(`Reading data from:`, app.db.path());
46
+
47
+ let choices = [
48
+ { value: 'create', name: 'Create new secret' },
49
+ { value: 'read', name: 'Read secret' },
50
+ { value: 'delete', name: 'Delete secret' },
51
+ ];
52
+
53
+ const { action } = await prompt({
54
+ name: 'action',
55
+ type: 'list',
56
+ choices,
57
+ required: true,
58
+ });
59
+
60
+ switch (action) {
61
+ case 'create':
62
+ await createSecret(app);
63
+ break;
64
+
65
+ case 'read':
66
+ {
67
+ const readSecret = await getSecret(app);
68
+ let encryptionKey = app.db.encryptionKey;
69
+ if (readSecret.protected) {
70
+ encryptionKey = await getEncryptionKey();
71
+ }
72
+
73
+ readSecret.value = Cipher.decrypt({ ...readSecret, encryptionKey });
74
+
75
+ switch (readSecret.type) {
76
+ case 'password':
77
+ console.log('Username:', readSecret.typeOptions.username);
78
+ console.log('Password:', readSecret.value);
79
+ break;
80
+ case 'note':
81
+ console.log('Note:', readSecret.value);
82
+ break;
83
+ case 'otp':
84
+ {
85
+ const otp = new OTP(readSecret);
86
+ console.log('OTP code:', otp.generate());
87
+ setTimeout(() => {
88
+ console.log('Expired');
89
+ process.exit(0);
90
+ }, 30000);
91
+ }
92
+
93
+ break;
94
+ }
95
+ }
96
+
97
+ break;
98
+ case 'delete':
99
+ {
100
+ const deleteSecret = await getSecret(app);
101
+ await app.secrets.remove(deleteSecret.id);
102
+ console.log('Removed');
103
+ process.exit(0);
104
+ }
105
+ break;
106
+ default:
107
+ console.log('Unknown action:', action);
108
+ process.exit(1);
109
+ }
110
+ } catch (error) {
111
+ logger.error('Something went wrong, Error: ', error.message);
112
+ console.log(error.stack);
113
+ process.exit(1);
114
+ }
115
+ });
116
+
117
+ program.parse();
package/package.json CHANGED
@@ -1,25 +1,19 @@
1
1
  {
2
2
  "name": "autho",
3
- "version": "0.0.3",
3
+ "version": "1.0.0",
4
+ "description": "",
4
5
  "main": "index.js",
5
6
  "type": "module",
6
- "bin": {
7
- "autho": "src/cli/bin.js"
8
- },
9
- "scripts": {
10
- "test": "echo \"Error: no test specified\" && exit 1"
11
- },
12
- "keywords": [],
13
- "author": "",
14
- "license": "ISC",
15
7
  "dependencies": {
16
8
  "commander": "^12.0.0",
17
- "conf": "^12.0.0",
18
9
  "inquirer": "^9.2.17",
19
- "inquirer-autocomplete-standalone": "^0.8.1",
20
- "joi": "^17.12.2",
21
- "otpauth": "^9.2.2"
10
+ "sdk": "1.0.0",
11
+ "shared": "1.0.0"
22
12
  },
23
- "devDependencies": {},
24
- "description": "Open Source Authentication and Password Management Tool"
25
- }
13
+ "keywords": [],
14
+ "author": "",
15
+ "license": "ISC",
16
+ "scripts": {
17
+ "test": "echo \"Error: no test specified\" && exit 1"
18
+ }
19
+ }
@@ -1,15 +1,15 @@
1
- import inquirer from "inquirer";
2
-
3
- export const prompt = inquirer.prompt;
4
-
5
- export const ask = async ({ name = "", message = "", type = "input" }) => {
6
- const answers = await inquirer.prompt([
7
- {
8
- name,
9
- message,
10
- type,
11
- },
12
- ]);
13
-
14
- return answers[name];
15
- };
1
+ import inquirer from 'inquirer';
2
+
3
+ export const prompt = inquirer.prompt;
4
+
5
+ export const ask = async ({ name = '', message = '', type = 'input' }) => {
6
+ const answers = await inquirer.prompt([
7
+ {
8
+ name,
9
+ message,
10
+ type,
11
+ },
12
+ ]);
13
+
14
+ return answers[name];
15
+ };
@@ -0,0 +1,124 @@
1
+ import { prompt } from '../utils.js';
2
+ import getEncryptionKey from './getEncryptionKey.js';
3
+
4
+ const wizard = async (app) => {
5
+ const secrets = app.secrets;
6
+ const info = await prompt([
7
+ {
8
+ name: 'name',
9
+ message: 'name:',
10
+ type: 'input',
11
+ required: true,
12
+ },
13
+ {
14
+ name: 'type',
15
+ message: 'type:',
16
+ type: 'list',
17
+ default: 'password',
18
+ choices: [
19
+ { name: 'Password', value: 'password' },
20
+ { name: 'OTP', value: 'otp' },
21
+ { name: 'Note', value: 'note' },
22
+ ],
23
+ required: true,
24
+ },
25
+ {
26
+ name: 'protected',
27
+ message: 'protected:',
28
+ type: 'confirm',
29
+ default: false,
30
+ required: true,
31
+ },
32
+ ]);
33
+
34
+ let newSecret = { typeOptions: {} };
35
+ let encryptionKey = app.db.encryptionKey;
36
+
37
+ if (info.protected) {
38
+ encryptionKey = await getEncryptionKey(true);
39
+ }
40
+
41
+ switch (info.type) {
42
+ case 'password':
43
+ {
44
+ const password = await prompt([
45
+ {
46
+ name: 'url',
47
+ message: 'url:',
48
+ type: 'input',
49
+ required: false,
50
+ },
51
+ {
52
+ name: 'username',
53
+ message: 'username:',
54
+ type: 'input',
55
+ required: true,
56
+ },
57
+ {
58
+ name: 'value',
59
+ message: 'password:',
60
+ type: 'password',
61
+ required: true,
62
+ },
63
+ ]);
64
+ newSecret = {
65
+ ...info,
66
+ value: password.value,
67
+ typeOptions: {
68
+ username: password.username,
69
+ url: password.url,
70
+ },
71
+ };
72
+ }
73
+
74
+ break;
75
+ case 'note':
76
+ {
77
+ const note = await prompt([
78
+ {
79
+ name: 'value',
80
+ message: 'note:',
81
+ type: 'password',
82
+ required: true,
83
+ },
84
+ ]);
85
+ newSecret = {
86
+ ...info,
87
+ value: note.value,
88
+ typeOptions: {},
89
+ };
90
+ }
91
+
92
+ break;
93
+ case 'otp':
94
+ {
95
+ const otp = await prompt([
96
+ {
97
+ name: 'username',
98
+ message: 'username:',
99
+ type: 'input',
100
+ required: true,
101
+ },
102
+ {
103
+ name: 'value',
104
+ message: 'value:',
105
+ type: 'password',
106
+ required: true,
107
+ },
108
+ ]);
109
+ newSecret = {
110
+ ...info,
111
+ value: otp.value,
112
+ typeOptions: {
113
+ username: otp.username,
114
+ },
115
+ };
116
+ }
117
+
118
+ break;
119
+ }
120
+
121
+ await secrets.add(newSecret, encryptionKey);
122
+ };
123
+
124
+ export default wizard;
@@ -0,0 +1,30 @@
1
+ import Cipher from 'sdk/cipher.js';
2
+ import { prompt } from '../utils.js';
3
+
4
+ const wizard = async (confirm = false) => {
5
+ const questions = [
6
+ {
7
+ name: 'password',
8
+ message: 'password:',
9
+ type: 'password',
10
+ required: true,
11
+ },
12
+ ];
13
+ if (confirm) {
14
+ questions.push({
15
+ name: 'confirmPassword',
16
+ message: 'confirm password:',
17
+ type: 'password',
18
+ required: true,
19
+ });
20
+ }
21
+ const input = await prompt(questions);
22
+
23
+ if (input.confirmPassword && input.password !== input.confirmPassword) {
24
+ throw new Error('Passwords do not match');
25
+ }
26
+
27
+ return Cipher.hash(input.password);
28
+ };
29
+
30
+ export default wizard;
@@ -0,0 +1,31 @@
1
+ import { prompt } from '../utils.js';
2
+
3
+ const wizard = async (app) => {
4
+ const existingSecrets = app.db.get('secrets', []);
5
+
6
+ if (existingSecrets.length === 0) {
7
+ throw new Error('No secrets found');
8
+ }
9
+
10
+ const choices = existingSecrets.map((secret) => ({
11
+ value: secret.id,
12
+ name: `${secret.name} (${secret.typeOptions.username || secret.id})`,
13
+ }));
14
+
15
+ const { id: secretId } = await prompt({
16
+ name: 'id',
17
+ message: 'Secrets:',
18
+ type: 'list',
19
+ choices,
20
+ required: true,
21
+ });
22
+ const secret = await app.secrets.get(secretId);
23
+
24
+ if (!secret) {
25
+ throw new Error('Secret not found');
26
+ }
27
+
28
+ return secret;
29
+ };
30
+
31
+ export default wizard;
package/Readme.md DELETED
@@ -1,63 +0,0 @@
1
- # Autho: Open Source Authentication and Password Management Tool
2
-
3
- Autho is an open-source, self-hosted alternative to services like Authy, providing One-Time Password (OTP) generation and password management functionalities. With Autho, users can securely manage their authentication tokens and passwords while maintaining full control over their data.
4
-
5
- ## Features
6
-
7
- - **OTP Generation**: Autho allows users to generate One-Time Passwords (OTPs) for two-factor authentication (2FA) using industry-standard algorithms.
8
-
9
- - **Password Management**: Autho provides a secure vault for users to store and manage their passwords, ensuring easy access and strong encryption.
10
-
11
- - **Self-Hosted**: Autho can be self-hosted, giving users complete control over their data and eliminating reliance on third-party services.
12
-
13
- - **Open Source**: Autho is open-source software, allowing users to inspect, modify, and contribute to its codebase, ensuring transparency and security.
14
-
15
- ## Installation
16
-
17
- To install Autho globally, use npm:
18
-
19
- ```sh
20
- npm install -g autho
21
- ```
22
-
23
- ## Usage
24
-
25
- After installing Autho, you can run the `autho` command in your terminal to access its functionalities:
26
-
27
- This will start the Autho CLI, where you can generate OTPs, manage passwords, and configure settings as needed.
28
-
29
- ## Getting Started
30
-
31
- 1. **Setting Up Autho**: After installation, run the `autho` command to set up Autho for the first time. Follow the on-screen instructions to configure your master password and other settings.
32
-
33
- 2. **Generating OTPs**: Use Autho to generate OTPs for your accounts by providing the associated account name or label. Autho will generate a time-based OTP using a secure algorithm.
34
-
35
- 3. **Managing Passwords**: Autho provides a secure vault for storing and managing your passwords. You can add, view, update, and delete passwords using the CLI interface.
36
-
37
- 4. **Self-Hosting**: If you prefer self-hosting, deploy Autho on your own server by following the instructions provided in the documentation.
38
-
39
- ## Security Considerations
40
-
41
- - **Encryption**: Autho employs strong encryption algorithms to protect user data, ensuring that passwords and OTPs are securely stored.
42
-
43
- - **Master Password**: Users are required to set a master password during setup, which is used to encrypt and decrypt their data. Choose a strong and unique master password to enhance security.
44
-
45
- - **Self-Hosting**: By self-hosting Autho, users maintain control over their data and reduce reliance on external services, minimizing the risk of data breaches.
46
-
47
- - **Regular Updates**: Keep Autho and its dependencies up to date to ensure that security vulnerabilities are addressed promptly.
48
-
49
- ## Contributing
50
-
51
- Autho is an open-source project, and contributions are welcome! Feel free to report issues, suggest features, or submit pull requests on the project's GitHub repository.
52
-
53
- ## License
54
-
55
- Autho is licensed under the [MIT License](link-to-license), allowing for unrestricted use, modification, and distribution.
56
-
57
- ## Support
58
-
59
- For support or inquiries, please reach out to the [official Autho community](link-to-community) for assistance.
60
-
61
- ## Acknowledgments
62
-
63
- Autho is built upon various open-source libraries and technologies. We extend our gratitude to the developers and contributors of these projects.
package/src/cli/bin.js DELETED
@@ -1,119 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { Command } from "commander";
4
- import chalk from "chalk";
5
- import { prompt, ask } from "./utils.js";
6
- import Config from "../sdk/config.js";
7
- import Cipher from "../sdk/cipher.js";
8
- import createSecret from "./wizards/createSecret.js";
9
- import Secrets from "../sdk/secrets.js";
10
- import OTP from "../sdk/otp.js";
11
-
12
- const program = new Command();
13
-
14
- const getSecret = async (config) => {
15
- const existingSecrets = config.get("secrets", []);
16
-
17
- if (existingSecrets.length === 0) {
18
- throw new Error("No secrets found");
19
- }
20
-
21
- const choices = existingSecrets.map((secret) => ({
22
- value: secret.id,
23
- name: `${secret.name} (${secret.typeOptions.username || secret.id})`,
24
- }));
25
-
26
- const { id: secretId } = await prompt({
27
- name: "id",
28
- message: "Secrets:",
29
- type: "list",
30
- choices,
31
- required: true,
32
- });
33
- const secrets = new Secrets(config);
34
- const secret = await secrets.get(secretId);
35
-
36
- if (!secret) {
37
- throw new Error("Secret not found");
38
- }
39
-
40
- return secret;
41
- };
42
-
43
- program
44
- .name("autho")
45
- .description("Secrets manager")
46
- .version("0.0.1")
47
- .option("-p, --password <password>", "Master password")
48
- .action(async (args) => {
49
- try {
50
- const masterPassword = args.password
51
- ? args.password
52
- : await ask({
53
- name: "masterPassword",
54
- message: "Password:",
55
- type: "password",
56
- required: true,
57
- });
58
- const masterPasswordHash = Cipher.hash(masterPassword);
59
- const config = new Config({ encryptionKey: masterPasswordHash });
60
-
61
- let choices = [
62
- { value: "create", name: "Create new secret" },
63
- { value: "read", name: "Read secret" },
64
- { value: "delete", name: "Delete secret" },
65
- ];
66
-
67
- const { action } = await prompt({
68
- name: "action",
69
- type: "list",
70
- choices,
71
- required: true,
72
- });
73
- switch (action) {
74
- case "create":
75
- await createSecret(config, masterPasswordHash);
76
- break;
77
-
78
- case "read":
79
- const readSecret = await getSecret(config);
80
- readSecret.value = Cipher.decrypt(readSecret.value, readSecret.publicKey, masterPasswordHash)
81
-
82
- switch (readSecret.type) {
83
- case "password":
84
- console.log("Username:", readSecret.typeOptions.username);
85
- console.log("Password:", readSecret.value);
86
- break;
87
- case "note":
88
- console.log("Note:", readSecret.value);
89
- break;
90
- case "otp":
91
- const otp = new OTP(readSecret);
92
- console.log("OTP code:", otp.generate());
93
- setTimeout(() => {
94
- console.log("Expired");
95
- process.exit(0);
96
- }, 30000);
97
- break;
98
- }
99
-
100
- break;
101
- case "delete":
102
- const deleteSecret = await getSecret(config);
103
- const secrets = new Secrets(config);
104
- await secrets.remove(deleteSecret.id)
105
- console.log("Removed");
106
- process.exit(0);
107
- break;
108
- }
109
- } catch (error) {
110
- console.log(
111
- chalk.redBright("Something went wrong, Error: "),
112
- error.message
113
- );
114
- console.log(error.stack);
115
- process.exit(1);
116
- }
117
- });
118
-
119
- program.parse();
@@ -1,97 +0,0 @@
1
- import { prompt } from "../utils.js";
2
- import Secrets from "../../sdk/secrets.js";
3
-
4
- const wizard = async (config, masterPasswordHash) => {
5
- const info = await prompt([
6
- {
7
- name: "name",
8
- message: "name:",
9
- type: "input",
10
- required: true,
11
- },
12
- {
13
- name: "type",
14
- message: "type:",
15
- type: "list",
16
- default: "password",
17
- choices: ["password", "otp", "note"],
18
- required: true,
19
- }
20
- ]);
21
-
22
- let newSecret = {};
23
-
24
- switch (info.type) {
25
- case "password":
26
- const password = await prompt([
27
- {
28
- name: "username",
29
- message: "username:",
30
- type: "input",
31
- required: true,
32
- },
33
- {
34
- name: "value",
35
- message: "password:",
36
- type: "password",
37
- required: true,
38
- },
39
- ]);
40
- newSecret = {
41
- name: info.name,
42
- type: info.type,
43
- value: password.value,
44
- typeOptions: {
45
- username: password.username,
46
- },
47
- };
48
- break;
49
- case "note":
50
- const note = await prompt([
51
- {
52
- name: "value",
53
- message: "note:",
54
- type: "password",
55
- required: true,
56
- },
57
- ]);
58
- newSecret = {
59
- name: info.name,
60
- type: info.type,
61
- value: note.value,
62
- typeOptions: {
63
-
64
- },
65
- };
66
- break;
67
- case "otp":
68
- const otp = await prompt([
69
- {
70
- name: "username",
71
- message: "username:",
72
- type: "input",
73
- required: true,
74
- },
75
- {
76
- name: "value",
77
- message: "value:",
78
- type: "password",
79
- required: true,
80
- },
81
- ]);
82
- newSecret = {
83
- name: info.name,
84
- type: info.type,
85
- value: otp.value,
86
- typeOptions: {
87
- username: otp.username,
88
- },
89
- };
90
- break;
91
- }
92
-
93
- const secrets = new Secrets(config);
94
- await secrets.add(newSecret, masterPasswordHash);
95
- };
96
-
97
- export default wizard;
@@ -1,12 +0,0 @@
1
- import Joi from 'joi';
2
- import Cipher from "../sdk/cipher.js";
3
-
4
- export const createSecretSchema = Joi.object({
5
- id: Joi.string().default(Cipher.randomString()),
6
- protected: Joi.boolean().default(false), // ask for password
7
- name: Joi.string().required(),
8
- type: Joi.string().required().valid('otp', 'password', 'note'),
9
- value: Joi.string().required(),
10
- typeOptions: Joi.object().default({}),
11
- createdAt: Joi.date().default(new Date()),
12
- })
package/src/sdk/cipher.js DELETED
@@ -1,54 +0,0 @@
1
- import crypto from "crypto";
2
-
3
- const algorithm = "aes-256-ctr";
4
- const IV_LENGTH = 16;
5
-
6
- export default class Cipher {
7
- constructor() { }
8
-
9
- static hash(text) {
10
- const hash = crypto.createHash("sha256");
11
- hash.update(text);
12
-
13
- return hash.digest("hex");
14
- }
15
-
16
- static random(size = IV_LENGTH) {
17
- const rnd = crypto.randomBytes(size);
18
-
19
- return rnd;
20
- }
21
-
22
- static randomString() {
23
- const rnd = Cipher.random().toString("hex");
24
-
25
- return rnd;
26
- }
27
-
28
- static encrypt(text, password) {
29
- const publicKey = Cipher.randomString();
30
- let cipher = crypto.createCipheriv(
31
- algorithm,
32
- Buffer.from(password, "hex"),
33
- Buffer.from(publicKey, "hex"),
34
- );
35
- let encrypted = cipher.update(text);
36
- encrypted = Buffer.concat([encrypted, cipher.final()]);
37
- encrypted = encrypted.toString("hex");
38
-
39
- return { publicKey, encrypted };
40
- }
41
-
42
- static decrypt(encryptedText, publicKey, password) {
43
- encryptedText = Buffer.from(encryptedText, "hex");
44
- let decipher = crypto.createDecipheriv(
45
- algorithm,
46
- Buffer.from(password, "hex"),
47
- Buffer.from(publicKey, "hex")
48
- );
49
- let decrypted = decipher.update(encryptedText);
50
- decrypted = Buffer.concat([decrypted, decipher.final()]);
51
-
52
- return decrypted.toString();
53
- }
54
- }
package/src/sdk/config.js DELETED
@@ -1,22 +0,0 @@
1
- import Conf from "conf";
2
-
3
- const { AUTHO_ENCRYPTION_KEY = "", AUTHO_NAME = 'default' } = process.env;
4
-
5
- export default class Config {
6
- constructor({
7
- encryptionKey = AUTHO_ENCRYPTION_KEY,
8
- configName = AUTHO_NAME
9
- }) {
10
- this.config = new Conf({ projectName: "autho", encryptionKey, configName });
11
- }
12
-
13
- get(key, defaultValue) {
14
- return this.config.get(key, defaultValue);
15
- }
16
-
17
- set(key, value) {
18
- this.config.set(key, value);
19
- }
20
-
21
- }
22
-
package/src/sdk/otp.js DELETED
@@ -1,25 +0,0 @@
1
- import * as OTPAuth from "otpauth";
2
-
3
- export default class OTP {
4
- constructor(secret) {
5
-
6
- const options = {
7
- issuer: "Autho",
8
- label: secret.name,
9
- algorithm: "SHA1",
10
- digits: 6,
11
- period: 30,
12
- secret: secret.value,
13
- };
14
-
15
- this.totp = new OTPAuth.TOTP(options);
16
- }
17
-
18
- generate() {
19
- return this.totp.generate();
20
- }
21
-
22
- validate(token, window = 1) {
23
- return this.totp.validate({ token, window });
24
- }
25
- }
@@ -1,41 +0,0 @@
1
- import { createSecretSchema } from "../models/Secret.js";
2
- import Cipher from "./cipher.js";
3
-
4
- export default class Secrets {
5
- constructor(config) {
6
- this.config = config;
7
- }
8
-
9
- get secrets() {
10
- return this.config.get("secrets", []);
11
- }
12
-
13
- set secrets(value) {
14
- this.config.set("secrets", value);
15
- }
16
-
17
- async get(id) {
18
- return this.secrets.find((secret) => secret.id == id);
19
- }
20
-
21
- async add(secret, password) {
22
- const { value, error } = createSecretSchema.validate(secret);
23
- if (error) {
24
- throw new Error(error);
25
- }
26
-
27
- const { publicKey, encrypted } = Cipher.encrypt(value.value, password);
28
- value.value = encrypted;
29
- value.publicKey = publicKey;
30
-
31
- this.secrets = [...this.secrets, value];
32
- }
33
-
34
- async remove(id) {
35
- this.secrets = this.secrets.filter((secret) => secret.id != id);
36
- }
37
-
38
- async clear() {
39
- this.secrets = [];
40
- }
41
- }