diff --git a/.gitignore b/.gitignore index 273aa69..7bec52d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,179 @@ coverage .idea .vscode + +# Local .terraform directories +**/.terraform/* +*.tf + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log +crash.*.log + +# Exclude all .tfvars files, which are likely to contain sensitive data, such as +# password, private keys, and other secrets. These should not be part of version +# control as they are data points which are potentially sensitive and subject +# to change depending on the environment. +*.tfvars +*.tfvars.json + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Ignore transient lock info files created by terraform apply +.terraform.tfstate.lock.info + +# Include override files you do wish to add to version control using negated pattern +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +# example: *tfplan* + +# Ignore CLI configuration files +.terraformrc +terraform.rc + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# vitepress build output +**/.vitepress/dist + +# vitepress cache directory +**/.vitepress/cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* \ No newline at end of file diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..015188d --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,5 @@ +# Permit CLI Community Code of Conduct +Permit CLI follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting +the maintainers via . diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..1102e45 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,81 @@ +# Contributing Guide + +We would love for you to contribute to this project and help make it even better than it is today! πŸ’Ž + +As a contributor, here are the guidelines we would like you to follow: + - [New Commands Guidelines](#new-command-guidelines) + - [Code of Conduct](https://github.com/permitio/permit-cli/blob/master/CODE_OF_CONDUCT.md) + - [Question or Problem?](#question) + - [Issues and Bugs](#issue) + - [Feature Requests](#feature) + + + +## New Command Guidelines + +We are excited to have you onboard as a contributor to Permit CLI! πŸŽ‰ + +For new commands, we have a few guidelines to ensure consistency and maintainability: + + +## Got a Question or Problem? +Come talk to us about Permit CLI, or authorization in general - we would love to hear from you ❀️ + +You can: +- Raise questions in our [GitHub discussions](https://github.com/permitio/permit-cli/discussions) +- Report issues and ask for features in [GitHub issues](https://github.com/permitio/permit-cli/issues) +- Follow us on [Twitter](https://twitter.com/permit_io) to get the latest Permit CLI updates +- Join our [Slack community](https://io.permit.io/slack) to chat about authorization, open-source, realtime communication, tech or anything else! We are super available on Slack ;) + +If you are using our project, please consider giving us a ⭐️ + +### Found a Bug? +If you find a bug in the source code, you can help us by [submitting an issue](https://github.com/permitio/permit-cli/issues) or even better, you can [submit a Pull Request](#submit-pr) with a fix. + +Before you submit an issue, please search the issue tracker; maybe an issue for your problem already exists, and the discussion might inform you of workarounds readily available. + +We want to fix all the issues as soon as possible, but before fixing a bug, we need to reproduce and confirm it. +In order to reproduce bugs, we require that you provide a full loom or other kind of terminal recording, so we can understand the issue and reproduce it. + +### Missing a Command / Feature? +You can *request* a new feature by [submitting an issue](https://github.com/permitio/permit-cli/issues) to our GitHub Repository. +Please provide as much detail and context as possible, along with examples or references to similar features, as this will help us understand your request better. + +We encourage you to contribute to Permit CLI by submitting a [Pull Request](#submit-pr) with your feature implementation and are happy to guide you through the process. + +We are always looking to improve Permit CLI and would love to hear your ideas! + +### Submitting a Pull Request (PR) + +Pull requests are welcome! πŸ™ + +Please follow these guidelines: + +1. **Create an Issue**: Open a [GitHub Issue](https://github.com/permitio/permit-cli/issues) for your feature or bug fix. +2. **Fork & Branch**: Fork this repository and create a new branch based on `main`. Name your branch descriptively (e.g., `fix/issue-123`, `feature/new-fetch-provider`). +3. **Write Tests**: If your changes affect functionality, include tests. +4. **Update Documentation**: Ensure any new features or configurations are documented. +5. **Check Quality**: Run all tests and linters: + ```bash + npm run lint + npm run test + ``` +6. **Submit PR**: Open a pull request, linking to the issue and explaining your changes clearly. + +We aim to review all PRs promptly. After you submit a PR, here’s what you can expect: +1. **Initial Review:** A maintainer will review your PR within a few days. If there are any issues, they will provide feedback. +2. **Feedback:** If changes are needed, please make the necessary updates and push them to your branch. The PR will be updated automatically. +3. **Approval:** Once your PR is approved, it will be merged into the main branch. +4. **Release:** Your changes will be included in the next release of Permit CLI. We will update the changelog and release notes accordingly. +5. **Announcement:** We will announce your contribution in our community channels and give you a shoutout! πŸŽ‰ + +### Contributor Checklist + +Before submitting your contribution, ensure the following: + +- [ ] Issue created and linked in the PR +- [ ] Branch created from `main` and appropriately named +- [ ] Tests written and passing +- [ ] Documentation updated (if applicable) +- [ ] Code formatted and linted +- [ ] Changes thoroughly explained in the PR description diff --git a/README.md b/README.md index c95bc35..b5a7ef5 100644 --- a/README.md +++ b/README.md @@ -1,49 +1,228 @@ -![permit CLI](https://github.com/user-attachments/assets/89dbb075-6d88-4fd7-8d19-9490177248fc) +# Permit CLI [![test](https://github.com/permitio/permit-cli/actions/workflows/node.js.yml/badge.svg)](https://github.com/vadimdemedes/pastel/actions/workflows/node.js.yml) [![Join our Slack!](https://img.shields.io/badge/Slack%20Community-4A154B?logo=slack&logoColor=white)](https://io.permit.io/cli-slack) ![Early Stage Development](https://img.shields.io/badge/⚠️_Early_Stage_Development-2B1400) ![Follow us on LinkedIn](https://img.shields.io/badge/LinkedIn-0077B5?style=for-the-badge&logo=linkedin&logoColor=white) -# Permit CLI +

