Fix blueprints

This commit is contained in:
Joey Yakimowich-Payne 2026-01-16 09:10:19 -07:00
commit 1bfe7e3437
No known key found for this signature in database
GPG key ID: 6BFE655FA5ABD1E1
4 changed files with 79 additions and 16 deletions

View file

@ -16,6 +16,15 @@ metadata:
name: Kaboot Application Setup (Production) name: Kaboot Application Setup (Production)
labels: labels:
blueprints.goauthentik.io/description: "Complete Kaboot OAuth2/OIDC setup for production" blueprints.goauthentik.io/description: "Complete Kaboot OAuth2/OIDC setup for production"
blueprints.goauthentik.io/instantiate: "true"
depends_on:
- default/flow-default-authentication-flow.yaml
- default/flow-default-invalidation-flow.yaml
- default/flow-default-provider-authorization-implicit-consent.yaml
- default/flow-default-provider-invalidation.yaml
- default/flow-default-user-settings-flow.yaml
- system/providers-oauth2.yaml
context: context:
kaboot_domain: kaboot.example.com kaboot_domain: kaboot.example.com
@ -127,7 +136,7 @@ entries:
scope_name: groups scope_name: groups
description: "Include user groups in the token" description: "Include user groups in the token"
expression: | expression: |
return [group.name for group in user.ak_groups.all()] return {"groups": [group.name for group in request.user.ak_groups.all()]}
# ═══════════════════════════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════════════════════════
# OAUTH2/OIDC PROVIDER # OAUTH2/OIDC PROVIDER

View file

@ -23,8 +23,71 @@ metadata:
name: Kaboot Application Setup name: Kaboot Application Setup
labels: labels:
blueprints.goauthentik.io/description: "Complete Kaboot OAuth2/OIDC setup with enrollment flow" blueprints.goauthentik.io/description: "Complete Kaboot OAuth2/OIDC setup with enrollment flow"
blueprints.goauthentik.io/instantiate: "true"
# This blueprint depends on default authentik resources being created first.
# The depends_on ensures proper ordering during initial bootstrap.
depends_on:
- default/flow-default-authentication-flow.yaml
- default/flow-default-invalidation-flow.yaml
- default/flow-default-provider-authorization-implicit-consent.yaml
- default/flow-default-provider-invalidation.yaml
- default/flow-default-user-settings-flow.yaml
- system/providers-oauth2.yaml
entries: entries:
# ═══════════════════════════════════════════════════════════════════════════════
# CUSTOM INVALIDATION FLOW (must be defined before brand that references it)
# ═══════════════════════════════════════════════════════════════════════════════
- id: kaboot-logout-stage
model: authentik_stages_user_logout.userlogoutstage
identifiers:
name: kaboot-logout
attrs:
name: kaboot-logout
- id: kaboot-redirect-stage
model: authentik_stages_redirect.redirectstage
identifiers:
name: kaboot-redirect-to-app
attrs:
name: kaboot-redirect-to-app
mode: static
target_static: http://localhost:5173
- id: kaboot-invalidation-flow
model: authentik_flows.flow
identifiers:
slug: kaboot-invalidation-flow
attrs:
name: Kaboot Logout Flow
title: Logging out...
slug: kaboot-invalidation-flow
designation: invalidation
authentication: none
background: /media/branding/background.svg
- id: kaboot-invalidation-logout-binding
model: authentik_flows.flowstagebinding
identifiers:
target: !KeyOf kaboot-invalidation-flow
stage: !KeyOf kaboot-logout-stage
attrs:
order: 0
evaluate_on_plan: true
re_evaluate_policies: false
- id: kaboot-invalidation-redirect-binding
model: authentik_flows.flowstagebinding
identifiers:
target: !KeyOf kaboot-invalidation-flow
stage: !KeyOf kaboot-redirect-stage
attrs:
order: 10
evaluate_on_plan: true
re_evaluate_policies: false
# ═══════════════════════════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════════════════════════
# GROUPS # GROUPS
# ═══════════════════════════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════════════════════════
@ -56,7 +119,7 @@ entries:
scope_name: groups scope_name: groups
description: "Include user groups in the token" description: "Include user groups in the token"
expression: | expression: |
return [group.name for group in user.ak_groups.all()] return {"groups": [group.name for group in request.user.ak_groups.all()]}
# ═══════════════════════════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════════════════════════
# OAUTH2/OIDC PROVIDER # OAUTH2/OIDC PROVIDER
@ -69,7 +132,7 @@ entries:
attrs: attrs:
name: Kaboot OAuth2 name: Kaboot OAuth2
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]] authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]] invalidation_flow: !KeyOf kaboot-invalidation-flow
signing_key: !Find [authentik_crypto.certificatekeypair, [name, authentik Internal JWT Certificate]] signing_key: !Find [authentik_crypto.certificatekeypair, [name, authentik Internal JWT Certificate]]
client_type: public client_type: public
client_id: kaboot-spa client_id: kaboot-spa
@ -134,7 +197,7 @@ entries:
branding_logo: /media/branding/logo.svg branding_logo: /media/branding/logo.svg
branding_favicon: /media/branding/logo.svg branding_favicon: /media/branding/logo.svg
flow_authentication: !Find [authentik_flows.flow, [slug, default-authentication-flow]] flow_authentication: !Find [authentik_flows.flow, [slug, default-authentication-flow]]
flow_invalidation: !Find [authentik_flows.flow, [slug, default-invalidation-flow]] flow_invalidation: !KeyOf kaboot-invalidation-flow
flow_user_settings: !Find [authentik_flows.flow, [slug, default-user-settings-flow]] flow_user_settings: !Find [authentik_flows.flow, [slug, default-user-settings-flow]]
default_application: !KeyOf kaboot-application default_application: !KeyOf kaboot-application
attributes: attributes:
@ -266,13 +329,6 @@ entries:
title: Welcome to Kaboot! title: Welcome to Kaboot!
background: /media/branding/background.svg background: /media/branding/background.svg
- id: update-invalidation-flow-background
model: authentik_flows.flow
identifiers:
slug: default-invalidation-flow
attrs:
background: /media/branding/background.svg
- id: update-authorization-flow-background - id: update-authorization-flow-background
model: authentik_flows.flow model: authentik_flows.flow
identifiers: identifiers:

