Fix compose issues. Add host and end early
This commit is contained in:
parent
eee3e7e47b
commit
a5f2f19898
5 changed files with 259 additions and 223 deletions
|
|
@ -74,115 +74,6 @@ entries:
|
||||||
evaluate_on_plan: true
|
evaluate_on_plan: true
|
||||||
re_evaluate_policies: false
|
re_evaluate_policies: false
|
||||||
|
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
# BRANDING
|
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
|
|
||||||
- id: kaboot-brand
|
|
||||||
model: authentik_brands.brand
|
|
||||||
identifiers:
|
|
||||||
domain: !Context auth_domain
|
|
||||||
attrs:
|
|
||||||
domain: !Context auth_domain
|
|
||||||
default: false
|
|
||||||
branding_title: Kaboot
|
|
||||||
branding_logo: /media/branding/logo.svg
|
|
||||||
branding_favicon: /media/branding/logo.svg
|
|
||||||
flow_authentication: !Find [authentik_flows.flow, [slug, default-authentication-flow]]
|
|
||||||
flow_invalidation: !KeyOf kaboot-invalidation-flow
|
|
||||||
flow_user_settings: !Find [authentik_flows.flow, [slug, default-user-settings-flow]]
|
|
||||||
default_application: !Find [authentik_core.application, [slug, kaboot]]
|
|
||||||
attributes:
|
|
||||||
settings:
|
|
||||||
theme:
|
|
||||||
base: light
|
|
||||||
css: |
|
|
||||||
:root {
|
|
||||||
--ak-accent: #2563eb;
|
|
||||||
--ak-primary: #2563eb;
|
|
||||||
--ak-primary-dark: #1e40af;
|
|
||||||
--ak-primary-light: #60a5fa;
|
|
||||||
--ak-error: #ef4444;
|
|
||||||
--ak-success: #22c55e;
|
|
||||||
--pf-global--FontFamily--sans-serif: "Inter", system-ui, -apple-system, sans-serif;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
background-color: #2563eb !important;
|
|
||||||
}
|
|
||||||
.pf-c-login__main {
|
|
||||||
background-color: #ffffff !important;
|
|
||||||
border-radius: 2rem !important;
|
|
||||||
box-shadow: 0 10px 0 rgba(0,0,0,0.1) !important;
|
|
||||||
padding: 3rem !important;
|
|
||||||
max-width: 500px !important;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
.pf-c-form-control {
|
|
||||||
border: 2px solid #e5e7eb !important;
|
|
||||||
border-radius: 1rem !important;
|
|
||||||
padding: 0.75rem 1rem !important;
|
|
||||||
font-weight: 600 !important;
|
|
||||||
color: #333 !important;
|
|
||||||
font-size: 1rem !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
transition: all 0.2s ease !important;
|
|
||||||
}
|
|
||||||
.pf-c-form-control:focus {
|
|
||||||
border-color: #2563eb !important;
|
|
||||||
outline: none !important;
|
|
||||||
}
|
|
||||||
.pf-c-button.pf-m-primary {
|
|
||||||
background-color: #333333 !important;
|
|
||||||
color: #ffffff !important;
|
|
||||||
border: none !important;
|
|
||||||
border-radius: 1rem !important;
|
|
||||||
padding: 0.75rem 1.5rem !important;
|
|
||||||
font-weight: 800 !important;
|
|
||||||
font-size: 1.1rem !important;
|
|
||||||
box-shadow: 0 6px 0 #000000 !important;
|
|
||||||
transform: translateY(0) !important;
|
|
||||||
transition: all 0.1s ease !important;
|
|
||||||
text-transform: uppercase !important;
|
|
||||||
letter-spacing: 0.05em !important;
|
|
||||||
}
|
|
||||||
.pf-c-button.pf-m-primary:hover {
|
|
||||||
background-color: #1a1a1a !important;
|
|
||||||
}
|
|
||||||
.pf-c-button.pf-m-primary:active {
|
|
||||||
transform: translateY(6px) !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
}
|
|
||||||
.pf-c-button.pf-m-secondary, .pf-c-button.pf-m-link {
|
|
||||||
color: #2563eb !important;
|
|
||||||
font-weight: 600 !important;
|
|
||||||
}
|
|
||||||
.pf-c-title {
|
|
||||||
font-weight: 900 !important;
|
|
||||||
color: #111827 !important;
|
|
||||||
text-align: center !important;
|
|
||||||
margin-bottom: 1.5rem !important;
|
|
||||||
}
|
|
||||||
.pf-c-brand {
|
|
||||||
filter: drop-shadow(0 4px 6px rgba(0,0,0,0.1));
|
|
||||||
}
|
|
||||||
.pf-c-alert {
|
|
||||||
border-radius: 1rem !important;
|
|
||||||
border: 2px solid transparent !important;
|
|
||||||
box-shadow: 0 4px 0 rgba(0,0,0,0.05) !important;
|
|
||||||
}
|
|
||||||
.pf-c-alert.pf-m-danger {
|
|
||||||
background-color: #fef2f2 !important;
|
|
||||||
border-color: #fca5a5 !important;
|
|
||||||
color: #991b1b !important;
|
|
||||||
}
|
|
||||||
.pf-c-login__main-footer-links-item-link {
|
|
||||||
color: #6b7280 !important;
|
|
||||||
font-weight: 500 !important;
|
|
||||||
}
|
|
||||||
.pf-c-background-image {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
# FLOW BACKGROUNDS
|
# FLOW BACKGROUNDS
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
@ -299,6 +190,115 @@ entries:
|
||||||
negate: false
|
negate: false
|
||||||
timeout: 30
|
timeout: 30
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
# BRANDING (must be after application is created)
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
- id: kaboot-brand
|
||||||
|
model: authentik_brands.brand
|
||||||
|
identifiers:
|
||||||
|
domain: !Context auth_domain
|
||||||
|
attrs:
|
||||||
|
domain: !Context auth_domain
|
||||||
|
default: false
|
||||||
|
branding_title: Kaboot
|
||||||
|
branding_logo: /media/branding/logo.svg
|
||||||
|
branding_favicon: /media/branding/logo.svg
|
||||||
|
flow_authentication: !Find [authentik_flows.flow, [slug, default-authentication-flow]]
|
||||||
|
flow_invalidation: !KeyOf kaboot-invalidation-flow
|
||||||
|
flow_user_settings: !Find [authentik_flows.flow, [slug, default-user-settings-flow]]
|
||||||
|
default_application: !KeyOf kaboot-application
|
||||||
|
attributes:
|
||||||
|
settings:
|
||||||
|
theme:
|
||||||
|
base: light
|
||||||
|
css: |
|
||||||
|
:root {
|
||||||
|
--ak-accent: #2563eb;
|
||||||
|
--ak-primary: #2563eb;
|
||||||
|
--ak-primary-dark: #1e40af;
|
||||||
|
--ak-primary-light: #60a5fa;
|
||||||
|
--ak-error: #ef4444;
|
||||||
|
--ak-success: #22c55e;
|
||||||
|
--pf-global--FontFamily--sans-serif: "Inter", system-ui, -apple-system, sans-serif;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
background-color: #2563eb !important;
|
||||||
|
}
|
||||||
|
.pf-c-login__main {
|
||||||
|
background-color: #ffffff !important;
|
||||||
|
border-radius: 2rem !important;
|
||||||
|
box-shadow: 0 10px 0 rgba(0,0,0,0.1) !important;
|
||||||
|
padding: 3rem !important;
|
||||||
|
max-width: 500px !important;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.pf-c-form-control {
|
||||||
|
border: 2px solid #e5e7eb !important;
|
||||||
|
border-radius: 1rem !important;
|
||||||
|
padding: 0.75rem 1rem !important;
|
||||||
|
font-weight: 600 !important;
|
||||||
|
color: #333 !important;
|
||||||
|
font-size: 1rem !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
transition: all 0.2s ease !important;
|
||||||
|
}
|
||||||
|
.pf-c-form-control:focus {
|
||||||
|
border-color: #2563eb !important;
|
||||||
|
outline: none !important;
|
||||||
|
}
|
||||||
|
.pf-c-button.pf-m-primary {
|
||||||
|
background-color: #333333 !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
border: none !important;
|
||||||
|
border-radius: 1rem !important;
|
||||||
|
padding: 0.75rem 1.5rem !important;
|
||||||
|
font-weight: 800 !important;
|
||||||
|
font-size: 1.1rem !important;
|
||||||
|
box-shadow: 0 6px 0 #000000 !important;
|
||||||
|
transform: translateY(0) !important;
|
||||||
|
transition: all 0.1s ease !important;
|
||||||
|
text-transform: uppercase !important;
|
||||||
|
letter-spacing: 0.05em !important;
|
||||||
|
}
|
||||||
|
.pf-c-button.pf-m-primary:hover {
|
||||||
|
background-color: #1a1a1a !important;
|
||||||
|
}
|
||||||
|
.pf-c-button.pf-m-primary:active {
|
||||||
|
transform: translateY(6px) !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
.pf-c-button.pf-m-secondary, .pf-c-button.pf-m-link {
|
||||||
|
color: #2563eb !important;
|
||||||
|
font-weight: 600 !important;
|
||||||
|
}
|
||||||
|
.pf-c-title {
|
||||||
|
font-weight: 900 !important;
|
||||||
|
color: #111827 !important;
|
||||||
|
text-align: center !important;
|
||||||
|
margin-bottom: 1.5rem !important;
|
||||||
|
}
|
||||||
|
.pf-c-brand {
|
||||||
|
filter: drop-shadow(0 4px 6px rgba(0,0,0,0.1));
|
||||||
|
}
|
||||||
|
.pf-c-alert {
|
||||||
|
border-radius: 1rem !important;
|
||||||
|
border: 2px solid transparent !important;
|
||||||
|
box-shadow: 0 4px 0 rgba(0,0,0,0.05) !important;
|
||||||
|
}
|
||||||
|
.pf-c-alert.pf-m-danger {
|
||||||
|
background-color: #fef2f2 !important;
|
||||||
|
border-color: #fca5a5 !important;
|
||||||
|
color: #991b1b !important;
|
||||||
|
}
|
||||||
|
.pf-c-login__main-footer-links-item-link {
|
||||||
|
color: #6b7280 !important;
|
||||||
|
font-weight: 500 !important;
|
||||||
|
}
|
||||||
|
.pf-c-background-image {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
# PASSWORD POLICY
|
# PASSWORD POLICY
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
|
||||||
|
|
@ -26,15 +26,109 @@ metadata:
|
||||||
|
|
||||||
entries:
|
entries:
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
# BRANDING
|
# GROUPS
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
- id: kaboot-users-group
|
||||||
|
model: authentik_core.group
|
||||||
|
identifiers:
|
||||||
|
name: kaboot-users
|
||||||
|
attrs:
|
||||||
|
name: kaboot-users
|
||||||
|
|
||||||
|
- id: kaboot-ai-access-group
|
||||||
|
model: authentik_core.group
|
||||||
|
identifiers:
|
||||||
|
name: kaboot-ai-access
|
||||||
|
attrs:
|
||||||
|
name: kaboot-ai-access
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
# GROUPS SCOPE MAPPING
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
- id: groups-scope-mapping
|
||||||
|
model: authentik_providers_oauth2.scopemapping
|
||||||
|
identifiers:
|
||||||
|
managed: goauthentik.io/providers/oauth2/scope-kaboot-groups
|
||||||
|
attrs:
|
||||||
|
name: "Kaboot Groups Scope"
|
||||||
|
scope_name: groups
|
||||||
|
description: "Include user groups in the token"
|
||||||
|
expression: |
|
||||||
|
return [group.name for group in user.ak_groups.all()]
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
# OAUTH2/OIDC PROVIDER
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
- id: kaboot-oauth2-provider
|
||||||
|
model: authentik_providers_oauth2.oauth2provider
|
||||||
|
identifiers:
|
||||||
|
name: Kaboot OAuth2
|
||||||
|
attrs:
|
||||||
|
name: Kaboot OAuth2
|
||||||
|
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
|
||||||
|
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
|
||||||
|
signing_key: !Find [authentik_crypto.certificatekeypair, [name, authentik Internal JWT Certificate]]
|
||||||
|
client_type: public
|
||||||
|
client_id: kaboot-spa
|
||||||
|
redirect_uris:
|
||||||
|
- url: http://localhost:5173/callback
|
||||||
|
matching_mode: strict
|
||||||
|
- url: http://localhost:5173/silent-renew.html
|
||||||
|
matching_mode: strict
|
||||||
|
- url: http://localhost:5173
|
||||||
|
matching_mode: strict
|
||||||
|
access_code_validity: minutes=1
|
||||||
|
access_token_validity: minutes=30
|
||||||
|
refresh_token_validity: days=30
|
||||||
|
sub_mode: hashed_user_id
|
||||||
|
include_claims_in_id_token: true
|
||||||
|
issuer_mode: per_provider
|
||||||
|
property_mappings:
|
||||||
|
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, openid]]
|
||||||
|
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, profile]]
|
||||||
|
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, email]]
|
||||||
|
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, offline_access]]
|
||||||
|
- !KeyOf groups-scope-mapping
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
# APPLICATION
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
- id: kaboot-application
|
||||||
|
model: authentik_core.application
|
||||||
|
identifiers:
|
||||||
|
slug: kaboot
|
||||||
|
attrs:
|
||||||
|
name: Kaboot
|
||||||
|
slug: kaboot
|
||||||
|
provider: !KeyOf kaboot-oauth2-provider
|
||||||
|
policy_engine_mode: any
|
||||||
|
meta_launch_url: http://localhost:5173
|
||||||
|
|
||||||
|
- id: kaboot-group-policy-binding
|
||||||
|
model: authentik_policies.policybinding
|
||||||
|
identifiers:
|
||||||
|
target: !KeyOf kaboot-application
|
||||||
|
group: !KeyOf kaboot-users-group
|
||||||
|
attrs:
|
||||||
|
order: 0
|
||||||
|
enabled: true
|
||||||
|
negate: false
|
||||||
|
timeout: 30
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
# BRANDING (must be after application is created)
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
- id: kaboot-brand
|
- id: kaboot-brand
|
||||||
model: authentik_brands.brand
|
model: authentik_brands.brand
|
||||||
identifiers:
|
identifiers:
|
||||||
domain: localhost
|
domain: authentik-default
|
||||||
attrs:
|
attrs:
|
||||||
domain: localhost
|
domain: authentik-default
|
||||||
default: true
|
default: true
|
||||||
branding_title: Kaboot
|
branding_title: Kaboot
|
||||||
branding_logo: /media/branding/logo.svg
|
branding_logo: /media/branding/logo.svg
|
||||||
|
|
@ -42,7 +136,7 @@ entries:
|
||||||
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: !Find [authentik_flows.flow, [slug, default-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: !Find [authentik_core.application, [slug, kaboot]]
|
default_application: !KeyOf kaboot-application
|
||||||
attributes:
|
attributes:
|
||||||
settings:
|
settings:
|
||||||
theme:
|
theme:
|
||||||
|
|
@ -186,100 +280,6 @@ entries:
|
||||||
attrs:
|
attrs:
|
||||||
background: /media/branding/background.svg
|
background: /media/branding/background.svg
|
||||||
|
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
# GROUPS
|
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
|
|
||||||
- id: kaboot-users-group
|
|
||||||
model: authentik_core.group
|
|
||||||
identifiers:
|
|
||||||
name: kaboot-users
|
|
||||||
attrs:
|
|
||||||
name: kaboot-users
|
|
||||||
|
|
||||||
- id: kaboot-ai-access-group
|
|
||||||
model: authentik_core.group
|
|
||||||
identifiers:
|
|
||||||
name: kaboot-ai-access
|
|
||||||
attrs:
|
|
||||||
name: kaboot-ai-access
|
|
||||||
|
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
# GROUPS SCOPE MAPPING
|
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
|
|
||||||
- id: groups-scope-mapping
|
|
||||||
model: authentik_providers_oauth2.scopemapping
|
|
||||||
identifiers:
|
|
||||||
managed: goauthentik.io/providers/oauth2/scope-kaboot-groups
|
|
||||||
attrs:
|
|
||||||
name: "Kaboot Groups Scope"
|
|
||||||
scope_name: groups
|
|
||||||
description: "Include user groups in the token"
|
|
||||||
expression: |
|
|
||||||
return [group.name for group in user.ak_groups.all()]
|
|
||||||
|
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
# OAUTH2/OIDC PROVIDER
|
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
|
|
||||||
- id: kaboot-oauth2-provider
|
|
||||||
model: authentik_providers_oauth2.oauth2provider
|
|
||||||
identifiers:
|
|
||||||
name: Kaboot OAuth2
|
|
||||||
attrs:
|
|
||||||
name: Kaboot OAuth2
|
|
||||||
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
|
|
||||||
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
|
|
||||||
signing_key: !Find [authentik_crypto.certificatekeypair, [name, authentik Internal JWT Certificate]]
|
|
||||||
client_type: public
|
|
||||||
client_id: kaboot-spa
|
|
||||||
redirect_uris:
|
|
||||||
- url: http://localhost:5173/callback
|
|
||||||
matching_mode: strict
|
|
||||||
- url: http://localhost:5173/silent-renew.html
|
|
||||||
matching_mode: strict
|
|
||||||
- url: http://localhost:5173
|
|
||||||
matching_mode: strict
|
|
||||||
access_code_validity: minutes=1
|
|
||||||
access_token_validity: minutes=30
|
|
||||||
refresh_token_validity: days=30
|
|
||||||
sub_mode: hashed_user_id
|
|
||||||
include_claims_in_id_token: true
|
|
||||||
issuer_mode: per_provider
|
|
||||||
property_mappings:
|
|
||||||
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, openid]]
|
|
||||||
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, profile]]
|
|
||||||
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, email]]
|
|
||||||
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, offline_access]]
|
|
||||||
- !KeyOf groups-scope-mapping
|
|
||||||
|
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
# APPLICATION
|
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
|
||||||
|
|
||||||
- id: kaboot-application
|
|
||||||
model: authentik_core.application
|
|
||||||
identifiers:
|
|
||||||
slug: kaboot
|
|
||||||
attrs:
|
|
||||||
name: Kaboot
|
|
||||||
slug: kaboot
|
|
||||||
provider: !KeyOf kaboot-oauth2-provider
|
|
||||||
policy_engine_mode: any
|
|
||||||
meta_launch_url: http://localhost:5173
|
|
||||||
|
|
||||||
- id: kaboot-group-policy-binding
|
|
||||||
model: authentik_policies.policybinding
|
|
||||||
identifiers:
|
|
||||||
target: !KeyOf kaboot-application
|
|
||||||
group: !KeyOf kaboot-users-group
|
|
||||||
attrs:
|
|
||||||
order: 0
|
|
||||||
enabled: true
|
|
||||||
negate: false
|
|
||||||
timeout: 30
|
|
||||||
|
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
# PASSWORD POLICY
|
# PASSWORD POLICY
|
||||||
# ═══════════════════════════════════════════════════════════════════════════════
|
# ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@ services:
|
||||||
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
|
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
|
||||||
start_period: 20s
|
start_period: 20s
|
||||||
interval: 30s
|
interval: 30s
|
||||||
retries: 5
|
|
||||||
timeout: 5s
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
volumes:
|
volumes:
|
||||||
- postgresql-data:/var/lib/postgresql/data
|
- postgresql-data:/var/lib/postgresql/data
|
||||||
environment:
|
environment:
|
||||||
|
|
@ -31,15 +31,15 @@ services:
|
||||||
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
|
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
|
||||||
start_period: 20s
|
start_period: 20s
|
||||||
interval: 30s
|
interval: 30s
|
||||||
retries: 5
|
|
||||||
timeout: 3s
|
timeout: 3s
|
||||||
|
retries: 5
|
||||||
volumes:
|
volumes:
|
||||||
- redis-data:/data
|
- redis-data:/data
|
||||||
networks:
|
networks:
|
||||||
- kaboot-network
|
- kaboot-network
|
||||||
|
|
||||||
authentik-server:
|
authentik-server:
|
||||||
image: ghcr.io/goauthentik/server:2025.2
|
image: ghcr.io/goauthentik/server:2025.10.3
|
||||||
container_name: kaboot-authentik-server
|
container_name: kaboot-authentik-server
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: server
|
command: server
|
||||||
|
|
@ -69,7 +69,7 @@ services:
|
||||||
- kaboot-network
|
- kaboot-network
|
||||||
|
|
||||||
authentik-worker:
|
authentik-worker:
|
||||||
image: ghcr.io/goauthentik/server:2025.2
|
image: ghcr.io/goauthentik/server:2025.10.3
|
||||||
container_name: kaboot-authentik-worker
|
container_name: kaboot-authentik-worker
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: worker
|
command: worker
|
||||||
|
|
@ -80,12 +80,15 @@ services:
|
||||||
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
|
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
|
||||||
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
|
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
|
||||||
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
|
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
|
||||||
|
AUTHENTIK_BOOTSTRAP_PASSWORD: ${AUTHENTIK_BOOTSTRAP_PASSWORD:-}
|
||||||
|
AUTHENTIK_BOOTSTRAP_TOKEN: ${AUTHENTIK_BOOTSTRAP_TOKEN:-}
|
||||||
user: root
|
user: root
|
||||||
volumes:
|
volumes:
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
- ./authentik/media:/media
|
- ./authentik/media:/media
|
||||||
- ./authentik/certs:/certs
|
- ./authentik/certs:/certs
|
||||||
- ./authentik/custom-templates:/templates
|
- ./authentik/custom-templates:/templates
|
||||||
|
- ./authentik/blueprints:/blueprints/custom
|
||||||
depends_on:
|
depends_on:
|
||||||
postgresql:
|
postgresql:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
|
|
@ -113,6 +116,8 @@ services:
|
||||||
OIDC_JWKS_URI: http://${KABOOT_HOST:-localhost}:${AUTHENTIK_PORT_HTTP:-9000}/application/o/kaboot/jwks/
|
OIDC_JWKS_URI: http://${KABOOT_HOST:-localhost}:${AUTHENTIK_PORT_HTTP:-9000}/application/o/kaboot/jwks/
|
||||||
OIDC_INTERNAL_JWKS_URI: http://authentik-server:9000/application/o/kaboot/jwks/
|
OIDC_INTERNAL_JWKS_URI: http://authentik-server:9000/application/o/kaboot/jwks/
|
||||||
CORS_ORIGIN: http://localhost:${KABOOT_FRONTEND_PORT:-5173},http://${KABOOT_HOST:-localhost}:${KABOOT_FRONTEND_PORT:-5173}
|
CORS_ORIGIN: http://localhost:${KABOOT_FRONTEND_PORT:-5173},http://${KABOOT_HOST:-localhost}:${KABOOT_FRONTEND_PORT:-5173}
|
||||||
|
LOG_REQUESTS: ${LOG_REQUESTS:-true}
|
||||||
|
GEMINI_API_KEY: ${GEMINI_API_KEY:-}
|
||||||
volumes:
|
volumes:
|
||||||
- ./data:/data
|
- ./data:/data
|
||||||
ports:
|
ports:
|
||||||
|
|
|
||||||
|
|
@ -854,6 +854,7 @@ export const useGame = () => {
|
||||||
if (p.id !== playerId) return p;
|
if (p.id !== playerId) return p;
|
||||||
return { ...p, score: newScore, previousScore: p.score, streak: newStreak, lastAnswerCorrect: isCorrect, selectedShape, pointsBreakdown: breakdown };
|
return { ...p, score: newScore, previousScore: p.score, streak: newStreak, lastAnswerCorrect: isCorrect, selectedShape, pointsBreakdown: breakdown };
|
||||||
});
|
});
|
||||||
|
playersRef.current = updatedPlayers;
|
||||||
setPlayers(updatedPlayers);
|
setPlayers(updatedPlayers);
|
||||||
|
|
||||||
conn.send({ type: 'RESULT', payload: { isCorrect, scoreAdded: breakdown.total, newScore, breakdown } });
|
conn.send({ type: 'RESULT', payload: { isCorrect, scoreAdded: breakdown.total, newScore, breakdown } });
|
||||||
|
|
@ -1379,6 +1380,7 @@ export const useGame = () => {
|
||||||
if (p.id !== 'host') return p;
|
if (p.id !== 'host') return p;
|
||||||
return { ...p, score: newScore, previousScore: p.score, streak: newStreak, lastAnswerCorrect: isCorrect, selectedShape: option.shape, pointsBreakdown: breakdown };
|
return { ...p, score: newScore, previousScore: p.score, streak: newStreak, lastAnswerCorrect: isCorrect, selectedShape: option.shape, pointsBreakdown: breakdown };
|
||||||
});
|
});
|
||||||
|
playersRef.current = updatedPlayers;
|
||||||
setPlayers(updatedPlayers);
|
setPlayers(updatedPlayers);
|
||||||
|
|
||||||
const allAnswered = updatedPlayers.every(p => p.lastAnswerCorrect !== null);
|
const allAnswered = updatedPlayers.every(p => p.lastAnswerCorrect !== null);
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ ENV_FILE=".env"
|
||||||
ENV_EXAMPLE=".env.example"
|
ENV_EXAMPLE=".env.example"
|
||||||
ENV_LOCAL=".env.local"
|
ENV_LOCAL=".env.local"
|
||||||
|
|
||||||
echo "Kaboot Setup Script"
|
echo "Kaboot Development Setup"
|
||||||
echo "==================="
|
echo "========================"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
if [ -f "$ENV_FILE" ]; then
|
if [ -f "$ENV_FILE" ]; then
|
||||||
|
|
@ -39,14 +39,22 @@ echo ""
|
||||||
read -p "Enter host IP/domain for network access [$DETECTED_IP]: " KABOOT_HOST
|
read -p "Enter host IP/domain for network access [$DETECTED_IP]: " KABOOT_HOST
|
||||||
KABOOT_HOST=${KABOOT_HOST:-$DETECTED_IP}
|
KABOOT_HOST=${KABOOT_HOST:-$DETECTED_IP}
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "System AI Configuration (Optional)"
|
||||||
|
echo "-----------------------------------"
|
||||||
|
echo "You can provide a Gemini API key to enable AI quiz generation"
|
||||||
|
echo "for all users without requiring them to set up their own key."
|
||||||
|
echo ""
|
||||||
|
read -p "Enter Gemini API key (or press Enter to skip): " GEMINI_API_KEY
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "Generating secrets..."
|
echo "Generating secrets..."
|
||||||
|
|
||||||
PG_PASS=$(openssl rand -base64 36 | tr -d '\n')
|
PG_PASS=$(openssl rand -base64 36 | tr -d '\n' | tr -d '/')
|
||||||
AUTHENTIK_SECRET_KEY=$(openssl rand -base64 60 | tr -d '\n')
|
AUTHENTIK_SECRET_KEY=$(openssl rand -base64 60 | tr -d '\n' | tr -d '/')
|
||||||
AUTHENTIK_BOOTSTRAP_PASSWORD=$(openssl rand -base64 24 | tr -d '\n')
|
AUTHENTIK_BOOTSTRAP_PASSWORD=$(openssl rand -base64 24 | tr -d '\n' | tr -d '/')
|
||||||
AUTHENTIK_BOOTSTRAP_TOKEN=$(openssl rand -base64 36 | tr -d '\n')
|
AUTHENTIK_BOOTSTRAP_TOKEN=$(openssl rand -hex 32)
|
||||||
ENCRYPTION_KEY=$(openssl rand -base64 36 | tr -d '\n')
|
ENCRYPTION_KEY=$(openssl rand -base64 36 | tr -d '\n' | tr -d '/')
|
||||||
|
|
||||||
cp "$ENV_EXAMPLE" "$ENV_FILE"
|
cp "$ENV_EXAMPLE" "$ENV_FILE"
|
||||||
|
|
||||||
|
|
@ -57,6 +65,8 @@ if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
sed -i '' "s|^AUTHENTIK_BOOTSTRAP_TOKEN=.*|AUTHENTIK_BOOTSTRAP_TOKEN=${AUTHENTIK_BOOTSTRAP_TOKEN}|" "$ENV_FILE"
|
sed -i '' "s|^AUTHENTIK_BOOTSTRAP_TOKEN=.*|AUTHENTIK_BOOTSTRAP_TOKEN=${AUTHENTIK_BOOTSTRAP_TOKEN}|" "$ENV_FILE"
|
||||||
sed -i '' "s|^ENCRYPTION_KEY=.*|ENCRYPTION_KEY=${ENCRYPTION_KEY}|" "$ENV_FILE"
|
sed -i '' "s|^ENCRYPTION_KEY=.*|ENCRYPTION_KEY=${ENCRYPTION_KEY}|" "$ENV_FILE"
|
||||||
sed -i '' "s|^KABOOT_HOST=.*|KABOOT_HOST=${KABOOT_HOST}|" "$ENV_FILE"
|
sed -i '' "s|^KABOOT_HOST=.*|KABOOT_HOST=${KABOOT_HOST}|" "$ENV_FILE"
|
||||||
|
sed -i '' "s|^LOG_REQUESTS=.*|LOG_REQUESTS=true|" "$ENV_FILE"
|
||||||
|
sed -i '' "s|^GEMINI_API_KEY=.*|GEMINI_API_KEY=${GEMINI_API_KEY}|" "$ENV_FILE"
|
||||||
else
|
else
|
||||||
sed -i "s|^PG_PASS=.*|PG_PASS=${PG_PASS}|" "$ENV_FILE"
|
sed -i "s|^PG_PASS=.*|PG_PASS=${PG_PASS}|" "$ENV_FILE"
|
||||||
sed -i "s|^AUTHENTIK_SECRET_KEY=.*|AUTHENTIK_SECRET_KEY=${AUTHENTIK_SECRET_KEY}|" "$ENV_FILE"
|
sed -i "s|^AUTHENTIK_SECRET_KEY=.*|AUTHENTIK_SECRET_KEY=${AUTHENTIK_SECRET_KEY}|" "$ENV_FILE"
|
||||||
|
|
@ -64,32 +74,51 @@ else
|
||||||
sed -i "s|^AUTHENTIK_BOOTSTRAP_TOKEN=.*|AUTHENTIK_BOOTSTRAP_TOKEN=${AUTHENTIK_BOOTSTRAP_TOKEN}|" "$ENV_FILE"
|
sed -i "s|^AUTHENTIK_BOOTSTRAP_TOKEN=.*|AUTHENTIK_BOOTSTRAP_TOKEN=${AUTHENTIK_BOOTSTRAP_TOKEN}|" "$ENV_FILE"
|
||||||
sed -i "s|^ENCRYPTION_KEY=.*|ENCRYPTION_KEY=${ENCRYPTION_KEY}|" "$ENV_FILE"
|
sed -i "s|^ENCRYPTION_KEY=.*|ENCRYPTION_KEY=${ENCRYPTION_KEY}|" "$ENV_FILE"
|
||||||
sed -i "s|^KABOOT_HOST=.*|KABOOT_HOST=${KABOOT_HOST}|" "$ENV_FILE"
|
sed -i "s|^KABOOT_HOST=.*|KABOOT_HOST=${KABOOT_HOST}|" "$ENV_FILE"
|
||||||
|
sed -i "s|^LOG_REQUESTS=.*|LOG_REQUESTS=true|" "$ENV_FILE"
|
||||||
|
sed -i "s|^GEMINI_API_KEY=.*|GEMINI_API_KEY=${GEMINI_API_KEY}|" "$ENV_FILE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create .env.local for Vite frontend
|
# Create .env.local for Vite frontend
|
||||||
cat > "$ENV_LOCAL" << EOF
|
cat > "$ENV_LOCAL" << EOF
|
||||||
# Auto-generated by setup.sh - Frontend environment variables
|
# Auto-generated by setup.sh - Frontend environment variables
|
||||||
|
VITE_API_URL=http://${KABOOT_HOST}:3001
|
||||||
VITE_BACKEND_URL=http://${KABOOT_HOST}:3001
|
VITE_BACKEND_URL=http://${KABOOT_HOST}:3001
|
||||||
VITE_AUTHENTIK_URL=http://${KABOOT_HOST}:9000
|
VITE_AUTHENTIK_URL=http://${KABOOT_HOST}:9000
|
||||||
|
VITE_OIDC_CLIENT_ID=kaboot-spa
|
||||||
|
VITE_OIDC_APP_SLUG=kaboot
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "Created .env and .env.local files."
|
echo "Setup Complete!"
|
||||||
|
echo "==============="
|
||||||
echo ""
|
echo ""
|
||||||
echo "Host configuration:"
|
echo "Configuration Summary"
|
||||||
|
echo "---------------------"
|
||||||
echo " KABOOT_HOST: ${KABOOT_HOST}"
|
echo " KABOOT_HOST: ${KABOOT_HOST}"
|
||||||
echo " Frontend: http://${KABOOT_HOST}:5173"
|
echo " Frontend: http://${KABOOT_HOST}:5173"
|
||||||
echo " Backend: http://${KABOOT_HOST}:3001"
|
echo " Backend: http://${KABOOT_HOST}:3001"
|
||||||
echo " Authentik: http://${KABOOT_HOST}:9000"
|
echo " Authentik: http://${KABOOT_HOST}:9000"
|
||||||
|
if [ -n "$GEMINI_API_KEY" ]; then
|
||||||
|
echo " System AI: Enabled"
|
||||||
|
else
|
||||||
|
echo " System AI: Disabled (users need own API key)"
|
||||||
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
echo "Authentik admin credentials (save these):"
|
echo "Authentik Admin Credentials (SAVE THESE)"
|
||||||
|
echo "-----------------------------------------"
|
||||||
echo " Username: akadmin"
|
echo " Username: akadmin"
|
||||||
echo " Password: ${AUTHENTIK_BOOTSTRAP_PASSWORD}"
|
echo " Password: ${AUTHENTIK_BOOTSTRAP_PASSWORD}"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Next steps:"
|
echo "Files Created"
|
||||||
|
echo "-------------"
|
||||||
|
echo " .env - Docker Compose environment variables"
|
||||||
|
echo " .env.local - Vite frontend environment variables"
|
||||||
|
echo ""
|
||||||
|
echo "Next Steps"
|
||||||
|
echo "----------"
|
||||||
echo " 1. Run: docker compose up -d"
|
echo " 1. Run: docker compose up -d"
|
||||||
echo " 2. Wait for Authentik to start (~30 seconds)"
|
echo " 2. Wait for Authentik to start (~30 seconds)"
|
||||||
echo " 3. For development: npm run dev -- --host"
|
echo " 3. For development: npm install && npm run dev -- --host"
|
||||||
echo " 4. Access from other devices via http://${KABOOT_HOST}:5173"
|
echo " 4. Access from other devices via http://${KABOOT_HOST}:5173"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Note: Update Authentik redirect URIs to include http://${KABOOT_HOST}:5173/callback"
|
echo "Note: Update Authentik redirect URIs to include http://${KABOOT_HOST}:5173/callback"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue