Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Cargo.lock

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

8 changes: 4 additions & 4 deletions apps/rook/dashboard/e2e/api-keys.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ async function revokeKeysByLabelViaApi(page: Page, label: string): Promise<void>
async function createApiKeyViaApi(
page: Page,
label: string,
scopes: string[] = ['read'],
scopes: string[] = ['chat:read'],
tier: string = 'free'
): Promise<{ id: string; plaintextKey: string }> {
const csrf = await getCsrfToken(page)
Expand Down Expand Up @@ -235,7 +235,7 @@ test.describe('API Keys - Create Flow', () => {

// Fill in the form
await page.getByLabel(/label/i).fill(createLabel)
await page.getByRole('dialog').getByText(/read/i).click()
await page.getByRole('dialog').getByText(/^chat read$/i).click()

// Submit
await page.getByRole('button', { name: /create key/i }).click()
Expand Down Expand Up @@ -283,7 +283,7 @@ test.describe('API Keys - Edit Flow', () => {
// Revoke any leftover key for this worker, then create a fresh one.
await revokeKeysByLabelViaApi(page, editLabel)
await revokeKeysByLabelViaApi(page, `updated-key-label-${testInfo.workerIndex}`)
await createApiKeyViaApi(page, editLabel, ['read'], 'free')
await createApiKeyViaApi(page, editLabel, ['chat:read'], 'free')
})

test('opens edit modal when clicking edit button', async ({ page }) => {
Expand Down Expand Up @@ -366,7 +366,7 @@ test.describe('API Keys - Revoke Flow', () => {
// Revoke only OUR worker's label — avoids touching keys belonging to
// concurrent browser workers, which caused a race condition on reload.
await revokeKeysByLabelViaApi(page, revokeLabel)
await createApiKeyViaApi(page, revokeLabel, ['read'], 'free')
await createApiKeyViaApi(page, revokeLabel, ['chat:read'], 'free')
})

test('shows confirmation dialog when revoking', async ({ page }) => {
Expand Down
4 changes: 2 additions & 2 deletions apps/rook/dashboard/src/views/ApiKeysView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,8 @@ const hasNextPage = computed(() => offset.value + limit.value < total.value)
const hasPrevPage = computed(() => offset.value > 0)

const scopesOptions = [
{ value: 'read', label: 'Read' },
{ value: 'write', label: 'Write' },
{ value: 'chat:read', label: 'Chat Read' },
{ value: 'chat:write', label: 'Chat Write' },
]

const tierOptions = [
Expand Down
3 changes: 3 additions & 0 deletions crates/application/rook-usecases/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,6 @@ subtle = "2"

# Base64 for token encoding
base64 = "0.22"

# Hex encoding for digest output
hex = "0.4"
2 changes: 2 additions & 0 deletions crates/application/rook-usecases/src/auth/bootstrap_status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ impl BootstrapStatus {
scopes: vec![ApiKeyScope::parse("admin").expect("static admin scope")],
tier: ApiKeyTier::Enterprise,
expires_at: None,
allowed_models: vec![],
allowed_providers: vec![],
})
.await?;

Expand Down
2 changes: 1 addition & 1 deletion crates/application/rook-usecases/src/auth/login.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl Login {
// Step 5: SHA-256 hash the token → token_hash
let mut hasher = Sha256::new();
hasher.update(token_bytes);
let token_hash = format!("{:x}", hasher.finalize());
let token_hash = hex::encode(hasher.finalize());

// Step 6: Create session
let new_session = rook_core::NewSession {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl ValidateSession {
// Step 2: SHA-256 hash the token bytes
let mut hasher = Sha256::new();
hasher.update(&token_bytes);
let token_hash = format!("{:x}", hasher.finalize());
let token_hash = hex::encode(hasher.finalize());

// Step 3: Look up session by token hash
let session = self
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,10 @@ mod tests {
ApiKeySubject {
id: ApiKeyId::new("key_1"),
label: "Production".to_string(),
scopes: vec![ApiKeyScope::parse("read").expect("scope")],
scopes: vec![ApiKeyScope::parse("chat:read").expect("scope")],
tier: ApiKeyTier::Pro,
allowed_models: vec![],
allowed_providers: vec![],
}
}

Expand Down
Loading