authorgravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-01-02 01:00:15-08:00
committergravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-01-05 03:50:50-08:00
logdd75657461727cf1146fb33cb1d6f0649c09e9b9
tree5215c462c216a452527df7d84a9a62ae705a9655
parent914005dab4ce28f6ba6f52c236f3c621549630ce
signaturelock-open Commit is signed but in an unrecognized format.

feat: forgejo + snow sign on


10 files changed, 352 insertions(+), 175 deletions(-)

.env.example+1
...@@ -8,6 +8,7 @@ APP_ROOT=./.apps...@@ -8,6 +8,7 @@ APP_ROOT=./.apps
8STORE_ROOT=/Volumes8STORE_ROOT=/Volumes
9CLOVER_ROOT=/Volumes/clover9CLOVER_ROOT=/Volumes/clover
10MEDIA_ROOT=/Volumes/media10MEDIA_ROOT=/Volumes/media
11TORRENT_TEMP=
1112
12MAILER_ADDRESS=smtp.example.com13MAILER_ADDRESS=smtp.example.com
13MAILER_USERNAME=me@paperclover.net14MAILER_USERNAME=me@paperclover.net
compose.yaml+26-15
...@@ -98,7 +98,7 @@ services:...@@ -98,7 +98,7 @@ services:
98 keycloak:98 keycloak:
99 condition: service_healthy99 condition: service_healthy
100 volumes:100 volumes:
101 - "${APP_ROOT}/keycloak/forward-auth:/shared/forward-auth:ro"101 - "${APP_ROOT}/keycloak:/shared:ro"
102 # file manager102 # file manager
103 copyparty: # port 80103 copyparty: # port 80
104 image: copyparty/ac104 image: copyparty/ac
...@@ -146,37 +146,46 @@ services:...@@ -146,37 +146,46 @@ services:
146 # git hosting146 # git hosting
147 forgejo: # port 3000147 forgejo: # port 3000
148 container_name: forgejo148 container_name: forgejo
149 image: code.forgejo.org/forgejo/forgejo:13
150 entrypoint: ["/bin/sh", "/custom/init/entry.sh"]
151 ports:
152 - 22:22
153 - 40244:3000 # port used for forgejo-runner
149 environment:154 environment:
150 USER_UID: "$USER_ID"155 USER_UID: "$USER_ID"
151 USER_GID: "$GROUP_ID"156 USER_GID: "$GROUP_ID"
157 HOME_DOMAIN: "${HOME_DOMAIN}"
152 FORGEJO_CUSTOM: "/custom"158 FORGEJO_CUSTOM: "/custom"
153 FORGEJO__MAILER__SMTP_ADDR: "${MAILER_ADDRESS}"159 MAILER_ADDRESS: "${MAILER_ADDRESS}"
154 FORGEJO__MAILER__USER: "${MAILER_USERNAME}"160 MAILER_USERNAME: "${MAILER_USERNAME}"
155 FORGEJO__MAILER__PASSWD: "${MAILER_PASSWORD}"161 MAILER_PASSWORD: "${MAILER_PASSWORD}"
156 FORGEJO__SERVER__LFS_JWT_SECRET: "${FORGEJO_SERVER_LFS_JWT_SECRET}"162 FORGEJO_SERVER_LFS_JWT_SECRET: "${FORGEJO_SERVER_LFS_JWT_SECRET}"
157 FORGEJO__OAUTH2__JWT_SECRET: "${FORGEJO_OAUTH2_JWT_SECRET}"163 FORGEJO_OAUTH2_JWT_SECRET: "${FORGEJO_OAUTH2_JWT_SECRET}"
158 FORGEJO__SECURITY__SECRET_KEY: "${FORGEJO_SECURITY_SECRET_KEY}"164 FORGEJO_SECURITY_SECRET_KEY: "${FORGEJO_SECURITY_SECRET_KEY}"
159 FORGEJO__SECURITY__INTERNAL_TOKEN: "${FORGEJO_SECURITY_INTERNAL_TOKEN}"165 FORGEJO_SECURITY_INTERNAL_TOKEN: "${FORGEJO_SECURITY_INTERNAL_TOKEN}"
160 image: code.forgejo.org/forgejo/forgejo:13
161 ports:
162 - 22:22
163 - 40244:3000
164 restart: unless-stopped166 restart: unless-stopped
165 volumes:167 volumes:
168 - "${APP_ROOT}/keycloak:/shared-keys:ro"
166 - "${APP_ROOT}/forgejo:/data:rw"169 - "${APP_ROOT}/forgejo:/data:rw"
167 - "/etc/timezone:/etc/timezone:ro"170 - "/etc/timezone:/etc/timezone:ro"
168 - "/etc/localtime:/etc/localtime:ro"171 - "/etc/localtime:/etc/localtime:ro"
169 - ./config/forgejo:/custom:ro172 - ./config/forgejo/public:/custom/public:ro
173 - ./config/forgejo/templates:/custom/templates:ro
170 - ./config/font:/custom/public/assets/font:ro174 - ./config/font:/custom/public/assets/font:ro
175 - ./config/forgejo/init:/custom/init:ro
171 labels:176 labels:
172 net.paperclover.list.name: Clover Git Forge177 net.paperclover.list.name: Clover Git Forge
173 net.paperclover.list.domain: git178 net.paperclover.list.domain: git
174 net.paperclover.list.priority: 105179 net.paperclover.list.priority: 105
175 depends_on:180 depends_on:
181 postgres:
182 condition: service_healthy
183 redis:
184 condition: service_healthy
176 keycloak:185 keycloak:
177 condition: service_healthy186 condition: service_healthy
178 # forgejo-anubis:187 forgejo-anubis:
179 # condition: service_healthy188 condition: service_started
180 forgejo-anubis:189 forgejo-anubis:
181 container_name: forgejo-anubis190 container_name: forgejo-anubis
182 image: ghcr.io/techarohq/anubis:latest191 image: ghcr.io/techarohq/anubis:latest
...@@ -385,6 +394,8 @@ services:...@@ -385,6 +394,8 @@ services:
385 timeout: 5s394 timeout: 5s
386 retries: 5395 retries: 5
387 start_period: 10s396 start_period: 10s
397 ports:
398 - 5432:5432
388 pgadmin: # port 80399 pgadmin: # port 80
389 container_name: pgadmin400 container_name: pgadmin
390 entrypoint: ["/bin/sh", "/init/pgadmin-init.sh"]401 entrypoint: ["/bin/sh", "/init/pgadmin-init.sh"]
config/Caddyfile+3
...@@ -68,6 +68,9 @@ db.{$HOME_DOMAIN} {...@@ -68,6 +68,9 @@ db.{$HOME_DOMAIN} {
68 reverse_proxy "http://clover-source-of-truth"68 reverse_proxy "http://clover-source-of-truth"
69}69}
70git.{$HOME_DOMAIN} {70git.{$HOME_DOMAIN} {
71 handle /user/login {
72 rewrite /user/oauth2/snow
73 }
71 reverse_proxy "http://forgejo-anubis" {74 reverse_proxy "http://forgejo-anubis" {
72 header_up X-Real-Ip {remote_host}75 header_up X-Real-Ip {remote_host}
73 header_up X-Http-Version {http.request.proto}76 header_up X-Http-Version {http.request.proto}
config/forgejo/conf/app.ini deleted-105
...@@ -1,105 +0,0 @@
1APP_NAME="clover's git"
2APP_SLOGAL=and then we knew, just like paper airplanes: that we could fly...
3RUN_MODE=prod
4RUN_USER=git
5WORK_PATH=/data/work
6
7[repository]
8MAX_CREATION_LIMIT=0
9ROOT=/data/git/repositories
10DEFAULT_CLOSE_ISSUES_VIA_COMMITS_IN_ANY_BRANCH=true
11DEFAULT_REPO_UNITS=repo.code,repo.issues,repo.pulls
12DISABLE_STARS=true
13DEFAULT_BRANCH=master
14
15[repository.local]
16LOCAL_COPY_PATH=/data/work/tmp/local-repo
17
18[repository.upload]
19TEMP_PATH=/data/work/uploads
20
21[ui]
22EXPLORE_PAGING_NUM=100
23ISSUE_PAGING_NUM=500
24MEMBERS_PAGING_NUM=100
25THEMES=clover
26DEFAULT_THEME=clover
27
28[server]
29APP_DATA_PATH=/data/work
30DOMAIN=git.paperclover.net
31SSH_DOMAIN=git.paperclover.net
32HTTP_PORT=3000
33ROOT_URL=https://git.paperclover.net/
34DISABLE_SSH=false
35SSH_PORT=22
36SSH_LISTEN_PORT=22
37LFS_START_SERVER=true
38OFFLINE_MODE=true
39LANDING_PAGE=/explore/repos
40
41[database]
42PATH=/data/work/gitea.db
43DB_TYPE=sqlite3
44HOST=localhost:3306
45NAME=gitea
46USER=root
47PASSWD=
48LOG_SQL=false
49SCHEMA=
50SSL_MODE=disable
51
52[indexer]
53ISSUE_INDEXER_PATH=/data/work/indexers/issues.bleve
54
55[session]
56PROVIDER_CONFIG=/data/work/sessions
57PROVIDER=file
58
59[picture]
60AVATAR_UPLOAD_PATH=/data/work/avatars
61REPOSITORY_AVATAR_UPLOAD_PATH=/data/work/repo-avatars
62
63[admin]
64DISABLE_REGULAR_ORG_CREATION=true
65
66[attachment]
67PATH=/data/work/attachments
68
69[log]
70MODE=console
71LEVEL=info
72ROOT_PATH=/data/work/log
73
74[security]
75INSTALL_LOCK=true
76REVERSE_PROXY_LIMIT=1
77REVERSE_PROXY_TRUSTED_PROXIES=*
78PASSWORD_HASH_ALGO=pbkdf2_hi
79
80[service]
81DISABLE_REGISTRATION=false
82REQUIRE_SIGNIN_VIEW=false
83REGISTER_EMAIL_CONFIRM=true
84ENABLE_NOTIFY_MAIL=true
85ALLOW_ONLY_EXTERNAL_REGISTRATION=false
86DEFAULT_KEEP_EMAIL_PRIVATE=false
87DEFAULT_ALLOW_CREATE_ORGANIZATION=true
88DEFAULT_ENABLE_TIMETRACKING=true
89NO_REPLY_ADDRESS=noreply.localhost
90
91[lfs]
92PATH = /data/git/lfs
93
94[mailer]
95ENABLED = true
96FROM=noreply.git@paperclover.net
97PROTOCOL=smtps
98SMTP_PORT=587
99IS_TLS_ENABLED=true
100
101[repository.pull-request]
102DEFAULT_MERGE_STYLE=squash
103
104[repository.signing]
105DEFAULT_TRUST_MODEL=committer
config/forgejo/init/app.ini created+121
...@@ -0,0 +1,121 @@
1APP_NAME="clover's git"
2APP_SLOGAL=and then we knew, just like paper airplanes: that we could fly...
3RUN_MODE=prod
4RUN_USER=git
5WORK_PATH=/data/work
6
7[repository]
8MAX_CREATION_LIMIT=0
9ROOT=/data/git/repositories
10DEFAULT_CLOSE_ISSUES_VIA_COMMITS_IN_ANY_BRANCH=true
11DEFAULT_REPO_UNITS=repo.code,repo.issues,repo.pulls
12DISABLE_STARS=true
13DISABLE_FORKS=true
14DEFAULT_BRANCH=master
15
16[repository.local]
17LOCAL_COPY_PATH=/data/work/tmp/local-repo
18
19[repository.upload]
20TEMP_PATH=/data/work/uploads
21
22[ui]
23EXPLORE_PAGING_NUM=100
24ISSUE_PAGING_NUM=500
25MEMBERS_PAGING_NUM=100
26THEMES=clover
27DEFAULT_THEME=clover
28
29[server]
30APP_DATA_PATH=/data/work
31DOMAIN=git.$HOME_DOMAIN
32SSH_DOMAIN=git.$HOME_DOMAIN
33HTTP_PORT=3000
34ROOT_URL=https://git.$HOME_DOMAIN/
35DISABLE_SSH=false
36SSH_PORT=22
37SSH_LISTEN_PORT=22
38LFS_JWT_SECRET=$FORGEJO_SERVER_LFS_JWT_SECRET
39LFS_START_SERVER=true
40OFFLINE_MODE=true
41LANDING_PAGE=/explore/repos
42
43[database]
44PATH=/data/work/gitea.db
45DB_TYPE=sqlite3
46HOST=localhost:3306
47NAME=gitea
48USER=root
49PASSWD=
50LOG_SQL=false
51SCHEMA=
52SSL_MODE=disable
53
54[indexer]
55ISSUE_INDEXER_PATH=/data/work/indexers/issues.bleve
56
57[session]
58PROVIDER_CONFIG=/data/work/sessions
59PROVIDER=file
60
61[picture]
62AVATAR_UPLOAD_PATH=/data/work/avatars
63REPOSITORY_AVATAR_UPLOAD_PATH=/data/work/repo-avatars
64
65[admin]
66DISABLE_REGULAR_ORG_CREATION=true
67
68[attachment]
69PATH=/data/work/attachments
70
71[log]
72MODE=console
73LEVEL=info
74ROOT_PATH=/data/work/log
75
76[security]
77INSTALL_LOCK=true
78REVERSE_PROXY_LIMIT=1
79REVERSE_PROXY_TRUSTED_PROXIES=*
80PASSWORD_HASH_ALGO=pbkdf2_hi
81SECRET_KEY=$FORGEJO_SECURITY_SECRET_KEY
82INTERNAL_TOKEN=$FORGEJO_SECURITY_INTERNAL_TOKEN
83
84[openid]
85ENABLE_OPENID_SIGNIN=false
86ENABLE_OPENID_SIGNUP=true
87WHITELISTED_URIS=auth.local.test
88
89[service]
90ENABLE_INTERNAL_SIGNIN=false
91DISABLE_REGISTRATION=false
92ALLOW_ONLY_EXTERNAL_REGISTRATION=true
93SHOW_REGISTRATION_BUTTON=false
94REQUIRE_SIGNIN_VIEW=false
95REGISTER_EMAIL_CONFIRM=true
96ENABLE_NOTIFY_MAIL=true
97DEFAULT_KEEP_EMAIL_PRIVATE=false
98DEFAULT_ALLOW_CREATE_ORGANIZATION=true
99DEFAULT_ENABLE_TIMETRACKING=true
100NO_REPLY_ADDRESS=noreply.localhost
101
102[lfs]
103PATH = /data/git/lfs
104
105[mailer]
106ENABLED=false
107FROM=noreply.git@$HOME_DOMAIN
108PROTOCOL=smtps
109SMTP_PORT=587
110SMTP_ADDR=$MAILER_ADDRESS
111USER=$MAILER_USERNAME
112PASSWD=$MAILER_PASSWORD
113
114[repository.pull-request]
115DEFAULT_MERGE_STYLE=squash
116
117[repository.signing]
118DEFAULT_TRUST_MODEL=committer
119
120[oauth2]
121JWT_SECRET=$FORGEJO_OAUTH2_JWT_SECRET
config/forgejo/init/config.sh created+20
...@@ -0,0 +1,20 @@
1#!/bin/sh
2set -e
3
4FORGEJO_OPENID_SECRET="$(cat /shared-keys/forgejo)"
5
6openid_args="--provider=openidConnect \
7--name=snow \
8--key=forgejo \
9--secret=$FORGEJO_OPENID_SECRET \
10--auto-discover-url=https://auth.$HOME_DOMAIN/realms/master/.well-known/openid-configuration \
11--scopes=openid email profile groups"
12
13forgejo migrate
14
15if ! forgejo admin auth add-oauth $openid_args; then
16 id=$(forgejo admin auth list | awk '$2=="snow" {print $1}')
17 if [ -n "$id" ]; then
18 forgejo admin auth update-oauth --id="$id" $openid_args
19 fi
20fi
config/forgejo/init/entry.sh created+14
...@@ -0,0 +1,14 @@
1#!/bin/sh
2set -e
3
4mkdir -p /custom/conf
5envsubst </custom/init/app.ini >/custom/conf/app.ini
6chmod 444 /custom/conf/app.ini
7
8CADDY_IP="$(getent hosts caddy | awk '{print $1}')"
9echo "${CADDY_IP} auth.${HOME_DOMAIN}" >>/etc/hosts
10
11/usr/bin/entrypoint echo meow >/dev/null
12su git -c "bash /custom/init/config.sh"
13
14exec /usr/bin/entrypoint /usr/bin/s6-svscan /etc/s6
config/forgejo/public/assets/css/theme-clover.css+130-52
...@@ -2,32 +2,32 @@...@@ -2,32 +2,32 @@
2@import "theme-forgejo-dark.css" (prefers-color-scheme: dark);2@import "theme-forgejo-dark.css" (prefers-color-scheme: dark);
33
4@font-face {4@font-face {
5 font-family: 'Name Mono';5 font-family: "Name Mono";
6 src: url('../font/ATNameMono-Regular.woff2') format('woff2');6 src: url("../font/nm.woff2") format("woff2");
7 font-weight: 400;7 font-weight: 400;
8 font-style: normal;8 font-style: normal;
9 font-display: swap;9 font-display: swap;
10}10}
1111
12@font-face {12@font-face {
13 font-family: 'Name Mono';13 font-family: "Name Mono";
14 src: url('../font/ATNameMono-Bold.woff2') format('woff2');14 src: url("../font/nmb.woff2") format("woff2");
15 font-weight: 700;15 font-weight: 700;
16 font-style: normal;16 font-style: normal;
17 font-display: swap;17 font-display: swap;
18}18}
1919
20@font-face {20@font-face {
21 font-family: 'Name Mono';21 font-family: "Name Mono";
22 src: url('../font/ATNameMono-Italic.woff2') format('woff2');22 src: url("../font/nmi.woff2") format("woff2");
23 font-weight: 400;23 font-weight: 400;
24 font-style: italic;24 font-style: italic;
25 font-display: swap;25 font-display: swap;
26}26}
2727
28@font-face {28@font-face {
29 font-family: 'Name Sans';29 font-family: "Name Sans";
30 src: url('../font/ATNameSansVariable-Regular.woff2') format('woff2') tech(variations);30 src: url("../font/nsv.woff2") format("woff2") tech(variations);
31 font-weight: 100 900;31 font-weight: 100 900;
32 font-style: normal;32 font-style: normal;
33 font-display: swap;33 font-display: swap;
...@@ -35,8 +35,8 @@...@@ -35,8 +35,8 @@
35}35}
3636
37@font-face {37@font-face {
38 font-family: 'Name Sans';38 font-family: "Name Sans";
39 src: url('../font/ATNameSansVariable-Italic.woff2') format('woff2') tech(variations);39 src: url("../font/nsvi.woff2") format("woff2") tech(variations);
40 font-weight: 100 900;40 font-weight: 100 900;
41 font-style: italic;41 font-style: italic;
42 font-display: swap;42 font-display: swap;
...@@ -44,9 +44,14 @@...@@ -44,9 +44,14 @@
44}44}
4545
46:root {46:root {
47 --fonts-proportional: 'Name Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif !important;47 --fonts-proportional:
48 --fonts-monospace: 'Name Mono', 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace !important;48 "Name Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans",
49 --fonts-emoji: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji' !important;49 Helvetica, Arial, sans-serif !important;
50 --fonts-monospace:
51 "Name Mono", "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas,
52 "Courier New", monospace !important;
53 --fonts-emoji:
54 "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji" !important;
50 --steel-900: oklch(0.15 0.08 320);55 --steel-900: oklch(0.15 0.08 320);
51 --steel-850: oklch(0.18 0.07 320);56 --steel-850: oklch(0.18 0.07 320);
52 --steel-800: oklch(0.21 0.06 320);57 --steel-800: oklch(0.21 0.06 320);
...@@ -65,24 +70,24 @@...@@ -65,24 +70,24 @@
65 --steel-150: oklch(0.90 0.04 320);70 --steel-150: oklch(0.90 0.04 320);
66 --steel-100: oklch(0.95 0.01 320);71 --steel-100: oklch(0.95 0.01 320);
6772
68 --zinc-900: oklch(calc(0.15 * 1.05) calc(0.08/1.5) 320);73 --zinc-900: oklch(calc(0.15 * 1.05) calc(0.08 / 1.5) 320);
69 --zinc-850: oklch(calc(0.18 * 1.05) calc(0.07/1.5) 320);74 --zinc-850: oklch(calc(0.18 * 1.05) calc(0.07 / 1.5) 320);
70 --zinc-800: oklch(calc(0.21 * 1.05) calc(0.06/1.5) 320);75 --zinc-800: oklch(calc(0.21 * 1.05) calc(0.06 / 1.5) 320);
71 --zinc-750: oklch(calc(0.24 * 1.05) calc(0.06/1.5) 320);76 --zinc-750: oklch(calc(0.24 * 1.05) calc(0.06 / 1.5) 320);
72 --zinc-700: oklch(calc(0.27 * 1.05) calc(0.04/1.5) 320);77 --zinc-700: oklch(calc(0.27 * 1.05) calc(0.04 / 1.5) 320);
73 --zinc-650: oklch(calc(0.30 * 1.05) calc(0.05/1.5) 320);78 --zinc-650: oklch(calc(0.30 * 1.05) calc(0.05 / 1.5) 320);
74 --zinc-600: oklch(calc(0.35 * 1.05) calc(0.04/1.5) 320);79 --zinc-600: oklch(calc(0.35 * 1.05) calc(0.04 / 1.5) 320);
75 --zinc-550: oklch(calc(0.40 * 1.05) calc(0.03/1.5) 320);80 --zinc-550: oklch(calc(0.40 * 1.05) calc(0.03 / 1.5) 320);
76 --zinc-500: oklch(calc(0.45 * 1.05) calc(0.02/1.5) 320);81 --zinc-500: oklch(calc(0.45 * 1.05) calc(0.02 / 1.5) 320);
77 --zinc-450: oklch(calc(0.50 * 1.05) calc(0.03/1.5) 320);82 --zinc-450: oklch(calc(0.50 * 1.05) calc(0.03 / 1.5) 320);
78 --zinc-400: oklch(calc(0.55 * 1.05) calc(0.04/1.5) 320);83 --zinc-400: oklch(calc(0.55 * 1.05) calc(0.04 / 1.5) 320);
79 --zinc-350: oklch(calc(0.60 * 1.05) calc(0.04/1.5) 320);84 --zinc-350: oklch(calc(0.60 * 1.05) calc(0.04 / 1.5) 320);
80 --zinc-300: oklch(calc(0.65 * 1.05) calc(0.06/1.5) 320);85 --zinc-300: oklch(calc(0.65 * 1.05) calc(0.06 / 1.5) 320);
81 --zinc-250: oklch(calc(0.70 * 1.05) calc(0.06/1.5) 320);86 --zinc-250: oklch(calc(0.70 * 1.05) calc(0.06 / 1.5) 320);
82 --zinc-200: oklch(calc(0.75 * 1.05) calc(0.07/1.5) 320);87 --zinc-200: oklch(calc(0.75 * 1.05) calc(0.07 / 1.5) 320);
83 --zinc-150: oklch(calc(0.90 * 1.05) calc(0.04/1.5) 320);88 --zinc-150: oklch(calc(0.90 * 1.05) calc(0.04 / 1.5) 320);
84 --zinc-100: oklch(calc(0.95 * 1.05) calc(0.01/1.5) 320);89 --zinc-100: oklch(calc(0.95 * 1.05) calc(0.01 / 1.5) 320);
85 --zinc-50: oklch(calc(0.95 * 1.05) calc(0.01/1.5) 320);90 --zinc-50: oklch(calc(0.95 * 1.05) calc(0.01 / 1.5) 320);
8691
87 --color-primary: #00896e;92 --color-primary: #00896e;
88 --color-primary-contrast: #000;93 --color-primary-contrast: #000;
...@@ -100,27 +105,63 @@...@@ -100,27 +105,63 @@
100 --color-primary-light-5: color-mix(in srgb, var(--color-primary) 50%, black);105 --color-primary-light-5: color-mix(in srgb, var(--color-primary) 50%, black);
101 --color-primary-light-6: color-mix(in srgb, var(--color-primary) 40%, black);106 --color-primary-light-6: color-mix(in srgb, var(--color-primary) 40%, black);
102 --color-primary-light-7: color-mix(in srgb, var(--color-primary) 30%, black);107 --color-primary-light-7: color-mix(in srgb, var(--color-primary) 30%, black);
103 --color-primary-alpha-10: color-mix(in srgb, var(--color-primary) 10%, transparent);108 --color-primary-alpha-10: color-mix(
104 --color-primary-alpha-20: color-mix(in srgb, var(--color-primary) 20%, transparent);109 in srgb,
105 --color-primary-alpha-30: color-mix(in srgb, var(--color-primary) 30%, transparent);110 var(--color-primary) 10%,
106 --color-primary-alpha-40: color-mix(in srgb, var(--color-primary) 40%, transparent);111 transparent
107 --color-primary-alpha-50: color-mix(in srgb, var(--color-primary) 50%, transparent);112 );
108 --color-primary-alpha-60: color-mix(in srgb, var(--color-primary) 60%, transparent);113 --color-primary-alpha-20: color-mix(
109 --color-primary-alpha-70: color-mix(in srgb, var(--color-primary) 70%, transparent);114 in srgb,
110 --color-primary-alpha-80: color-mix(in srgb, var(--color-primary) 80%, transparent);115 var(--color-primary) 20%,
111 --color-primary-alpha-90: color-mix(in srgb, var(--color-primary) 90%, transparent);116 transparent
117 );
118 --color-primary-alpha-30: color-mix(
119 in srgb,
120 var(--color-primary) 30%,
121 transparent
122 );
123 --color-primary-alpha-40: color-mix(
124 in srgb,
125 var(--color-primary) 40%,
126 transparent
127 );
128 --color-primary-alpha-50: color-mix(
129 in srgb,
130 var(--color-primary) 50%,
131 transparent
132 );
133 --color-primary-alpha-60: color-mix(
134 in srgb,
135 var(--color-primary) 60%,
136 transparent
137 );
138 --color-primary-alpha-70: color-mix(
139 in srgb,
140 var(--color-primary) 70%,
141 transparent
142 );
143 --color-primary-alpha-80: color-mix(
144 in srgb,
145 var(--color-primary) 80%,
146 transparent
147 );
148 --color-primary-alpha-90: color-mix(
149 in srgb,
150 var(--color-primary) 90%,
151 transparent
152 );
112}153}
113154
114@media (prefers-color-scheme: dark) {155@media (prefers-color-scheme: dark) {
115 :root {156 :root {
116 --is-dark-theme: true;157 --is-dark-theme: true;
117 --color-primary: #45F0CE;158 --color-primary: #45f0ce;
118 }159 }
119}160}
120161
121.warning {162.warning {
122 --color-primary: #c35b06;163 --color-primary: #c35b06;
123 @media (prefers-color-scheme:dark) {164 @media (prefers-color-scheme: dark) {
124 --color-primary: #ff9843;165 --color-primary: #ff9843;
125 }166 }
126 --color-primary-contrast: #000;167 --color-primary-contrast: #000;
...@@ -138,13 +179,50 @@...@@ -138,13 +179,50 @@
138 --color-primary-light-5: color-mix(in srgb, var(--color-primary) 50%, black);179 --color-primary-light-5: color-mix(in srgb, var(--color-primary) 50%, black);
139 --color-primary-light-6: color-mix(in srgb, var(--color-primary) 40%, black);180 --color-primary-light-6: color-mix(in srgb, var(--color-primary) 40%, black);
140 --color-primary-light-7: color-mix(in srgb, var(--color-primary) 30%, black);181 --color-primary-light-7: color-mix(in srgb, var(--color-primary) 30%, black);
141 --color-primary-alpha-10: color-mix(in srgb, var(--color-primary) 10%, transparent);
142 --color-primary-alpha-20: color-mix(in srgb, var(--color-primary) 20%, transparent);
143 --color-primary-alpha-30: color-mix(in srgb, var(--color-primary) 30%, transparent);
144 --color-primary-alpha-40: color-mix(in srgb, var(--color-primary) 40%, transparent);
145 --color-primary-alpha-50: color-mix(in srgb, var(--color-primary) 50%, transparent);
146 --color-primary-alpha-60: color-mix(in srgb, var(--color-primary) 60%, transparent);
147 --color-primary-alpha-70: color-mix(in srgb, var(--color-primary) 70%, transparent);
148 --color-primary-alpha-80: color-mix(in srgb, var(--color-primary) 80%, transparent);
149 --color-primary-alpha-90: color-mix(in srgb, var(--color-primary) 90%, transparent);
150}
\ No newline at end of file
182 --color-primary-alpha-10: color-mix(
183 in srgb,
184 var(--color-primary) 10%,
185 transparent
186 );
187 --color-primary-alpha-20: color-mix(
188 in srgb,
189 var(--color-primary) 20%,
190 transparent
191 );
192 --color-primary-alpha-30: color-mix(
193 in srgb,
194 var(--color-primary) 30%,
195 transparent
196 );
197 --color-primary-alpha-40: color-mix(
198 in srgb,
199 var(--color-primary) 40%,
200 transparent
201 );
202 --color-primary-alpha-50: color-mix(
203 in srgb,
204 var(--color-primary) 50%,
205 transparent
206 );
207 --color-primary-alpha-60: color-mix(
208 in srgb,
209 var(--color-primary) 60%,
210 transparent
211 );
212 --color-primary-alpha-70: color-mix(
213 in srgb,
214 var(--color-primary) 70%,
215 transparent
216 );
217 --color-primary-alpha-80: color-mix(
218 in srgb,
219 var(--color-primary) 80%,
220 transparent
221 );
222 --color-primary-alpha-90: color-mix(
223 in srgb,
224 var(--color-primary) 90%,
225 transparent
226 );
227}
228
config/forgejo/templates/.gitignore
config/keycloak/init.py+37-3
...@@ -126,6 +126,42 @@ def configure():...@@ -126,6 +126,42 @@ def configure():
126 else:126 else:
127 logger.info(f"Group {group_name} already exists, skipping")127 logger.info(f"Group {group_name} already exists, skipping")
128128
129 Path("/shared").mkdir(parents=True, exist_ok=True)
130
131 # forgejo
132 client_id = kc_admin.create_client(
133 {
134 "protocol": "openid-connect",
135 "clientId": "forgejo",
136 "name": "Forgejo",
137 "description": "",
138 "publicClient": False,
139 "authorizationServicesEnabled": False,
140 "serviceAccountsEnabled": False,
141 "implicitFlowEnabled": False,
142 "directAccessGrantsEnabled": False,
143 "standardFlowEnabled": True,
144 "frontchannelLogout": True,
145 "attributes": {
146 "saml_idp_initiated_sso_url_name": "",
147 "standard.token.exchange.enabled": False,
148 "oauth2.device.authorization.grant.enabled": False,
149 "oidc.ciba.grant.enabled": False,
150 "pkce.code.challenge.method": "",
151 "dpop.bound.access.tokens": "false",
152 "post.logout.redirect.uris": "*",
153 },
154 "alwaysDisplayInConsole": False,
155 "rootUrl": "",
156 "baseUrl": "",
157 "redirectUris": ["*"],
158 },
159 skip_exists=True,
160 )
161 client_data = kc_admin.get_client(client_id)
162 _ = Path("/shared/forgejo").write_text(client_data["secret"])
163
164 # forward auth
129 client_id = kc_admin.create_client(165 client_id = kc_admin.create_client(
130 {166 {
131 "protocol": "openid-connect",167 "protocol": "openid-connect",
...@@ -156,9 +192,7 @@ def configure():...@@ -156,9 +192,7 @@ def configure():
156 skip_exists=True,192 skip_exists=True,
157 )193 )
158 client_data = kc_admin.get_client(client_id)194 client_data = kc_admin.get_client(client_id)
159 fw_secret_path = Path("/shared/forward-auth")195 _ = Path("/shared/forward-auth").write_text(client_data["secret"])
160 fw_secret_path.parent.mkdir(parents=True, exist_ok=True)
161 _ = fw_secret_path.write_text(client_data["secret"])
162196
163197
164def main():198def main():