+ + + + + + +

-A command line utility from Permit.io to work with everything IAM and Authorization. -A one-stop-shop to manage all your Authorization tools (OPA, OPAL, CEDAR, AVP, openFGA, ...) as well as the Permit Service. +The **Permit CLI** is an open-source command-line utility that empowers developers with everything related to [Fine-Grained Authorization (FGA)](https://www.permit.io/blog/what-is-fine-grained-authorization-fga) and Identity and Access Management (IAM). It is a one-stop solution for handling all your authorization needs, seamlessly integrating with tools like OPA, OPAL, CEDAR, AVP, OpenFGA, and the Permit.io service. -- Manage the Permit PDP and perform permissions checks directly from the CLI -- Manage the Permit API -- Interact with OPA (Open Policy Agent) -- Coming Soon: Interact with OPAL -- Coming Soon: Interact with Cedar-Agent -- Coming Soon: Interact with OpenFGA +> :bulb: Permit CLI is fully open-source and actively accepts [contributions of many cool features](https://github.com/permitio/permit-cli/issues). Leverage your open-source game by [contributing](https://github.com/permitio/permit-cli/issues) and giving it a :star: -### This tool is in early stages of development +## Installation +Permit CLI is now available only via the `npm` and requires a [Node.js installation](https://nodejs.org/en/download) to run +```console +npm install -g @permitio/cli +``` -Give this Repo a ⭐ to support and stay updated +## Usage +All the commands in the CLI are available via the `permit` command in the following convention: +```bash +$ permit [command] [options] +``` -Based on [Pastel](https://github.com/vadimdemedes/create-pastel-app) +For example: +```bash +$ permit pdp check --user user@permit.io --action list --resource transactions +``` -## Run for development +## Commands -- Checkout this repo -- run `npm install` -- run `npx tsx ./source/cli.tsx` +- [`login`](#login) - login to your Permit.io account +- `logout` - logout from Permit.io +- `pdp` - a collection of commands to work with Permit's Policy Decision Point (PDP) + - `run` - print a docker command to run your Permit PDP + - `check` - perform an authorization check against the PDP +- `env` - a collection of commands to manage Permit policy environments + - `copy` - copy a Permit environment with its policies to another environment + - `member` - add and assign roles to members in Permit + - `select` - select a different active Permit.io environment +- `opa` - a collection of commands for better OPA experience + - `policy` - print the available policies of an active OPA instance +- `gitops create github` - configure Permit environment to use [GitOps flow](https://docs.permit.io/integrations/gitops/overview/) + +--- + +### `login` +After installing the CLI, you must authenticate to run commands against your Permit.io account. + +The `login` command will take you to the browser to perform user authentication and then let you choose the workspace, project, and environment to for future command runs. + +#### Options +- `key ` (Optional) - store a Permit API key in your workstation keychain instead of running browser authentication +- `workspace ` (Optional) - predefined workspace key to skip the workspace selection step + +#### Example +```bash +$ permit login +``` + +--- + +### `logout` + +This command will log you out from your Permit account and remove the stored key from your workspace. + +#### Example +```bash +permit logout +``` + +--- + +### `pdp` +This collection of commands aims to improve the experience of working with Policy Decision Points (PDP) such as the Permit PDP or Open Policy Agent. + +### `pdp run` +Use this command to get a `docker run` command configured with your PDP details from the account you logged in with + +#### Options +- `opa ` (Optional) - expose the OPA instance running in the PDP + +#### Example +```bash +$ permit pdp run --opa 8181 +``` + +### `pdp check` + +Use this command to perform an authorization check against the PDP. The command will take the user, action, and resource (and some other enrichment arguments) as options and return the decision. + +#### Options +- `user ` - the user id to check the authorization for +- `action ` - the action to check the authorization for +- `resource ` - the resource to check the authorization for +- `tenant ` (Optional) - the tenant to check the authorization for (default: `default`) +- `pdpurl ` (Optional) - the PDP URL to check the authorization against (default: `http://localhost:7676`) +- `userAttributes` (Optional) - additional user attributes to enrich the authorization check in the format `key1=value1,key2=value2` +- `resourceAttributes` (Optional) - additional resource attributes to enrich the authorization check in the format `key1=value1,key2=value2` + +#### Example +```bash +$ permit pdp check --user eventHandler --action update --resource Widget:dashboard-1-widget +``` + +--- + +### `env` +This collection of commands will enable you to automate SDLC operations for Fine-Grained Authorization with Permit.io + +### `env copy` +Developers and CI pipelines can use this command to enable secure blue-green deployment in the Software Development Lifecycle (SDLC). The command will get the source and destination environments as options and copy the policies from one to another. This will let you run your tests again in a non-production environment and merge it safely into production after the tests. -### Writing Tests +#### Options +- `key ` (Required) - a Permit API key in project level or higher to authenticate the operation +- `from ` (Optional) - the source environment to copy the policies from (will prompt if not provided) +- `to ` (Optional) - the destination environment to copy the policies to (will prompt if not provided) +- `name ` (Optional) - the name of a new environment to copy the policies to (will prompt if not provided) +- `description ` (Optional) - the description of a new environment to copy the policies to (will prompt if not provided) +- `conflictStrategy ` (Optional) - the strategy to handle conflicts when copying policies (default: `fail`) -Permit CLI uses [`vitest`](https://vitest.dev/) as a tool for writing tests. It also uses [`ink-testing-library`](https://github.com/vadimdemedes/ink-testing-library) to render the `Ink` components. +#### Example +```bash +$ permit env copy --key permit_key_.......... --from staging --to production --conflictStrategy overwrite +``` + +### `env member` +This command will assign members to environment with the roles you specify. This is useful for managing the access control of your team members in the Permit.io environment. + +This command can run in the CI after creating a new environment for development or testing to assign the roles to the team members who need to access the environment. + +#### Options +- `key ` (Required) - a Permit API key in project level or higher to authenticate the operation +- `environment ` (Optional) - the environment to assign the roles to (will prompt if not provided) +- `project ` (Optional) - the project to assign the roles to (will prompt if not provided) +- `email ` (Optional) - the email of the member to assign the roles to (will prompt if not provided) +- `role ` (Optional) - the role to assign to the member (will prompt if not provided) -- run `npx vitest` for testing -- run `npx vitest --coverage` for code coverage. +#### Example +```bash +$ permit env member --key permit_key_.......... --environment staging --project my-project --email gabriel@permit.io --role Owner +``` + +### `env select` +This command will let you select a different active Permit.io environment. This is useful when you have multiple environments in your account and you want to switch between them without logging out and logging in again. -## CLI +#### Options +- `key ` (Optional) - a Permit API key in project level or higher to authenticate the operation. If not provided, the command will reauthenticate you in the browser. +#### Example +```bash +$ permit env select --key permit_key_......... ``` -$ permit-cli --help - Usage - $ permit-cli +--- + +### `opa` +This collection of commands aims to create new experiences for developers working with Open Policy Agent (OPA) in their projects. + +### `opa policy` +This command will print the available policies of an active OPA instance. This is useful when you want to see the policies in your OPA instance without fetching them from the OPA server. - Examples - $ permit-cli pdp check -u filip@permit.io -a create -r task - Checking user="filip@permit.io" action=create resource=task at tenant=default - ALLOWED +#### Options +- `serverUrl ` (Optional) - the URL of the OPA server to fetch the policies from (default: `http://localhost:8181`) +- `apiKey ` (Optional) - the API key to authenticate the operation - $ permit-cli api-key permit_key_.......... - Key saved to './permit.key' +#### Example +```bash +$ permit opa policy --serverUrl http://localhost:8181 --apiKey permit_key_.......... ``` + +--- + +### `gitops create github` +This command will configure your Permit environment to use the GitOps flow with GitHub. This is useful when you want to manage your policies in your own Git repository and extend them with custom policy code. + +#### Options +- `key ` (Optional) - a Permit API key to authenticate the operation. If not provided, the command will take the one you logged in with. +- `inactive ` (Optional) - set the environment to inactive after configuring GitOps (default: `false`) + + +## Development +Permit CLI is based on Pastel, a library for building CLI applications using React-like syntax. The project is written in TypeScript and uses `tsc` to run the CLI commands in development. + +### Setup Development Environment +- Checkout this repo +- Run `npm install` +- Run `npm run dev` +- Use the CLI with the following convention `node ./dist/cli.js command [options]` + +### Add New Commands +To add a new command, you need to create a new file in the `src/commands` directory with the command name. The project is using the Pastel library to create the CLI commands. You can find the documentation [here](https://github.com/vadimdemedes/pastel?tab=readme-ov-file#commands) + +For a detailed command contribution guide, please refer to the [CONTRIBUTING.md](CONTRIBUTING.md) file. + +### Write Tests +Permit CLI enforce UT coverage level of >90% for the code in main. + +The CLI uses [`vitest`](https://vitest.dev/) as its test framework. It also uses [`ink-testing-library`](https://github.com/vadimdemedes/ink-testing-library) to render the `Ink` components. + +- run `npm run tests` for testing and coverage + +## Community + + We would love to chat with you about Pernut CKU. [Join our Slack community](https://io.permit.io/cli-slack) to chat about fine-grained authorization, open-source, realtime communication, tech, or anything else! + +You can raise questions and ask for features to be added to the road-map in our [**Github discussions**](https://github.com/permitio/permit-cli/discussions), report issues in [**Github issues**](https://github.com/permitio/permit-cli/issues) + +If you like our project, please consider giving us a ⭐️ + +## Contributing to Permit CLI + +We would love for you to contribute to this project and help make it even better than it is today! πŸ’Ž + +As a contributor, here are the guidelines we would like you to follow: + - [Code of Conduct](CODE_OF_CONDUCT.md) + - [Question or Problem?](CONTRIBUTING.md#question) + - [Issues and Bugs](CONTRIBUTING.md#issue) + - [Feature Requests](CONTRIBUTING.md#feature) + - [New Commands Guidelines](CONTRIBUTING.md#new-command-guidelines) + +## There's more! + +- Check out [OPAL](https://github.com/permitio/OPAL) - the best way to manage Open Policy Agent (OPA), Cedar, and OpenFGA in scale. +- Check out [Cedar-Agent](https://github.com/permitio/cedar-agent), the easiest way to deploy & run AWS Cedar. diff --git a/package-lock.json b/package-lock.json index 66fae01..b77be75 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@permitio/cli", - "version": "0.0.0", + "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@permitio/cli", - "version": "0.0.0", + "version": "0.1.0", "license": "MIT", "dependencies": { "clipboardy": "^4.0.0", diff --git a/package.json b/package.json index 97e3db7..1785fec 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,18 @@ { "name": "@permitio/cli", - "version": "0.0.0", + "version": "0.1.0", "license": "MIT", "bin": { "permit": "dist/cli.js" }, "type": "module", "engines": { - "node": ">=16" + "node": ">=22" }, "scripts": { "build": "tsc", "dev": " NODE_NO_WARNINGS=1 tsc --watch", - "lint": "eslint \"source/**/*.{js,ts,tsx}\"", + "lint": "prettier --check ./source && eslint \"source/**/*.{js,ts,tsx}\"", "lint:fix": "eslint \"source/**/*.{js,ts,tsx}\" --fix", "test": "prettier --check ./source && vitest run --coverage", "simple-check": "npx tsx ./source/cli.tsx pdp check -u filip@permit.io -a create -r task" diff --git a/source/cli.tsx b/source/cli.tsx index 8d0bddd..ae763fa 100644 --- a/source/cli.tsx +++ b/source/cli.tsx @@ -3,6 +3,7 @@ import Pastel from 'pastel'; const app = new Pastel({ importMeta: import.meta, + name: 'permit', }); await app.run(); diff --git a/source/commands/apiKey.tsx b/source/commands/apiKey.tsx deleted file mode 100644 index c71484c..0000000 --- a/source/commands/apiKey.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import { Text, Newline } from 'ink'; -import zod from 'zod'; -import { keyAccountOption } from '../options/keychain.js'; -import { KEYSTORE_PERMIT_SERVICE_NAME } from '../config.js'; - -import * as keytar from 'keytar'; - -export const args = zod.tuple([ - zod - .enum(['save', 'read', 'validate']) - .describe('Which action to take with the api-key and/or key-store'), - zod.string().describe('The key to save or validate').default('Undefined'), -]); - -export const options = zod.object({ - keyAccount: keyAccountOption, -}); - -type Props = { - args: zod.infer; - options: zod.infer; -}; - -export default function ApiKey({ args, options }: Props) { - const action: string = args[0]; - const key: string = args[1]; - const isValid = key.length >= 97 && key.startsWith('permit_key_'); - - const [readKey, setReadKey] = useState(''); - - useEffect(() => { - if (action === 'read') { - keytar - .getPassword(KEYSTORE_PERMIT_SERVICE_NAME, options.keyAccount) - .then(value => setReadKey(value || '')) - .catch(reason => - setReadKey( - `-- Failed to read key- reason ${reason instanceof Error ? reason.message : String(reason)}`, - ), - ); - } - }, [action, options.keyAccount]); - - if (isValid && action === 'save') { - keytar.setPassword(KEYSTORE_PERMIT_SERVICE_NAME, options.keyAccount, key); - return ( - - Key saved to secure key store. - - ); - } else if (isValid && action === 'validate') { - return ( - - Key is valid. - - ); - } else if (action === 'read') { - return ( - - {readKey} - - ); - } - return ( - - Key is not valid. - - Provided key: {key} - - ); -} diff --git a/source/commands/gitops/create/github.tsx b/source/commands/gitops/create/github.tsx index b7804b7..58e4098 100644 --- a/source/commands/gitops/create/github.tsx +++ b/source/commands/gitops/create/github.tsx @@ -4,6 +4,9 @@ import { option } from 'pastel'; import { AuthProvider } from '../../../components/AuthProvider.js'; import GitHubComponent from '../../../components/gitops/GitHubComponent.js'; +export const description = + 'Connect a GitHub repository to a permit Environment'; + export const options = zod.object({ key: zod .string() diff --git a/source/commands/index.tsx b/source/commands/index.tsx index bda0a61..ff535b0 100644 --- a/source/commands/index.tsx +++ b/source/commands/index.tsx @@ -1,14 +1,14 @@ import React from 'react'; import Gradient from 'ink-gradient'; -import BigText from 'ink-big-text'; import { Text } from 'ink'; export default function Index() { return ( <> - - - + + Permit CLI is a + developer swiss army knife for fine-grained authorization + Run this command with --help for more information ); diff --git a/source/lib/auth.ts b/source/lib/auth.ts index ea96fe3..6540c7b 100644 --- a/source/lib/auth.ts +++ b/source/lib/auth.ts @@ -10,7 +10,7 @@ import { URL, URLSearchParams } from 'url'; import { setTimeout } from 'timers'; import { Buffer } from 'buffer'; -const { setPassword, getPassword, deletePassword } = pkg; +const { setPassword, getPassword, deletePassword } = pkg.default; export enum TokenType { APIToken = 'APIToken', diff --git a/test.tsx b/test.tsx deleted file mode 100644 index 4b91bb6..0000000 --- a/test.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import React from 'react'; -import chalk from 'chalk'; -import { test } from 'node:test'; -import { render } from 'ink-testing-library'; -import assert from 'node:assert'; -import Check from './source/commands/pdp/check.js'; - -const API_KEY = process.env.API_KEY; - -test('check', t => { - t.test('Should Display Checking indicator', () => { - const { lastFrame } = render( - , - ); - const res = lastFrame(); - assert.equal( - res, - 'Checking user="filip@permit.io" action=create resource=task at tenant=default\nβ ‹', - ); - }); -}); diff --git a/tests/OPAPolicy.test.tsx b/tests/OPAPolicy.test.tsx index 7b3427c..20ac38f 100644 --- a/tests/OPAPolicy.test.tsx +++ b/tests/OPAPolicy.test.tsx @@ -3,14 +3,18 @@ import { describe, it, expect, vi } from 'vitest'; import { render } from 'ink-testing-library'; import Policy from '../source/commands/opa/policy'; import delay from 'delay'; -import * as keytar from "keytar" +import * as keytar from 'keytar'; global.fetch = vi.fn(); const enter = '\r'; -vi.mock("keytar",()=>({ - getPassword: vi.fn(), - setPassword: vi.fn(), - deletePassword:vi.fn() -})) + +vi.mock('keytar', () => { + const keytar = { + setPassword: vi.fn(), + getPassword: vi.fn(), // Mocked return value + deletePassword: vi.fn(), + }; + return { ...keytar, default: keytar }; +}); describe('OPA Policy Command', () => { it('should render the policy command', async () => { diff --git a/tests/PDPCheck.test.tsx b/tests/PDPCheck.test.tsx index cfa1d99..05b6ab1 100644 --- a/tests/PDPCheck.test.tsx +++ b/tests/PDPCheck.test.tsx @@ -6,9 +6,12 @@ import Check from '../source/commands/pdp/check'; import * as keytar from 'keytar'; global.fetch = vi.fn(); -vi.mock('keytar', () => ({ - getPassword: vi.fn().mockResolvedValue('permit_key_a'.concat('a').repeat(97)), -})); +vi.mock('keytar', () => { + const keytar = { + getPassword: vi.fn().mockResolvedValue('permit_key_a'.concat('a').repeat(97)), + }; + return { ...keytar, default: keytar }; +}); describe('PDP Check Component', () => { afterEach(() => { // Clear mock calls after each test diff --git a/tests/PDPRun.test.tsx b/tests/PDPRun.test.tsx index 2723c8d..3ccf2c5 100644 --- a/tests/PDPRun.test.tsx +++ b/tests/PDPRun.test.tsx @@ -1,19 +1,24 @@ import React from 'react'; -import {vi, describe, expect, it } from 'vitest'; +import { vi, describe, expect, it } from 'vitest'; import { render } from 'ink-testing-library'; import Run from '../source/commands/pdp/run'; -import * as keytar from "keytar" +import * as keytar from 'keytar'; -vi.mock("keytar",()=>({ - getPassword: vi.fn(), - setPassword: vi.fn(), - deletePassword:vi.fn() -})) +vi.mock('keytar', () => { + const keytar = { + setPassword: vi.fn(), + getPassword: vi.fn(), // Mocked return value + deletePassword: vi.fn(), + }; + return { ...keytar, default: keytar }; +}); describe('PDP Run', () => { it('Should render the PDP Run command', () => { - const {getPassword} = keytar; - (getPassword as any).mockResolvedValueOnce("permit_key_".concat("a".repeat(97))) + const { getPassword } = keytar; + (getPassword as any).mockResolvedValueOnce( + 'permit_key_'.concat('a'.repeat(97)), + ); const { lastFrame } = render(); expect(lastFrame()?.toString()).toMatch(/Loading Token/); }); diff --git a/tests/apiKey.test.tsx b/tests/apiKey.test.tsx deleted file mode 100644 index ea87b1d..0000000 --- a/tests/apiKey.test.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import React from 'react'; -import { render } from 'ink-testing-library'; -import ApiKey from '../source/commands/apiKey'; -import { vi, describe, it, expect } from 'vitest'; -import delay from 'delay'; -import * as keytar from 'keytar'; - -vi.mock('keytar', () => ({ - setPassword: vi.fn(), - getPassword: vi.fn(), - deletePassword: vi.fn(), -})); - -describe('ApiKey', () => { - it('Should save the key', () => { - const permitKey = 'permit_key_'.concat('a'.repeat(97)); - const { lastFrame } = render( - , - ); - expect(lastFrame()).toMatch(/Key saved to secure key store./); - }); - it('Should validate the key', () => { - const { getPassword } = keytar; - const permitKey = 'permit_key_'.concat('a'.repeat(97)); - (getPassword as any).mockResolvedValueOnce(permitKey); - const { lastFrame } = render( - , - ); - expect(lastFrame()).toMatch(/Key is valid./); - }); - it('Should read the key', async () => { - const permitKey = 'permit_key_'.concat('a'.repeat(97)); - const { getPassword } = keytar; - (getPassword as any).mockResolvedValueOnce(permitKey); - const { lastFrame } = render( - , - ); - await delay(100); - expect(lastFrame()).toMatch(/permit_key_aaaaaaa/); - }); - it('Invalid Key', async () => { - const permitKey = 'permit_key'.concat('a'.repeat(97)); - const { lastFrame } = render( - , - ); - await delay(50); - expect(lastFrame()).toMatch(/Key is not valid./); - }); -}); diff --git a/tests/lib/auth.test.ts b/tests/lib/auth.test.ts index 947320d..9bc12fe 100644 --- a/tests/lib/auth.test.ts +++ b/tests/lib/auth.test.ts @@ -28,11 +28,14 @@ vi.mock('node:crypto', () => ({ })); // Correct mock for 'keytar' using named exports -vi.mock('keytar', () => ({ - setPassword: vi.fn(), - getPassword: vi.fn(), // Mocked return value - deletePassword: vi.fn(), -})); +vi.mock('keytar', () => { + const keytar = { + setPassword: vi.fn(), + getPassword: vi.fn(), // Mocked return value + deletePassword: vi.fn(), + }; + return { ...keytar, default: keytar }; +}); describe('Token Type', () => { it('Should return correct token type', async () => { diff --git a/tests/login.test.tsx b/tests/login.test.tsx index 635cc9f..5862b10 100644 --- a/tests/login.test.tsx +++ b/tests/login.test.tsx @@ -3,13 +3,16 @@ import { vi, expect, it, describe } from 'vitest'; import { render } from 'ink-testing-library'; import Login from '../source/commands/login'; import delay from 'delay'; -import * as keytar from "keytar" +import * as keytar from 'keytar'; -vi.mock("keytar",()=>({ - getPassword: vi.fn(), - setPassword: vi.fn(), - deletePassword:vi.fn() -})) +vi.mock('keytar', () => { + const keytar = { + setPassword: vi.fn(), + getPassword: vi.fn(), // Mocked return value + deletePassword: vi.fn(), + }; + return { ...keytar, default: keytar }; +}); describe('Login Component', () => { it('Should render the login component', async () => { diff --git a/tests/logout.test.tsx b/tests/logout.test.tsx index 5b14f22..abed868 100644 --- a/tests/logout.test.tsx +++ b/tests/logout.test.tsx @@ -5,12 +5,14 @@ import Logout from '../source/commands/logout'; import delay from 'delay'; import * as keytar from 'keytar'; -vi.mock('keytar', () => ({ - setPassword: vi.fn(), - getPassword: vi.fn(), - deletePassword: vi.fn(), -})); - +vi.mock('keytar', () => { + const keytar = { + setPassword: vi.fn(), + getPassword: vi.fn(), // Mocked return value + deletePassword: vi.fn(), + }; + return { ...keytar, default: keytar }; +}); describe('Logout', () => { beforeEach(() => { vi.spyOn(process, 'exit').mockImplementation(code => {