fix: API_KEY is no longer required for login to work

This commit is contained in:
Aarnav Tale 2024-05-01 02:43:44 -04:00
parent a57e777a6b
commit a63f4e4d52
No known key found for this signature in database
8 changed files with 39 additions and 18 deletions

9
CHANGELOG.md Normal file
View File

@ -0,0 +1,9 @@
### 0.1.2 (May 1, 2024)
- Added support for renaming, expiring, removing, and managing the routes of a machine.
- Implemented an expiry check for machines which now reflect on the machine table.
- Fixed an issue where `HEADSCALE_CONTAINER` was needed to start even without the Docker integration.
- Removed the requirement for the root `API_KEY` unless OIDC was being used for authentication.
- Switched to [React Aria](https://react-spectrum.adobe.com/react-aria/) for better accessibility support.
- Cleaned up various different UI inconsistencies and copied components that could've been abstracted.
- Added a changelog for any new versions going forward.

View File

@ -33,14 +33,6 @@ export async function loader() {
throw new Error('The COOKIE_SECRET environment variable is required')
}
if (!process.env.API_KEY) {
throw new Error('The API_KEY environment variable is required')
}
if (!process.env.HEADSCALE_CONTAINER) {
throw new Error('The HEADSCALE_CONTAINER environment variable is required')
}
// eslint-disable-next-line unicorn/no-null
return null
}

View File

@ -233,6 +233,7 @@ async function getOidcConfig() {
let issuer = process.env.OIDC_ISSUER
let client = process.env.OIDC_CLIENT_ID
let secret = process.env.OIDC_CLIENT_SECRET
const rootKey = process.env.API_KEY
if (!issuer || !client || !secret) {
const config = await getConfig()
@ -250,6 +251,10 @@ async function getOidcConfig() {
return
}
if (!rootKey) {
throw new Error('Cannot use OIDC without the root API_KEY variable set')
}
return { issuer, client, secret }
}

View File

@ -1,4 +1,4 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
/* eslint-disable no-await-in-loop */
/* eslint-disable no-constant-condition */
import { setTimeout } from 'node:timers/promises'
@ -6,7 +6,7 @@ import { setTimeout } from 'node:timers/promises'
import { Client } from 'undici'
import { getContext } from './config'
import { pull } from './headscale'
import { HeadscaleError, pull } from './headscale'
export async function sighupHeadscale() {
const context = await getContext()
@ -61,9 +61,16 @@ export async function restartHeadscale() {
let attempts = 0
while (true) {
try {
await pull('v1/apikey', process.env.API_KEY!)
// Acceptable blank because API_KEY is not required
await pull('v1/apikey', process.env.API_KEY ?? '')
return
} catch {
} catch (error) {
// This means the server is up but the API key is invalid
// This can happen if the user only uses API_KEY via cookies
if (error instanceof HeadscaleError && error.status === 401) {
break
}
if (attempts > 10) {
throw new Error('Headscale did not restart in time')
}

View File

@ -12,7 +12,7 @@ export class HeadscaleError extends Error {
export class FatalError extends Error {
constructor() {
super('The Headscale server is not accessible or the API_KEY is invalid.')
super('The Headscale server is not accessible or the supplied API key is invalid')
this.name = 'FatalError'
}
}

View File

@ -68,9 +68,8 @@ services:
ports:
- '3000:3000'
environment:
# These are always required for Headplane to work
# This is always required for Headplane to work
COOKIE_SECRET: 'abcdefghijklmnopqrstuvwxyz'
API_KEY: 'abcdefghijklmnopqrstuvwxyz'
HEADSCALE_CONTAINER: 'headscale'
DISABLE_API_KEY_LOGIN: 'true'
@ -82,6 +81,11 @@ services:
OIDC_CLIENT_ID: 'headscale'
OIDC_ISSUER: 'https://sso.example.com'
OIDC_CLIENT_SECRET: 'super_secret_client_secret'
# This NEEDS to be set with OIDC, regardless of what's in the config
# This needs to be a very long-lived (999 day) API key used to create
# shorter ones for OIDC and allow the OIDC functionality to work
API_KEY: 'abcdefghijklmnopqrstuvwxyz'
```
> For a breakdown of each configuration variable, please refer to the [Configuration](/docs/Configuration.md) guide.

View File

@ -28,13 +28,17 @@ services:
- '3000:3000'
environment:
HEADSCALE_URL: 'http://headscale:8080'
API_KEY: 'abcdefghijklmnopqrstuvwxyz'
COOKIE_SECRET: 'abcdefghijklmnopqrstuvwxyz'
# These are all optional!
HEADSCALE_CONTAINER: 'headscale'
API_KEY: 'abcdefghijklmnopqrstuvwxyz'
OIDC_CLIENT_ID: 'headscale'
OIDC_ISSUER: 'https://sso.example.com'
OIDC_CLIENT_SECRET: 'super_secret_client_secret'
DISABLE_API_KEY_LOGIN: 'true'
# These are the default values
HOST: '0.0.0.0'
PORT: '3000'
```

View File

@ -4,9 +4,8 @@ You can configure Headplane using environment variables.
#### Required Variables
- **`HEADSCALE_URL`**: The public URL of your Headscale server.
- **`API_KEY`**: An API key used to issue new ones for sessions (keep expiry fairly long).
- **`COOKIE_SECRET`**: A secret used to sign cookies (use a relatively long and random string).
- **`HEADSCALE_URL`**: The public URL of your Headscale server (not required if using the configuration file).
#### Optional Variables
@ -24,6 +23,7 @@ If you use the Headscale configuration integration, these are not required.
- **`OIDC_ISSUER`**: The issuer URL of your OIDC provider.
- **`OIDC_CLIENT_ID`**: The client ID of your OIDC provider.
- **`OIDC_CLIENT_SECRET`**: The client secret of your OIDC provider.
- **`API_KEY`**: An API key used to issue new ones for sessions (keep expiry fairly long).
- **`DISABLE_API_KEY_LOGIN`**: If you want to disable API key login, set this to `true`.
Here's what an example with Authelia would look like if you used the same client for both Headscale and Headplane.