View file

@ -112,7 +112,7 @@ const runMigrations = () => {
const quizTableInfo = db.prepare("PRAGMA table_info(quizzes)").all() as { name: string }[]; const quizTableInfo = db.prepare("PRAGMA table_info(quizzes)").all() as { name: string }[];
const hasShareToken = quizTableInfo.some(col => col.name === "share_token"); const hasShareToken = quizTableInfo.some(col => col.name === "share_token");
if (!hasShareToken) { if (!hasShareToken) {
db.exec("ALTER TABLE quizzes ADD COLUMN share_token TEXT UNIQUE"); db.exec("ALTER TABLE quizzes ADD COLUMN share_token TEXT");
console.log("Migration: Added share_token to quizzes"); console.log("Migration: Added share_token to quizzes");
} }
@ -124,8 +124,8 @@ const runMigrations = () => {
const shareTokenIndex = db.prepare("SELECT name FROM sqlite_master WHERE type='index' AND name='idx_quizzes_share_token'").get(); const shareTokenIndex = db.prepare("SELECT name FROM sqlite_master WHERE type='index' AND name='idx_quizzes_share_token'").get();
if (!shareTokenIndex) { if (!shareTokenIndex) {
db.exec("CREATE INDEX idx_quizzes_share_token ON quizzes(share_token)"); db.exec("CREATE UNIQUE INDEX idx_quizzes_share_token ON quizzes(share_token)");
console.log("Migration: Created index on quizzes.share_token"); console.log("Migration: Created unique index on quizzes.share_token");
} }
}; };

View file

@ -60,7 +60,5 @@ CREATE TABLE IF NOT EXISTS game_sessions (
); );
CREATE INDEX IF NOT EXISTS idx_quizzes_user ON quizzes(user_id); CREATE INDEX IF NOT EXISTS idx_quizzes_user ON quizzes(user_id);
CREATE INDEX IF NOT EXISTS idx_quizzes_share_token ON quizzes(share_token);
CREATE INDEX IF NOT EXISTS idx_questions_quiz ON questions(quiz_id); CREATE INDEX IF NOT EXISTS idx_questions_quiz ON questions(quiz_id);
CREATE INDEX IF NOT EXISTS idx_options_question ON answer_options(question_id); CREATE INDEX IF NOT EXISTS idx_options_question ON answer_options(question_id);
CREATE INDEX IF NOT EXISTS idx_game_sessions_updated ON game_sessions(updated_at);