From 2bb4ec2bd8263e9f53e26e663c3b631fbcd4051c Mon Sep 17 00:00:00 2001 From: Sagar Date: Fri, 5 Jul 2024 14:24:44 +0530 Subject: [PATCH 1/6] =?UTF-8?q?=F0=9F=9A=80=20feat=20:=20Add=20configurati?= =?UTF-8?q?on=20option?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added a configuration option for the CLI to allow users to customize and tweak certain behaviors. --- README.md | 30 +++++++--- package-lock.json | 55 +++++++++++++++++-- package.json | 1 + src/cli.js | 6 ++ src/commands/commit/prompt.js | 4 +- src/commands/config/index.js | 15 +++++ src/commands/config/prompt.js | 23 ++++++++ src/constants/config.js | 1 + src/constants/flag.js | 1 + .../configurationVault/getConfiguration.js | 38 ++++++++++++- src/utils/configurationVault/index.js | 6 +- 11 files changed, 158 insertions(+), 22 deletions(-) create mode 100644 src/commands/config/index.js create mode 100644 src/commands/config/prompt.js diff --git a/README.md b/README.md index 138e3b2..9481e60 100644 --- a/README.md +++ b/README.md @@ -28,13 +28,16 @@ gitemo --help Usage $ gitemo [option] [command] Options - --commit, -c Interactively commit using the prompts - --list, -l List all the available git emojis - --version, -v Print gitemo-cli installed version + --commit, -c Interactively commit using the prompts + --aiCommit, --aic Use ai for generating commits + --config, --g To change configuration + --list, -l List all the available git emojis + --version, -v Print gitemo-cli installed version Commands - commit Interactively commit using the prompts - list List all the available gitmojis - version Print gitemo-cli installed version + commit Interactively commit using the prompts + list List all the available gitmojis + version Print gitemo-cli installed version + config Change configuration Examples $ gitemo -c ``` @@ -46,7 +49,7 @@ You can use the commit functionality to develop your commits message based on pr Start the interactive commit client, to auto generate your commit based on your prompts. ```bash -gitemo -c +gitemo --c ``` ##### Options @@ -67,7 +70,7 @@ gitemo -c --title="Commit" --message="Message" --scope="Scope" Pretty print all the available git emojis. ```bash -gitemo -l +gitemo --l ``` ### Version @@ -75,5 +78,14 @@ gitemo -l List down the current version of the cli ```bash -gitemo -v +gitemo --v ``` +### Config + +You can use the default configs or customize your own configurations. + +Some of the default settings are: + +```bash +gitemo --g +``` \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 5ecfa22..85f52bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "gitemo-cli", - "version": "2.2.2", + "version": "2.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "gitemo-cli", - "version": "2.2.2", + "version": "2.3.0", "license": "MIT", "dependencies": { "@changesets/cli": "^2.27.6", @@ -22,6 +22,7 @@ "meow": "^13.2.0", "nanoid": "^5.0.7", "ora": "^8.0.1", + "path-exists": "^5.0.0", "update-notifier": "^7.0.0" }, "bin": { @@ -4000,6 +4001,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/eslint/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -4213,6 +4223,15 @@ "path-exists": "^4.0.0" } }, + "node_modules/find-babel-config/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -4225,6 +4244,14 @@ "node": ">=8" } }, + "node_modules/find-up/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, "node_modules/find-yarn-workspace-root2": { "version": "1.2.16", "resolved": "https://registry.npmjs.org/find-yarn-workspace-root2/-/find-yarn-workspace-root2-1.2.16.tgz", @@ -5687,11 +5714,11 @@ } }, "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, "node_modules/path-is-absolute": { @@ -5923,6 +5950,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/preferred-pm/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -6857,6 +6892,14 @@ "node": ">=8.15" } }, + "node_modules/which-pm/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, "node_modules/widest-line": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", diff --git a/package.json b/package.json index aa4711f..7cd8e56 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "meow": "^13.2.0", "nanoid": "^5.0.7", "ora": "^8.0.1", + "path-exists": "^5.0.0", "update-notifier": "^7.0.0" }, "devDependencies": { diff --git a/src/cli.js b/src/cli.js index b18b257..0be0920 100755 --- a/src/cli.js +++ b/src/cli.js @@ -9,6 +9,8 @@ const cli = meow( $ gitemo [option] [command] Options --${FLAGS.COMMIT}, -c Interactively commit using the prompts + --${FLAGS.HELP}, -h Display help message + --${FLAGS.CONFIG}, -g Configure gitemo-cli --${FLAGS.AIC}, -aic Interactively commit using the ai --${FLAGS.LIST}, -l List all the available git emojis --${FLAGS.VERSION}, -v Print gitemo-cli installed version @@ -16,6 +18,7 @@ const cli = meow( commit Interactively commit using the prompts list List all the available gitmojis version Print gitemo-cli installed version + config Configure gitemo-cli login Login to your account Examples $ gitemo -c @@ -27,6 +30,7 @@ const cli = meow( [FLAGS.AIC]: { type: 'boolean', shortFlag: 'aic' }, [FLAGS.HELP]: { type: 'boolean', shortFlag: 'h' }, [FLAGS.LIST]: { type: 'boolean', shortFlag: 'l' }, + [FLAGS.CONFIG]: { type: 'boolean' , shortFlag: 'g'}, [FLAGS.VERSION]: { type: 'boolean', shortFlag: 'v' }, [FLAGS.LOGIN]: { type: 'boolean'}, }, @@ -40,6 +44,8 @@ export const options = { (await import('./commands/ai-commit/index.js')).default(options), [FLAGS.LIST]: async () => (await import('./commands/list/index.js')).default(), + [FLAGS.CONFIG]: async () => + (await import('./commands/config/index.js')).default(), [FLAGS.LOGIN]: async () => (await import('./commands/login/index.js')).default(), } diff --git a/src/commands/commit/prompt.js b/src/commands/commit/prompt.js index 53d4185..391d99f 100644 --- a/src/commands/commit/prompt.js +++ b/src/commands/commit/prompt.js @@ -30,7 +30,9 @@ export default async (gitmojis, options) => { const length = (title || input).length.toString().padStart(2, '0'); return `[${length}/${TITLE_MAX_LENGTH_COUNT}]: ${ - configurationVault.getCapitalizeTitle ? capitaliseTitle(input) : input + configurationVault.getCapitalizeTitle() + ? capitaliseTitle(input) + : input }`; }, ...(title ? { default: title } : {}), diff --git a/src/commands/config/index.js b/src/commands/config/index.js new file mode 100644 index 0000000..bb4110a --- /dev/null +++ b/src/commands/config/index.js @@ -0,0 +1,15 @@ +import inquirer from 'inquirer'; + +import configurationPrompts from './prompt.js'; +import { CONFIG } from '@constants/config.js'; +import configurationVault from '@utils/configurationVault/index.js'; + +const config = () => { + inquirer.prompt(configurationPrompts()).then((answers) => { + configurationVault.setAutoAdd(answers[CONFIG.AUTO_ADD]); + configurationVault.setMessagePrompt(answers[CONFIG.MESSAGE_PROMPT]); + configurationVault.setCapitalizeTitle(answers[CONFIG.CAPITALIZE_TITLE]); + }); +}; + +export default config; diff --git a/src/commands/config/prompt.js b/src/commands/config/prompt.js new file mode 100644 index 0000000..c12a3ab --- /dev/null +++ b/src/commands/config/prompt.js @@ -0,0 +1,23 @@ +import configurationVault from '@utils/configurationVault'; +import { CONFIG } from '@constants/config.js'; + +export default () => [ + { + name: CONFIG.AUTO_ADD, + message: 'Enable automatic "git add ."', + type: 'confirm', + default: configurationVault.getAutoAdd(), + }, + { + name: CONFIG.MESSAGE_PROMPT, + message: 'Enable message prompt', + type: 'confirm', + default: configurationVault.getMessagePrompt(), + }, + { + name: CONFIG.CAPITALIZE_TITLE, + message: 'Capitalize title', + type: 'confirm', + default: configurationVault.getCapitalizeTitle(), + }, +]; diff --git a/src/constants/config.js b/src/constants/config.js index e7d2a75..e452ce5 100644 --- a/src/constants/config.js +++ b/src/constants/config.js @@ -1,4 +1,5 @@ export const CONFIG = { + AUTO_ADD: 'autoAdd', MESSAGE_PROMPT: 'messagePrompt', CAPITALIZE_TITLE: 'capitalizeTitle', }; diff --git a/src/constants/flag.js b/src/constants/flag.js index 8f44a02..047e973 100644 --- a/src/constants/flag.js +++ b/src/constants/flag.js @@ -5,6 +5,7 @@ const FLAGS = Object.freeze({ VERSION: 'version', AIC: 'aiCommit', LOGIN: 'login', + CONFIG: 'config', }); export default FLAGS; diff --git a/src/utils/configurationVault/getConfiguration.js b/src/utils/configurationVault/getConfiguration.js index fd7edac..53a2159 100644 --- a/src/utils/configurationVault/getConfiguration.js +++ b/src/utils/configurationVault/getConfiguration.js @@ -1,6 +1,8 @@ import Conf from 'conf'; - -import { CONFIG } from '../../constants/config.js'; +import { cwd } from 'process'; +import { readFileSync } from 'fs'; +import { pathExistsSync } from 'path-exists'; +import { CONFIG } from '@constants/config.js'; const DEFAULT_CONFIGURATION = { [CONFIG.MESSAGE_PROMPT]: true, @@ -26,10 +28,40 @@ const LOCAL_CONFIGURATION = new Conf({ }, }); +const getFile = (path) => { + try { + return JSON.parse(readFileSync(path)); + } catch (error) { + return; + } +}; + const getConfiguration = () => { + const loadConfig = () => { + const packageJson = `${cwd()}/package.json`; + const configurationFile = `${cwd()}/.gitemorc.json`; + + if (pathExistsSync(packageJson) && getFile(packageJson)?.gitmoji) { + return getFile(packageJson)?.gitmoji; + } + + if (pathExistsSync(configurationFile) && getFile(configurationFile)) { + return getFile(configurationFile); + } + + return LOCAL_CONFIGURATION.store; + }; + return { get: (key) => { - return LOCAL_CONFIGURATION.get(key) ?? DEFAULT_CONFIGURATION[key]; //fallback to default if null/undefined for local + const resolvedConfiguration = loadConfig(); + const configuration = + typeof resolvedConfiguration === 'object' && + Object.keys(resolvedConfiguration).length + ? resolvedConfiguration + : DEFAULT_CONFIGURATION; + + return configuration[key] ?? DEFAULT_CONFIGURATION[key]; //fallback to default if null/undefined for configuration[key] }, set: (key, value) => { LOCAL_CONFIGURATION.set(key, value); diff --git a/src/utils/configurationVault/index.js b/src/utils/configurationVault/index.js index efa497e..a7d5198 100644 --- a/src/utils/configurationVault/index.js +++ b/src/utils/configurationVault/index.js @@ -8,14 +8,14 @@ const getMessagePrompt = () => config.get(CONFIG.MESSAGE_PROMPT); const getAutoAdd = () => config.get(CONFIG.AUTO_ADD); const setAutoAdd = (autoAdd) => { - config.set(CONFIG.AUTO_ADD, autoAdd); + return config.set(CONFIG.AUTO_ADD, autoAdd); }; const setCapitalizeTitle = (capitalizeTitle) => { - config.set(CONFIG.CAPITALIZE_TITLE, capitalizeTitle); + return config.set(CONFIG.CAPITALIZE_TITLE, capitalizeTitle); }; const setMessagePrompt = (messagePrompt) => { - config.set(CONFIG.MESSAGE_PROMPT, messagePrompt); + return config.set(CONFIG.MESSAGE_PROMPT, messagePrompt); }; export default { From 79e7c600b9f2c8ad1212c34c104f12dc33c8f8d4 Mon Sep 17 00:00:00 2001 From: Sagar Date: Fri, 5 Jul 2024 14:28:11 +0530 Subject: [PATCH 2/6] =?UTF-8?q?=F0=9F=93=A6=20package=20:=20Updated=20pack?= =?UTF-8?q?ages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/six-beds-switch.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/six-beds-switch.md diff --git a/.changeset/six-beds-switch.md b/.changeset/six-beds-switch.md new file mode 100644 index 0000000..c84db69 --- /dev/null +++ b/.changeset/six-beds-switch.md @@ -0,0 +1,5 @@ +--- +'gitemo-cli': minor +--- + +configuration options for the cli From d0d5c7cf9051352c35a1099b0ad69fec31882e41 Mon Sep 17 00:00:00 2001 From: Sagar Date: Fri, 5 Jul 2024 20:19:56 +0530 Subject: [PATCH 3/6] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20chore=20:=20Added=20in?= =?UTF-8?q?-memory=20rate=20limiting"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added a custom rate limiting to prevent excessive traffic request to ai keys --- package-lock.json | 6 ++++ package.json | 1 + src/commands/ai-commit/aiResponse.js | 4 +-- src/commands/ai-commit/index.js | 24 ++++++++++++++- src/commands/commit/withClient/index.js | 2 ++ src/config/rateLimit.js | 30 +++++++++++++++++++ src/constants/config.js | 2 ++ .../configurationVault/getConfiguration.js | 10 +++++++ src/utils/configurationVault/index.js | 14 +++++++++ 9 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 src/config/rateLimit.js diff --git a/package-lock.json b/package-lock.json index 85f52bd..aaa7fe6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "nanoid": "^5.0.7", "ora": "^8.0.1", "path-exists": "^5.0.0", + "rate-limiter-flexible": "^5.0.3", "update-notifier": "^7.0.0" }, "bin": { @@ -6058,6 +6059,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/rate-limiter-flexible": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/rate-limiter-flexible/-/rate-limiter-flexible-5.0.3.tgz", + "integrity": "sha512-lWx2y8NBVlTOLPyqs+6y7dxfEpT6YFqKy3MzWbCy95sTTOhOuxufP2QvRyOHpfXpB9OUJPbVLybw3z3AVAS5fA==" + }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", diff --git a/package.json b/package.json index 7cd8e56..f16f38d 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "nanoid": "^5.0.7", "ora": "^8.0.1", "path-exists": "^5.0.0", + "rate-limiter-flexible": "^5.0.3", "update-notifier": "^7.0.0" }, "devDependencies": { diff --git a/src/commands/ai-commit/aiResponse.js b/src/commands/ai-commit/aiResponse.js index 3eff027..184703d 100644 --- a/src/commands/ai-commit/aiResponse.js +++ b/src/commands/ai-commit/aiResponse.js @@ -22,8 +22,8 @@ export async function aiResponse({ gitmoji, ai_prompt }) { if type is'feat' and about is 'I have done task like pretifying code and code correction' - it should strictly return like this format which is a json object with all proper space, formatting and intial letter of title capital: - { gitmoji: '🚀 feat', title: 'Pretifying code and code correction', message: 'The code changes prettifies code and also does correction' } + it should strictly return like this format which is a json object with all proper space, formatting and intial letter of title small: + { gitmoji: '🚀 feat', title: 'commit title', message: 'Whatever changes has been madein this commit' } Make sure there is a space between emoji and type like this gitmoji: '⚙️ chore' diff --git a/src/commands/ai-commit/index.js b/src/commands/ai-commit/index.js index 46fb10b..365a525 100644 --- a/src/commands/ai-commit/index.js +++ b/src/commands/ai-commit/index.js @@ -3,11 +3,25 @@ import prompt from './prompt'; import withClient from '@commands/commit/withClient'; import { gitmojis } from '@utils/emoji.js'; import inquirer from 'inquirer'; +import { isRateLimited } from '../../config/rateLimit.js'; +import chalk from 'chalk'; +import configurationVault from '@utils/configurationVault/index.js'; +import { capitaliseTitle } from '@utils/capitaliseTitle.js'; const promptAndCommit = (options) => { prompt(gitmojis, options).then((questions) => { inquirer.prompt(questions).then(async (answers) => { - aiResponse(answers).then((transformedAnswers) => { + aiResponse(answers).then((aiAnswers) => { + const transformedAnswers = { + ...aiAnswers, + title: configurationVault.getCapitalizeTitle() + ? capitaliseTitle(aiAnswers.title) + : aiAnswers.title, + message: configurationVault.getMessagePrompt() + ? aiAnswers.message + : '', + }; + console.log(transformedAnswers); return withClient(transformedAnswers); }); }); @@ -15,6 +29,14 @@ const promptAndCommit = (options) => { }; const aiCommit = (options) => { + if (isRateLimited()) { + console.log( + chalk.red( + 'Error: You have exceeded the maximum number of AI commits per hour. Please try again later.' + ) + ); + return; + } return promptAndCommit(options); }; diff --git a/src/commands/commit/withClient/index.js b/src/commands/commit/withClient/index.js index dc3e2b9..1d0db5d 100644 --- a/src/commands/commit/withClient/index.js +++ b/src/commands/commit/withClient/index.js @@ -1,6 +1,7 @@ import { execa } from 'execa'; import chalk from 'chalk'; import configurationVault from '@utils/configurationVault/index.js'; +import { incrementCount } from '../../../config/rateLimit.js'; const withClient = async (answers) => { try { @@ -26,6 +27,7 @@ const withClient = async (answers) => { stdio: 'inherit', } ); + incrementCount(); } catch (error) { console.error( chalk.red( diff --git a/src/config/rateLimit.js b/src/config/rateLimit.js new file mode 100644 index 0000000..e993b01 --- /dev/null +++ b/src/config/rateLimit.js @@ -0,0 +1,30 @@ +// rateLimiter.js +import configurationVault from '@utils/configurationVault/index.js'; + +const LIMIT = 4; +const TIME_WINDOW = 60 * 60 * 1000; // 1 hour in milliseconds + +export const isRateLimited = () => { + const currentTime = Date.now().toString(); + const count = configurationVault.getRateLimitCount(); + const timestamp = configurationVault.getRateLimitTimestamp(); + + const timeDiff = (currentTime - timestamp) / TIME_WINDOW; + if (timeDiff >= 1) { + // Reset the count if the time window has passed + configurationVault.setRateLimitCount(1); + configurationVault.setRateLimitTimestamp(Date.now().toString()); + return false; + } + + if (count > LIMIT) { + return true; + } + + return false; +}; + +export const incrementCount = () => { + const count = configurationVault.getRateLimitCount(); + configurationVault.setRateLimitCount(count + 1); +}; diff --git a/src/constants/config.js b/src/constants/config.js index e452ce5..782c2d9 100644 --- a/src/constants/config.js +++ b/src/constants/config.js @@ -2,4 +2,6 @@ export const CONFIG = { AUTO_ADD: 'autoAdd', MESSAGE_PROMPT: 'messagePrompt', CAPITALIZE_TITLE: 'capitalizeTitle', + RATE_LIMIT_COUNT: 'rateLimitCount', + RATE_LIMIT_TIMESTAMP: 'rateLimitTimestamp', }; diff --git a/src/utils/configurationVault/getConfiguration.js b/src/utils/configurationVault/getConfiguration.js index 53a2159..d93d365 100644 --- a/src/utils/configurationVault/getConfiguration.js +++ b/src/utils/configurationVault/getConfiguration.js @@ -8,6 +8,8 @@ const DEFAULT_CONFIGURATION = { [CONFIG.MESSAGE_PROMPT]: true, [CONFIG.CAPITALIZE_TITLE]: true, [CONFIG.AUTO_ADD]: false, + [CONFIG.RATE_LIMIT_COUNT]: 0, + [CONFIG.RATE_LIMIT_TIMESTAMP]: Date.now().toString(), }; const LOCAL_CONFIGURATION = new Conf({ @@ -25,6 +27,14 @@ const LOCAL_CONFIGURATION = new Conf({ type: 'boolean', default: DEFAULT_CONFIGURATION[CONFIG.AUTO_ADD], }, + [CONFIG.RATE_LIMIT_COUNT]: { + type: 'number', + default: DEFAULT_CONFIGURATION[CONFIG.RATE_LIMIT_COUNT], + }, + [CONFIG.RATE_LIMIT_TIMESTAMP]: { + type: 'string', + default: DEFAULT_CONFIGURATION[CONFIG.RATE_LIMIT_TIMESTAMP], + }, }, }); diff --git a/src/utils/configurationVault/index.js b/src/utils/configurationVault/index.js index a7d5198..476f490 100644 --- a/src/utils/configurationVault/index.js +++ b/src/utils/configurationVault/index.js @@ -6,6 +6,8 @@ const config = getConfiguration(); const getCapitalizeTitle = () => config.get(CONFIG.CAPITALIZE_TITLE); const getMessagePrompt = () => config.get(CONFIG.MESSAGE_PROMPT); const getAutoAdd = () => config.get(CONFIG.AUTO_ADD); +const getRateLimitCount = () => config.get(CONFIG.RATE_LIMIT_COUNT); +const getRateLimitTimestamp = () => config.get(CONFIG.RATE_LIMIT_TIMESTAMP); const setAutoAdd = (autoAdd) => { return config.set(CONFIG.AUTO_ADD, autoAdd); @@ -18,11 +20,23 @@ const setMessagePrompt = (messagePrompt) => { return config.set(CONFIG.MESSAGE_PROMPT, messagePrompt); }; +const setRateLimitCount = (rateLimitCount) => { + return config.set(CONFIG.RATE_LIMIT_COUNT, rateLimitCount); +}; + +const setRateLimitTimestamp = (rateLimitTimestamp) => { + return config.set(CONFIG.RATE_LIMIT_TIMESTAMP, rateLimitTimestamp); +}; + export default { getCapitalizeTitle, getMessagePrompt, getAutoAdd, + getRateLimitCount, + getRateLimitTimestamp, setAutoAdd, setCapitalizeTitle, setMessagePrompt, + setRateLimitCount, + setRateLimitTimestamp, }; From 71c3d08ffa4424f1d0e15f22c513fd0c28c47dd1 Mon Sep 17 00:00:00 2001 From: Sagar Date: Fri, 5 Jul 2024 20:21:22 +0530 Subject: [PATCH 4/6] =?UTF-8?q?=F0=9F=93=A6=20package=20:=20Updated=20pack?= =?UTF-8?q?ages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/kind-zoos-yell.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/kind-zoos-yell.md diff --git a/.changeset/kind-zoos-yell.md b/.changeset/kind-zoos-yell.md new file mode 100644 index 0000000..0f95aeb --- /dev/null +++ b/.changeset/kind-zoos-yell.md @@ -0,0 +1,5 @@ +--- +'gitemo-cli': patch +--- + +rate-limiting to prevent api keys From e2bca8d9661dc9bed2be22498558841174d4d404 Mon Sep 17 00:00:00 2001 From: Sagar Date: Fri, 5 Jul 2024 23:42:42 +0530 Subject: [PATCH 5/6] =?UTF-8?q?=F0=9F=9A=80=20feat=20:=20Authenticated=20c?= =?UTF-8?q?ommands?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commands are executed via clerk token --- package-lock.json | 398 +++++++++++++++++- package.json | 1 + src/commands/login/index.js | 17 +- src/constants/config.js | 1 + .../configurationVault/getConfiguration.js | 5 + src/utils/configurationVault/index.js | 7 + src/utils/findGitemoCommands.js | 46 +- src/utils/hash.js | 19 + src/utils/requireLogin.js | 18 +- 9 files changed, 470 insertions(+), 42 deletions(-) create mode 100644 src/utils/hash.js diff --git a/package-lock.json b/package-lock.json index aaa7fe6..98248fa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@changesets/cli": "^2.27.6", "@google/generative-ai": "^0.14.0", "async-listen": "^3.0.1", + "bcrypt": "^5.1.1", "chalk": "^5.3.0", "conf": "^13.0.1", "dotenv": "^16.4.5", @@ -2596,6 +2597,58 @@ "node": ">=6 <7 || >=8" } }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@nicolo-ribaudo/chokidar-2": { "version": "2.1.8-no-fsevents.3", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz", @@ -2725,6 +2778,11 @@ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==" }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, "node_modules/acorn": { "version": "8.12.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", @@ -2746,6 +2804,17 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/ajv": { "version": "8.16.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", @@ -2854,6 +2923,24 @@ "node": ">= 8" } }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "deprecated": "This package is no longer supported.", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -3012,8 +3099,7 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/base64-js": { "version": "1.5.1", @@ -3034,6 +3120,19 @@ } ] }, + "node_modules/bcrypt": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz", + "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==", + "hasInstallScript": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.11", + "node-addon-api": "^5.0.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/better-path-resolve": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/better-path-resolve/-/better-path-resolve-1.0.0.tgz", @@ -3177,7 +3276,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3366,6 +3464,14 @@ "fsevents": "~2.3.2" } }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, "node_modules/ci-info": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", @@ -3448,6 +3554,14 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "bin": { + "color-support": "bin.js" + } + }, "node_modules/commander": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", @@ -3460,8 +3574,7 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/conf": { "version": "13.0.1", @@ -3542,6 +3655,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -3617,7 +3735,6 @@ "version": "4.3.5", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -3688,6 +3805,11 @@ "node": ">=10" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + }, "node_modules/detect-indent": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", @@ -3696,6 +3818,14 @@ "node": ">=8" } }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "engines": { + "node": ">=8" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -4302,6 +4432,33 @@ "node": ">=6 <7 || >=8" } }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs-minipass/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/fs-readdir-recursive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", @@ -4311,8 +4468,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "2.3.3", @@ -4345,6 +4501,31 @@ "node": ">=10" } }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "deprecated": "This package is no longer supported.", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gauge/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -4385,7 +4566,6 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4513,6 +4693,11 @@ "node": ">=4" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -4542,6 +4727,18 @@ "node": ">=10.19.0" } }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/human-id": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/human-id/-/human-id-1.0.2.tgz", @@ -4654,7 +4851,6 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -5360,7 +5556,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -5385,6 +5580,45 @@ "node": ">=8" } }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/mri": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", @@ -5396,8 +5630,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/mute-stream": { "version": "1.0.0", @@ -5430,12 +5663,50 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/node-releases": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -5482,11 +5753,30 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "deprecated": "This package is no longer supported.", + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "dependencies": { "wrappy": "1" } @@ -5726,7 +6016,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -6313,6 +6602,21 @@ "node": ">=0.10.0" } }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/run-async": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", @@ -6409,6 +6713,11 @@ "node": ">=10" } }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -6623,6 +6932,35 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/term-size": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", @@ -6671,6 +7009,11 @@ "node": ">=8.0" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "node_modules/tslib": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", @@ -6867,6 +7210,20 @@ "defaults": "^1.0.3" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/when-exit": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/when-exit/-/when-exit-2.1.3.tgz", @@ -6906,6 +7263,14 @@ "node": ">=8" } }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, "node_modules/widest-line": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", @@ -6991,8 +7356,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/write-file-atomic": { "version": "3.0.3", diff --git a/package.json b/package.json index f16f38d..3d3f74c 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "@changesets/cli": "^2.27.6", "@google/generative-ai": "^0.14.0", "async-listen": "^3.0.1", + "bcrypt": "^5.1.1", "chalk": "^5.3.0", "conf": "^13.0.1", "dotenv": "^16.4.5", diff --git a/src/commands/login/index.js b/src/commands/login/index.js index 06e649d..7f0a926 100644 --- a/src/commands/login/index.js +++ b/src/commands/login/index.js @@ -1,6 +1,6 @@ import http from 'http'; import chalk from 'chalk'; -import { writeFileSync } from 'fs'; +import { writeFileSync, writeFile } from 'fs'; import ora from 'ora'; import url from 'url'; import { customAlphabet } from 'nanoid'; @@ -8,6 +8,8 @@ import { listen } from 'async-listen'; import dotenv from 'dotenv'; import { spawn } from 'child_process'; import path from 'path'; +import { hashPassword } from '@utils/hash.js'; +import configurationVault from '@utils/configurationVault/index.js'; dotenv.config(); import os from 'os'; @@ -25,7 +27,16 @@ async function writeToConfigFile(data) { try { const homeDir = os.homedir(); const filePath = path.join(homeDir, FILENAME); - writeFileSync(filePath, JSON.stringify(data)); + + configurationVault.setUserKey(data.key); + await hashPassword(data.key) + .then((hashedPassword) => { + data.key = hashedPassword; + return data; + }) + .then((data) => { + writeFileSync(filePath, JSON.stringify(data)); + }); } catch (error) { console.error('Error writing to local config file', error); } @@ -95,7 +106,7 @@ export default async function login() { spinner.start(); const authData = await authPromise; spinner.stop(); - writeToConfigFile(authData); + await writeToConfigFile(authData); console.log( `Authentication successful: wrote key to config file. To view it, type 'cat ~/${FILENAME}'.\n` ); diff --git a/src/constants/config.js b/src/constants/config.js index 782c2d9..dd5cb90 100644 --- a/src/constants/config.js +++ b/src/constants/config.js @@ -4,4 +4,5 @@ export const CONFIG = { CAPITALIZE_TITLE: 'capitalizeTitle', RATE_LIMIT_COUNT: 'rateLimitCount', RATE_LIMIT_TIMESTAMP: 'rateLimitTimestamp', + USER_KEY: 'userKey', }; diff --git a/src/utils/configurationVault/getConfiguration.js b/src/utils/configurationVault/getConfiguration.js index d93d365..abc3251 100644 --- a/src/utils/configurationVault/getConfiguration.js +++ b/src/utils/configurationVault/getConfiguration.js @@ -10,6 +10,7 @@ const DEFAULT_CONFIGURATION = { [CONFIG.AUTO_ADD]: false, [CONFIG.RATE_LIMIT_COUNT]: 0, [CONFIG.RATE_LIMIT_TIMESTAMP]: Date.now().toString(), + [CONFIG.USER_KEY]: '', }; const LOCAL_CONFIGURATION = new Conf({ @@ -35,6 +36,10 @@ const LOCAL_CONFIGURATION = new Conf({ type: 'string', default: DEFAULT_CONFIGURATION[CONFIG.RATE_LIMIT_TIMESTAMP], }, + [CONFIG.USER_KEY]: { + type: 'string', + default: DEFAULT_CONFIGURATION[CONFIG.USER_KEY], + }, }, }); diff --git a/src/utils/configurationVault/index.js b/src/utils/configurationVault/index.js index 476f490..e990ab0 100644 --- a/src/utils/configurationVault/index.js +++ b/src/utils/configurationVault/index.js @@ -8,6 +8,7 @@ const getMessagePrompt = () => config.get(CONFIG.MESSAGE_PROMPT); const getAutoAdd = () => config.get(CONFIG.AUTO_ADD); const getRateLimitCount = () => config.get(CONFIG.RATE_LIMIT_COUNT); const getRateLimitTimestamp = () => config.get(CONFIG.RATE_LIMIT_TIMESTAMP); +const getUserKey = () => config.get(CONFIG.USER_KEY); const setAutoAdd = (autoAdd) => { return config.set(CONFIG.AUTO_ADD, autoAdd); @@ -28,15 +29,21 @@ const setRateLimitTimestamp = (rateLimitTimestamp) => { return config.set(CONFIG.RATE_LIMIT_TIMESTAMP, rateLimitTimestamp); }; +const setUserKey = (userKey) => { + return config.set(CONFIG.USER_KEY, userKey); +}; + export default { getCapitalizeTitle, getMessagePrompt, getAutoAdd, getRateLimitCount, getRateLimitTimestamp, + getUserKey, setAutoAdd, setCapitalizeTitle, setMessagePrompt, setRateLimitCount, setRateLimitTimestamp, + setUserKey, }; diff --git a/src/utils/findGitemoCommands.js b/src/utils/findGitemoCommands.js index 8ef2eec..9cf76d9 100644 --- a/src/utils/findGitemoCommands.js +++ b/src/utils/findGitemoCommands.js @@ -37,34 +37,40 @@ const getOptionsForCommand = (command, flags, input, type) => { return null; }; -const findGitemoCommand = (cli, options) => { +const findGitemoCommand = async (cli, options) => { const { command, type } = determineCommand(cli.flags, cli.input, options); - var key = requireLogin(command); + if (!command || !isSupportedCommand(command, options)) { + return cli.showHelp(); + } - if (command === FLAGS.LOGIN) { - if (key && key !== 1) { - console.log(chalk.bold.green(`\n\nYou are already logged in\n\n`)); - return; + requireLogin(command).then((key) => { + if (command === FLAGS.LOGIN) { + if (key && key !== 1) { + console.log( + chalk.bold.green(`\n\nYou are already logged in already\n\n`) + ); + return; + } } - } - if (!key || key === undefined) { - return; - } + if (!key || key === undefined) { + return; + } - if (!command || !isSupportedCommand(command, options)) { - return cli.showHelp(); - } + if (!command || !isSupportedCommand(command, options)) { + return cli.showHelp(); + } - const commandOptions = getOptionsForCommand( - command, - cli.flags, - cli.input, - type - ); + const commandOptions = getOptionsForCommand( + command, + cli.flags, + cli.input, + type + ); - return options[command] ? options[command](commandOptions) : cli.showHelp(); + return options[command] ? options[command](commandOptions) : cli.showHelp(); + }); }; export default findGitemoCommand; diff --git a/src/utils/hash.js b/src/utils/hash.js new file mode 100644 index 0000000..67cdc2e --- /dev/null +++ b/src/utils/hash.js @@ -0,0 +1,19 @@ +import bcrypt from 'bcrypt'; +const saltRounds = 10; + +export async function hashPassword(password) { + try { + return await bcrypt.hash(password, saltRounds); + } catch (error) { + throw new Error('Error hashing password: ' + error.message); + } +} + +export async function comparePassword(password, hashedPassword) { + try { + const match = await bcrypt.compare(password, hashedPassword); + return match; + } catch (error) { + throw new Error('Error comparing password: ' + error.message); + } +} diff --git a/src/utils/requireLogin.js b/src/utils/requireLogin.js index ad0300f..c259c74 100644 --- a/src/utils/requireLogin.js +++ b/src/utils/requireLogin.js @@ -3,16 +3,30 @@ import path from 'path'; import chalk from 'chalk'; import { readFileSync } from 'fs'; import dotenv from 'dotenv'; +import configurationVault from '@utils/configurationVault/index.js'; +import { comparePassword } from '@utils/hash.js'; dotenv.config(); -function requireLogin(command) { +const verifyUser = async (key) => { + const keyFromConfig = configurationVault.getUserKey(); + return await comparePassword(keyFromConfig, key).then((match) => { + if (!match) { + console.log(chalk.red(`Key has been changed\n\n`)); + return undefined; + } + return key; + }); +}; + +async function requireLogin(command) { try { const FILENAME = process.env.KEY_FILENAME; const homeDir = os.homedir(); const filePath = path.join(homeDir, FILENAME); const fileData = readFileSync(filePath, 'utf8'); const { key } = JSON.parse(fileData); - return key; + + return await verifyUser(key); } catch (error) { if (command === 'login') { return 1; From e18ef7cde09043b6ea0de24cf70666a51cd27dfa Mon Sep 17 00:00:00 2001 From: Sagar Date: Fri, 5 Jul 2024 23:43:35 +0530 Subject: [PATCH 6/6] =?UTF-8?q?=F0=9F=93=A6=20package=20:=20Updated=20pack?= =?UTF-8?q?ages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/tasty-snakes-join.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/tasty-snakes-join.md diff --git a/.changeset/tasty-snakes-join.md b/.changeset/tasty-snakes-join.md new file mode 100644 index 0000000..57e49eb --- /dev/null +++ b/.changeset/tasty-snakes-join.md @@ -0,0 +1,5 @@ +--- +'gitemo-cli': patch +--- + +authenticated commands using clerk token