Skip to content

Commit

Permalink
Merge pull request #60 from 35C4n0r/auth-provider-signup-re
Browse files Browse the repository at this point in the history
feat: add auth provider and signup
  • Loading branch information
gemanor authored Jan 22, 2025
2 parents 75ecc0e + f536732 commit 7c74de6
Show file tree
Hide file tree
Showing 40 changed files with 2,473 additions and 1,069 deletions.
129 changes: 129 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,132 @@ Before submitting your contribution, ensure the following:
- [ ] Documentation updated (if applicable)
- [ ] Code formatted and linted
- [ ] Changes thoroughly explained in the PR description



# AuthProvider Component Documentation

## **Overview**
The `AuthProvider` component is a React context provider designed to manage authentication, authorization, and API key handling for CLI-based workflows. It handles multiple flows, such as login, API key validation, token management, and organization/project/environment selection.

This component is the backbone of authentication for the CLI app. It ensures a smooth and secure authentication process by abstracting away the complexities of API key creation, validation, and token management.

---

## **What It Does**
### **Authentication Flows**
1. **Token Validation:**
- It attempts to load an existing authentication token using `loadAuthToken()`.
- If a token exists but has the wrong scope or is invalid, the user is redirected to reauthenticate.
2. **API Key Validation:**
- The component validates the provided `--key` (if supplied) against the required scope (e.g., organization, project, or environment).
- If invalid, it throws an error.
3. **Token Creation and Management:**
- If no key is provided or no stored key is found, we take the user through appropriate selection flow, and get a token of that scope.
- If while fetching the token, no valid key with name (`CLI_API_Key`) is found, the component handles the creation of a new API key (`CLI_API_Key`), ensuring it is scoped appropriately.
### **User Prompts**
- Prompts users to select an organization or project if required and dynamically handles state transitions based on the user's input.
### **Error Handling**
- Any error in the authentication flow (e.g., invalid token, API failure) is captured and displayed to the user. If an error is critical, the CLI exits with a non-zero status.
---
## **Key Features**
1. **`--key<-->permitKey` Functionality:**
- Users can pass a `--key` flag to provide an API key directly to the `permitKey` prop of `AuthProvider`. The component validates the key and uses it if valid + has a valid scope.
- If not passed, the component tries to load a previously stored token or guides the user through a scope based selection and key creation flow.
2. **Scope Handling:**
- The `scope` prop defines the required level of access (e.g., `organization`, `project`, or `environment`).
- Based on the scope, the component dynamically fetches or validates the key.
3. **Key Creation:**
- If on an organization/project scope level, we fetch the key, and we don't find a `CLI_API_Key`, we create one for the user and notify them that it's a secure token and not to edit it in any way.
4. **Error and Loading Indicators:**
- Displays appropriate messages during loading or error states to ensure users are informed about what’s happening.
---
## **How to Use It**
- Any component that is wrapped with AuthProvider can use `useAuth()` to access:
```tsx
type AuthContextType = {
authToken: string;
loading: boolean;
error?: string | null;
scope: ApiKeyScope;
};
```
1. **Wrap Your Application:**
- The `AuthProvider` should wrap the root of your CLI app. It ensures that authentication is initialized before the app runs.
```tsx
import { AuthProvider } from './context/AuthProvider';
const App = () => (
<AuthProvider scope="project"> // The scope here is optional and defaults to environment
<YourCLICommands />
</AuthProvider>
);
```
2. **Access Authentication Context:**
- Use the `useAuth` hook to access the `authToken` and other authentication states in your components.
```tsx
import { useAuth } from './context/AuthProvider';
const MyCommand = () => {
const { authToken, loading, error, scope } = useAuth();
if (loading) {
return <Text>Loading...</Text>;
}
if (error) {
return <Text>Error: {error}</Text>;
}
return <Text>Authenticated with token: {authToken}</Text>;
};
```
3. **Customizing Behavior:**
- Pass the `permit_key` or `scope` prop to customize the authentication flow.
- Example:
```tsx
<AuthProvider permit_key="my-key" scope="organization">
<YourCLICommands />
</AuthProvider>
```
---
## **What Happens Inside**
### **Step-by-Step Breakdown**
1. **Initialization:**
- Checks if a `permit_key` or token is already available.
- Validates the token against the required `scope`.
2. **Token Validation:**
- If invalid or missing, it guides the user through organization/project/environment selection.
3. **API Key Handling:**
- Searches for an existing `CLI_API_Key` scoped to the organization/project.
- Creates one if it doesn’t exist and retrieves its secret.
4. **State Transition:**
- Handles transitions between `loading`, `login`, `organization`, `project`, and `done` states based on user input and validation results.
5. **Error Handling:**
- Displays errors and exits the process if authentication fails irrecoverably.
---
2 changes: 2 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import reactHooksPlugin from 'eslint-plugin-react-hooks';
import prettierPlugin from 'eslint-plugin-prettier';
import js from '@eslint/js';
import prettierConfig from 'eslint-config-prettier';
import globals from "globals";

const compat = new FlatCompat({
baseDirectory: import.meta.url,
Expand All @@ -31,6 +32,7 @@ export default [
},
},
globals: {
...globals.browser,
Headers: 'readonly',
RequestInit: 'readonly',
fetch: 'readonly',
Expand Down
11 changes: 10 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"dist"
],
"dependencies": {
"@scaleway/random-name": "^5.1.1",
"clipboardy": "^4.0.0",
"delay": "^6.0.0",
"fuse.js": "^7.0.0",
Expand Down
Loading

0 comments on commit 7c74de6

Please sign in to comment.