Changeset 5f483e3 in Klonkt
- Timestamp:
- 06/27/2026 03:01:13 PM (2 months ago)
- Branches:
- main
- Children:
- 3746f6a
- Parents:
- 98fe58a
- Files:
-
- 4 deleted
- 6 edited
-
.env.example (modified) (1 diff)
-
deploy/post-receive (modified) (1 diff)
-
deploy/verify.ps1 (deleted)
-
package.json (modified) (1 diff)
-
src/config/database.js (modified) (3 diffs)
-
src/routes/notifications.js (deleted)
-
src/services/NotificationService.js (deleted)
-
src/services/i18n.js (modified) (27 diffs)
-
src/views/pages/auth-login.ejs (modified) (3 diffs)
-
src/views/pages/notifications.ejs (deleted)
Legend:
- Unmodified
- Added
- Removed
-
.env.example
r98fe58a r5f483e3 27 27 # `npm run reset-admin` on the server. 28 28 29 # ── Google login for LISTENERS (optional) ───────────────────────────30 # Want listeners to sign in with Google to comment? Create your OWN Google OAuth31 # client (Google Cloud Console -> Credentials -> OAuth client ID -> "Web32 # application") and fill it in below. Your own client = your own Google Cloud33 # project; this site isn't centrally tied to anything. Not set? Then there's34 # simply no Google button. Google login NEVER grants admin rights (commenting only).35 # GOOGLE_REDIRECT_URI = <your domain>/auth/google/callback (set it exactly in the client)36 GOOGLE_CLIENT_ID=37 GOOGLE_CLIENT_SECRET=38 GOOGLE_REDIRECT_URI=https://example.com/auth/google/callback39 40 29 # ── Email (optional) — for "forgot password" reset links ──────────── 41 30 # Not set? Then reset only works via `npm run reset-admin` on the server. -
deploy/post-receive
r98fe58a r5f483e3 35 35 fi 36 36 37 # 4. pm2 reload — proces heet "prutcms" (legacy naam)38 pm2 reload prutcms 2>/dev/null || pm2 reload prutfolio2>/dev/null || true37 # 4. pm2 reload — process is named "klonkt" 38 pm2 reload klonkt 2>/dev/null || true 39 39 40 40 echo ">>> Done. App-files in $DEPLOY ongemoeid (.env, node_modules, storage)." -
package.json
r98fe58a r5f483e3 32 32 "nodemailer": "^6.9.15", 33 33 "sanitize-html": "^2.17.3", 34 "uuid": "^9.0.1", 35 "ws": "^8.18.0" 34 "uuid": "^9.0.1" 36 35 }, 37 36 "engines": { -
src/config/database.js
r98fe58a r5f483e3 163 163 `); 164 164 165 // ── Circles (federation) ────────────────────────────────────166 // Decentralised, asymmetric connections between solo instances.167 db.exec(`168 CREATE TABLE IF NOT EXISTS circle_links (169 id TEXT PRIMARY KEY,170 local_site_id TEXT NOT NULL,171 remote_url TEXT NOT NULL,172 remote_actor_id TEXT,173 label TEXT,174 status TEXT DEFAULT 'active',175 added_at DATETIME DEFAULT CURRENT_TIMESTAMP,176 last_synced DATETIME,177 last_error TEXT,178 UNIQUE(local_site_id, remote_url),179 FOREIGN KEY (local_site_id) REFERENCES sites(id)180 );181 CREATE TABLE IF NOT EXISTS remote_actors (182 id TEXT PRIMARY KEY,183 url TEXT UNIQUE NOT NULL,184 name TEXT,185 summary TEXT,186 avatar TEXT,187 public_key TEXT NOT NULL,188 fetched_at DATETIME DEFAULT CURRENT_TIMESTAMP189 );190 CREATE TABLE IF NOT EXISTS remote_posts (191 id TEXT PRIMARY KEY,192 actor_id TEXT NOT NULL,193 published DATETIME,194 title TEXT,195 summary TEXT,196 url TEXT,197 media_json TEXT,198 raw_json TEXT,199 fetched_at DATETIME DEFAULT CURRENT_TIMESTAMP,200 FOREIGN KEY (actor_id) REFERENCES remote_actors(id)201 );202 `);203 204 // Tags from the original post — shown in the circle feed (comma-separated string).205 ensureColumn('remote_posts', 'tags', 'TEXT');206 207 165 // Newsletter / mailing list (premium). Subscribers per site; double opt-in when SMTP 208 166 // is configured (status 'pending' until confirmed), otherwise single opt-in ('confirmed'). … … 252 210 `); 253 211 254 // Notifications: someone replies to your comment / post, or likes your post. Snapshots255 // of name/title so the list can be shown cheaply without joins.256 // NB: deliberately named 'user_notifications' — some older DBs still have a stale,257 // unused 'notifications' table with a different schema (no read column).258 db.exec(`259 CREATE TABLE IF NOT EXISTS user_notifications (260 id TEXT PRIMARY KEY,261 user_id TEXT NOT NULL,262 type TEXT NOT NULL,263 actor_id TEXT,264 actor_name TEXT,265 post_slug TEXT,266 post_title TEXT,267 url TEXT,268 read INTEGER DEFAULT 0,269 created_at DATETIME DEFAULT CURRENT_TIMESTAMP270 );271 `);272 // Older DBs may have a user_notifications table predating these columns — add273 // them before the index (which references `read`), else boot crashes.274 ensureColumn('user_notifications', 'type', 'TEXT');275 ensureColumn('user_notifications', 'actor_id', 'TEXT');276 ensureColumn('user_notifications', 'actor_name', 'TEXT');277 ensureColumn('user_notifications', 'post_slug', 'TEXT');278 ensureColumn('user_notifications', 'post_title', 'TEXT');279 ensureColumn('user_notifications', 'url', 'TEXT');280 ensureColumn('user_notifications', 'read', 'INTEGER DEFAULT 0');281 db.exec('CREATE INDEX IF NOT EXISTS idx_unotif_user ON user_notifications(user_id, read, created_at);');282 283 212 // Link-in-bio click statistics (premium #6). One counter per (site, url); the 284 213 // link-in-bio page links via /links/go/:i which counts the click and redirects. … … 293 222 `); 294 223 295 // Likes / favourites: a logged-in user can like a post. The set of296 // posts a user liked = their favourites (/favorieten page). One row297 // per (post, user); unique so that liking is idempotent.298 db.exec(`299 CREATE TABLE IF NOT EXISTS post_likes (300 post_id TEXT NOT NULL,301 user_id TEXT NOT NULL,302 created_at DATETIME DEFAULT CURRENT_TIMESTAMP,303 PRIMARY KEY (post_id, user_id)304 );305 CREATE INDEX IF NOT EXISTS idx_post_likes_user ON post_likes(user_id, created_at);306 CREATE INDEX IF NOT EXISTS idx_post_likes_post ON post_likes(post_id);307 `);308 224 309 225 // ── ActivityPub (fediverse bridge) ────────────────────────── -
src/services/i18n.js
r98fe58a r5f483e3 69 69 'admin.b_makesite': '🎨 Maak je site aan', 'admin.b_circle': '🔗 Cirkel', 'admin.b_stats': '📊 Statistieken', 70 70 'admin.b_newsletter': '✉️ Nieuwsbrief', 'admin.b_perskit': '📰 Perskit', 'admin.b_downloads': '⬇ Downloads', 71 'admin.b_linkbio': '🔗 Link-in-bio', 'admin.b_agenda': '📅 Agenda', 'admin.b_google': '🔑 Google',71 'admin.b_linkbio': '🔗 Link-in-bio', 'admin.b_agenda': '📅 Agenda', 72 72 'admin.b_updates': '🔄 Updates', 'admin.b_help': '📖 Handleiding', 'admin.b_fediverse': 'Mijn reacties', 73 73 'admin.st_users': 'Gebruikers', 'admin.st_sites': 'Sites', 'admin.st_posts': 'Posts', 'admin.st_published': 'Gepubliceerd', … … 87 87 'auth.password': 'Wachtwoord', 88 88 'auth.forgot': 'Wachtwoord vergeten?', 89 'auth.google_btn': 'Inloggen met Google',90 89 'auth.public_sub': 'Log in om te reageren en je favorieten te bewaren.', 91 90 'auth.admin_box_q': 'Beheerder?', 92 91 'auth.admin_box_sub': 'Log in met gebruikersnaam & wachtwoord', 93 'auth.google_unavail': 'Inloggen met Google is op deze site nog niet ingesteld.',94 92 'auth.create_admin': 'Beheerder aanmaken', 95 93 'auth.reg_intro': 'Eerste keer opzetten — maak je beheerdersaccount aan. Dit kan maar één keer.', … … 138 136 'aset.solo': 'Solo', 139 137 'aset.solo_title': 'één site (de jouwe).', 140 'aset.solo_desc': 'Geen gebruikers-directory, geen site-wissel. Bezoekers kunnen wel met Google inloggen om te reageren.', 141 'aset.hub': 'Hub', 142 'aset.hub_title': 'bedrijfssite met', 138 'aset.solo_desc': 'Geen gebruikers-directory, geen site-wissel.', 143 139 'aset.premium_badge': 'premium', 144 'aset.hub_desc': 'Jij (admin) wijst gebruikers een eigen Klonkt Hub toe. Gesloten cirkel: geen open registratie.',145 'aset.hub_locked_note': 'Vereist premium — koppel Patreon in deze pagina.',146 140 'aset.circle': 'Cirkels', 147 141 'aset.circle_title': 'solo + federatie.', 148 142 'aset.circle_desc': 'Eén eigen site die de publieke posts van andere Klonkt-sites toont. Asymmetrisch: jij bepaalt wie in jouw cirkel zit.', 149 143 'aset.save': 'Opslaan', 150 'aset.hub_home': 'Hub-hoofdpagina',151 'aset.hub_home_help_1': 'De openbare hub-pagina',152 'aset.hub_home_help_2': 'is generiek — van geen enkele gebruiker. Hier stel je de naam en intro in. Jouw eigen Klonkt Hub blijft los bestaan onder',153 144 'aset.name': 'Naam', 154 145 'aset.name_ph': 'bijv. Studio Noord', … … 181 172 'aset.patreon_not_connected': 'Nog niet gekoppeld.', 182 173 'aset.patreon_connect': 'Koppel Patreon', 183 'aset.google_login': 'Google-login (bezoekers)',184 'aset.google_login_help': 'Laat bezoekers met Google inloggen om te reageren — met je eigen Google Cloud-client.',185 174 'aset.status_set': 'Status: ingesteld', 186 175 'aset.not_set_yet': 'Nog niet ingesteld.', 187 'aset.google_login_setup': 'Google-login instellen',188 176 'aset.newsletter': 'Nieuwsbrief', 189 177 'aset.newsletter_help_1': 'Toon een', … … 254 242 'asite.moderation_moderate': 'Modereren (eerst in de wachtrij)', 255 243 'asite.enable_audio': 'Audiospeler + embeds inschakelen', 256 'asite.enable_prutter': 'Prutter (DM’s tussen leden) inschakelen',257 'asite.enable_prutter_hint': '— Hub-functie, premium',258 244 'asite.links': 'Social / streaming-links', 259 245 'asite.links_hint': 'Getoond als merk-iconen op de profielkop. Voeg er zoveel toe als je wilt.', … … 322 308 'aseo.verify_yandex': 'Yandex', 323 309 'aseo.save': 'SEO opslaan', 324 'agoog.title': 'Google-login',325 'agoog.intro': 'Hiermee kunnen bezoekers met hun <strong>Google-account</strong> inloggen om te reageren. Je stelt dit één keer in met je eigen (gratis) Google-account — zo\'n 5 minuten, geen creditcard of betaalde dienst nodig.',326 'agoog.g1': 'Open de Google Cloud Console en log in. Maak bovenaan een <strong>nieuw project</strong> (Project selecteren → Nieuw project), geef het een naam en klik op <strong>Maken</strong>.',327 'agoog.g2': 'Ga in het menu links naar <strong>APIs en services → OAuth-toestemmingsscherm</strong>. Kies <strong>Extern</strong>, vul de app-naam + je e-mail in en sla op. Vraagt het systeem om testgebruikers? Voeg dan jezelf toe.',328 'agoog.g3': 'Ga naar <strong>APIs en services → Inloggegevens → Inloggegevens maken → OAuth-client-ID</strong> en kies als type <strong>Webapplicatie</strong>.',329 'agoog.g4': 'Plak bij <strong>Geautoriseerde omleidings-URI\'s</strong> exact dit adres en klik op <strong>Maken</strong>:',330 'agoog.g5': 'Google toont nu een <strong>Client-ID</strong> en <strong>Client-secret</strong>. Kopieer die naar de velden hieronder en klik op <strong>Opslaan</strong>. Klaar!',331 'agoog.copy': 'Kopieer',332 'agoog.copied': 'Gekopieerd ✓',333 'agoog.warn_short': 'Let op: moet <strong>exact</strong> kloppen — met <code>https://</code>, het juiste domein, en <strong>geen</strong> schuine streep aan het eind. Anders krijg je "Error 400: redirect_uri_mismatch".',334 'agoog.need_baseurl': 'Stel eerst <code>PUBLIC_BASE_URL</code> in (de publieke URL van je site) — daar wordt dit adres van afgeleid.',335 'agoog.no_api_note': '<strong>Tip:</strong> je hoeft géén API\'s aan te zetten (geen "People API" o.i.d.). Alleen het toestemmingsscherm + de OAuth-client zijn nodig.',336 'agoog.back': 'Instellingen',337 'agoog.card_title': 'Google-login (bezoekers)',338 'agoog.card_help_pre': 'Laat bezoekers met Google inloggen om te reageren — met je',339 'agoog.card_help_own': 'eigen',340 'agoog.card_help_mid': 'Google Cloud-client. Maak er een aan op',341 'agoog.card_help_post': '(OAuth client-ID, type "Web application").',342 'agoog.status_set': 'Status: ingesteld ✓',343 'agoog.status_unset': 'Nog niet ingesteld.',344 'agoog.guide_summary': 'Hoe stel ik dit in? (stap voor stap)',345 'agoog.step1_pre': 'Ga naar de',346 'agoog.step1_post': 'en maak (of kies) een project.',347 'agoog.step2_usertype': 'User type',348 'agoog.step2_scopes_pre': 'Voeg de scopes',349 'agoog.step2_scopes_and': 'en',350 'agoog.step2_scopes_post': 'toe.',351 'agoog.step2_testmode': '(In testmodus: voeg jezelf toe als testgebruiker.)',352 'agoog.step3_type': 'type',353 'agoog.step4_pre': 'Bij',354 'agoog.step4_post': ': plak de redirect-URI hieronder (moet exact matchen).',355 'agoog.step5_pre': 'Kopieer de',356 'agoog.step5_post': 'die je krijgt naar de velden hieronder en klik Opslaan.',357 'agoog.note_label': 'Let op:',358 'agoog.note_pre': 'je hoeft',359 'agoog.note_noapi': 'geen API\'s aan te zetten',360 'agoog.note_mid': '— "Google Cloud APIs", People API e.d. zijn',361 'agoog.note_not': 'niet',362 'agoog.note_post': 'nodig. Inloggen werkt via OpenID Connect (alleen het toestemmingsscherm + de OAuth-client).',363 'agoog.redirect_label': 'Redirect-URI — kopieer deze en plak \'m in Google',364 'agoog.rstep1_pre': 'Ga naar',365 'agoog.rstep2': 'Open jouw OAuth client-ID (type "Web application").',366 'agoog.rstep3_pre': 'Onder',367 'agoog.rstep3_mid': 'klik',368 'agoog.rstep3_post': 'en plak de regel hierboven.',369 'agoog.rstep4_pre': 'Klik',370 'agoog.rstep4_post': 'en wacht ~1 minuut.',371 'agoog.warn_pre': 'Moet',372 'agoog.warn_exact': 'exact',373 'agoog.warn_mid1': 'kloppen:',374 'agoog.warn_nohttp': 'geen',375 'agoog.warn_mid2': ', juiste domein, en',376 'agoog.warn_noslash': 'geen',377 'agoog.warn_mid3': 'schuine streep aan het eind. Anders krijg je',378 'agoog.warn_error': '"Error 400: redirect_uri_mismatch"',379 'agoog.set_baseurl_pre': 'Stel eerst',380 'agoog.set_baseurl_post': 'in — daar wordt de redirect-URI van afgeleid.',381 'agoog.client_id': 'Client ID',382 'agoog.client_secret': 'Client Secret',383 'agoog.client_secret_set': 'ingesteld; leeg laten = ongewijzigd',384 'agoog.secret_ph_set': '•••••••• (ingesteld)',385 'agoog.save': 'Opslaan',386 'agoog.disconnect': 'Loskoppelen',387 'agoog.premium_locked': 'Premium-laag staat aan zonder Patreon — de Google-knop blijft verborgen tot premium ontgrendeld is.',388 310 'aaud.title': 'Audio tracks', 389 311 'aaud.tagline_pre': 'MP3’s op site-niveau. Gebruik', … … 696 618 'ahelp.s_premium_h': 'Premium / Patreon', 697 619 'ahelp.s_premium_b': 'Premium-functies (Statistieken, Agenda, Downloads, Perskit, Nieuwsbrief, Link-in-bio, Embed) ontgrendel je in Beheer → Instellingen door Patreon te koppelen ($16 lifetime). Updates en de kernapp blijven altijd gratis.', 698 'ahelp.s_google_h': 'Google-login (bezoekers)',699 'ahelp.s_google_b': 'Beheer → Instellingen → <strong>Google</strong>. Optioneel: laat bezoekers/fans met Google inloggen om te reageren. Jij beheert met je wachtwoord — Google geeft nooit beheerrechten. Vul je eigen Google-client-gegevens in (per site).',700 620 'ahelp.s_updates_h': 'Updates', 701 621 'ahelp.s_updates_b': 'Beheer → <strong>Updates</strong> (alleen god) toont de huidige versie en of er een nieuwere is. Met "Nu bijwerken" haal je de laatste versie binnen.', … … 836 756 'acct.password_min': '(min 8 tekens)', 837 757 'acct.password_confirm': 'Bevestig nieuw wachtwoord', 838 'acct.google_login': 'Inloggen met Google',839 'acct.google_linked': '✓ Je Google-account is gekoppeld — je kunt ook met Google inloggen.',840 'acct.google_unlink': 'Google ontkoppelen',841 'acct.google_link_hint': 'Koppel je Google-account zodat je voortaan ook met één klik via Google kunt inloggen (naast je wachtwoord).',842 'acct.google_link': 'Koppel Google-account',843 758 'acct.login': 'Inloggen', 844 'acct.login_google_only': ' Je bent ingelogd via Google ({email}). Er is geen apart wachtwoord.',759 'acct.login_google_only': 'Dit account heeft geen wachtwoord ({email}). Gebruik "Wachtwoord vergeten" om er een in te stellen.', 845 760 'news.this_artist': 'deze artiest', 846 761 'news.form_title': 'Blijf op de hoogte', … … 938 853 'adir.page_info': 'Pagina {page} van {pages}', 939 854 'adir.next': 'Volgende →', 940 'glog.admin_title': 'Dit is een beheerders-account',941 'glog.admin_body': 'Je logde in met Google, maar dit e-mailadres hoort bij de beheerder van deze site. Inloggen met Google is alleen voor luisteraars/fans — beheerders gebruiken altijd hun wachtwoord (zo kan een Google-login nooit per ongeluk beheerrechten geven).',942 'glog.admin_li1': '<strong>Ben je de beheerder?</strong> <a href="/auth/admin">Log in met je gebruikersnaam + wachtwoord</a>.',943 'glog.admin_li2': '<strong>Wil je voortaan met Google inloggen?</strong> Log eerst in met wachtwoord en <strong>koppel je Google-account</strong> onder Account → daarna werkt Google-login ook voor jou.',944 'glog.admin_li3': '<strong>Wil je als fan inloggen?</strong> Gebruik een <strong>ander Google-account</strong> (niet je beheerdersadres).',945 'glog.session_title': 'Login afgebroken',946 'glog.session_body': 'De Google-login is afgebroken of de sessie was verlopen. Probeer het gewoon opnieuw.',947 'glog.email_title': 'Geen geverifieerd e-mailadres',948 'glog.email_body': 'Je Google-account heeft geen geverifieerd e-mailadres. Verifieer je adres bij Google.',949 'glog.linked_title': 'Adres al gekoppeld',950 'glog.linked_body': 'Dit e-mailadres is al aan een ander Google-account gekoppeld. Gebruik dat account, of neem contact op met de beheerder.',951 'glog.unavailable_title': 'Google-login niet beschikbaar',952 'glog.unavailable_body': 'Inloggen met Google is op deze site (nog) niet ingesteld.',953 'glog.failed_title': 'Google-login mislukt',954 'glog.failed_body': 'Er ging iets mis bij het inloggen met Google. Probeer het opnieuw.',955 855 'pusr.post_one': 'post', 956 856 'pusr.post_many': 'posts', … … 1088 988 'admin.b_makesite': '🎨 Create your site', 'admin.b_circle': '🔗 Circle', 'admin.b_stats': '📊 Statistics', 1089 989 'admin.b_newsletter': '✉️ Newsletter', 'admin.b_perskit': '📰 Press kit', 'admin.b_downloads': '⬇ Downloads', 1090 'admin.b_linkbio': '🔗 Link-in-bio', 'admin.b_agenda': '📅 Agenda', 'admin.b_google': '🔑 Google',990 'admin.b_linkbio': '🔗 Link-in-bio', 'admin.b_agenda': '📅 Agenda', 1091 991 'admin.b_updates': '🔄 Updates', 'admin.b_help': '📖 Manual', 'admin.b_fediverse': 'My replies', 1092 992 'admin.st_users': 'Users', 'admin.st_sites': 'Sites', 'admin.st_posts': 'Posts', 'admin.st_published': 'Published', … … 1104 1004 'auth.password': 'Password', 1105 1005 'auth.forgot': 'Forgot password?', 1106 'auth.google_btn': 'Sign in with Google',1107 1006 'auth.public_sub': 'Log in to comment and save your favorites.', 1108 1007 'auth.admin_box_q': 'Admin?', 1109 1008 'auth.admin_box_sub': 'Log in with username & password', 1110 'auth.google_unavail': 'Google sign-in isn’t set up on this site yet.',1111 1009 'auth.create_admin': 'Create admin', 1112 1010 'auth.reg_intro': 'First-time setup — create your admin account. This can only be done once.', … … 1152 1050 'aset.solo': 'Solo', 1153 1051 'aset.solo_title': 'one site (yours).', 1154 'aset.solo_desc': 'No user directory, no site switching. Visitors can still sign in with Google to comment.', 1155 'aset.hub': 'Hub', 1156 'aset.hub_title': 'company site with', 1052 'aset.solo_desc': 'No user directory, no site switching.', 1157 1053 'aset.premium_badge': 'premium', 1158 'aset.hub_desc': 'You (the admin) assign users their own Klonkt Hub. Closed circle: no open registration.',1159 'aset.hub_locked_note': 'Requires premium — connect Patreon on this page.',1160 1054 'aset.circle': 'Circles', 1161 1055 'aset.circle_title': 'solo + federation.', 1162 1056 'aset.circle_desc': 'A single site of your own that shows the public posts of other Klonkt sites. Asymmetric: you decide who is in your circle.', 1163 1057 'aset.save': 'Save', 1164 'aset.hub_home': 'Hub home page',1165 'aset.hub_home_help_1': 'The public hub page',1166 'aset.hub_home_help_2': 'is generic — it belongs to no single user. Here you set the name and intro. Your own Klonkt Hub stays separate under',1167 1058 'aset.name': 'Name', 1168 1059 'aset.name_ph': 'e.g. Studio Noord', … … 1195 1086 'aset.patreon_not_connected': 'Not connected yet.', 1196 1087 'aset.patreon_connect': 'Connect Patreon', 1197 'aset.google_login': 'Google login (visitors)',1198 'aset.google_login_help': 'Let visitors sign in with Google to comment — using your own Google Cloud client.',1199 1088 'aset.status_set': 'Status: configured', 1200 1089 'aset.not_set_yet': 'Not configured yet.', 1201 'aset.google_login_setup': 'Set up Google login',1202 1090 'aset.newsletter': 'Newsletter', 1203 1091 'aset.newsletter_help_1': 'Show a', … … 1268 1156 'asite.moderation_moderate': 'Moderate (queue first)', 1269 1157 'asite.enable_audio': 'Enable audio player + embeds', 1270 'asite.enable_prutter': 'Enable Prutter (DMs between members)',1271 'asite.enable_prutter_hint': '— Hub feature, premium',1272 1158 'asite.links': 'Social / streaming links', 1273 1159 'asite.links_hint': 'Shown as brand icons in the profile header. Add as many as you like.', … … 1336 1222 'aseo.verify_yandex': 'Yandex', 1337 1223 'aseo.save': 'Save SEO', 1338 'agoog.title': 'Google login',1339 'agoog.intro': 'This lets visitors sign in with their <strong>Google account</strong> to comment. You set it up once with your own (free) Google account — about 5 minutes, no credit card or paid service needed.',1340 'agoog.g1': 'Open the Google Cloud Console and sign in. At the top, create a <strong>new project</strong> (Select project → New project), give it a name and click <strong>Create</strong>.',1341 'agoog.g2': 'In the left menu go to <strong>APIs & Services → OAuth consent screen</strong>. Choose <strong>External</strong>, fill in the app name + your email and save. If it asks for test users, add yourself.',1342 'agoog.g3': 'Go to <strong>APIs & Services → Credentials → Create credentials → OAuth client ID</strong> and choose type <strong>Web application</strong>.',1343 'agoog.g4': 'Under <strong>Authorized redirect URIs</strong> paste exactly this address and click <strong>Create</strong>:',1344 'agoog.g5': 'Google now shows a <strong>Client ID</strong> and <strong>Client secret</strong>. Copy them into the fields below and click <strong>Save</strong>. Done!',1345 'agoog.copy': 'Copy',1346 'agoog.copied': 'Copied ✓',1347 'agoog.warn_short': 'Note: it must match <strong>exactly</strong> — with <code>https://</code>, the correct domain, and <strong>no</strong> trailing slash. Otherwise you get "Error 400: redirect_uri_mismatch".',1348 'agoog.need_baseurl': 'First set <code>PUBLIC_BASE_URL</code> (the public URL of your site) — this address is derived from it.',1349 'agoog.no_api_note': '<strong>Tip:</strong> you do not need to enable any APIs (no "People API" etc.). Only the consent screen + the OAuth client are needed.',1350 'agoog.back': 'Settings',1351 'agoog.card_title': 'Google login (visitors)',1352 'agoog.card_help_pre': 'Let visitors log in with Google to comment — using your',1353 'agoog.card_help_own': 'own',1354 'agoog.card_help_mid': 'Google Cloud client. Create one at',1355 'agoog.card_help_post': '(OAuth client ID, type "Web application").',1356 'agoog.status_set': 'Status: configured ✓',1357 'agoog.status_unset': 'Not configured yet.',1358 'agoog.guide_summary': 'How do I set this up? (step by step)',1359 'agoog.step1_pre': 'Go to the',1360 'agoog.step1_post': 'and create (or pick) a project.',1361 'agoog.step2_usertype': 'User type',1362 'agoog.step2_scopes_pre': 'Add the scopes',1363 'agoog.step2_scopes_and': 'and',1364 'agoog.step2_scopes_post': '.',1365 'agoog.step2_testmode': '(In testing mode: add yourself as a test user.)',1366 'agoog.step3_type': 'type',1367 'agoog.step4_pre': 'Under',1368 'agoog.step4_post': ': paste the redirect URI below (it must match exactly).',1369 'agoog.step5_pre': 'Copy the',1370 'agoog.step5_post': 'you receive into the fields below and click Save.',1371 'agoog.note_label': 'Note:',1372 'agoog.note_pre': 'you do',1373 'agoog.note_noapi': 'not need to enable any APIs',1374 'agoog.note_mid': '— "Google Cloud APIs", People API and the like are',1375 'agoog.note_not': 'not',1376 'agoog.note_post': 'required. Login works via OpenID Connect (just the consent screen + the OAuth client).',1377 'agoog.redirect_label': 'Redirect URI — copy this and paste it into Google',1378 'agoog.rstep1_pre': 'Go to',1379 'agoog.rstep2': 'Open your OAuth client ID (type "Web application").',1380 'agoog.rstep3_pre': 'Under',1381 'agoog.rstep3_mid': 'click',1382 'agoog.rstep3_post': 'and paste the line above.',1383 'agoog.rstep4_pre': 'Click',1384 'agoog.rstep4_post': 'and wait ~1 minute.',1385 'agoog.warn_pre': 'It must be',1386 'agoog.warn_exact': 'exactly',1387 'agoog.warn_mid1': 'right:',1388 'agoog.warn_nohttp': 'not',1389 'agoog.warn_mid2': ', the correct domain, and',1390 'agoog.warn_noslash': 'no',1391 'agoog.warn_mid3': 'trailing slash. Otherwise you get',1392 'agoog.warn_error': '"Error 400: redirect_uri_mismatch"',1393 'agoog.set_baseurl_pre': 'First set',1394 'agoog.set_baseurl_post': '— the redirect URI is derived from it.',1395 'agoog.client_id': 'Client ID',1396 'agoog.client_secret': 'Client Secret',1397 'agoog.client_secret_set': 'configured; leave blank to keep unchanged',1398 'agoog.secret_ph_set': '•••••••• (configured)',1399 'agoog.save': 'Save',1400 'agoog.disconnect': 'Disconnect',1401 'agoog.premium_locked': 'The premium tier is on without Patreon — the Google button stays hidden until premium is unlocked.',1402 1224 'aaud.title': 'Audio tracks', 1403 1225 'aaud.tagline_pre': 'Site-level MP3s. Use', … … 1710 1532 'ahelp.s_premium_h': 'Premium / Patreon', 1711 1533 'ahelp.s_premium_b': 'You unlock premium features (Statistics, Agenda, Downloads, Press kit, Newsletter, Link-in-bio, Embed) in Admin → Settings by connecting Patreon ($16 lifetime). Updates and the core app always stay free.', 1712 'ahelp.s_google_h': 'Google login (visitors)',1713 'ahelp.s_google_b': 'Admin → Settings → <strong>Google</strong>. Optional: let visitors/fans log in with Google to comment. You manage with your password — Google never grants admin rights. Enter your own Google client details (per site).',1714 1534 'ahelp.s_updates_h': 'Updates', 1715 1535 'ahelp.s_updates_b': 'Admin → <strong>Updates</strong> (god only) shows the current version and whether a newer one is available. With "Update now" you fetch the latest version.', … … 1849 1669 'acct.password_min': '(min 8 characters)', 1850 1670 'acct.password_confirm': 'Confirm new password', 1851 'acct.google_login': 'Sign in with Google',1852 'acct.google_linked': '✓ Your Google account is linked — you can also sign in with Google.',1853 'acct.google_unlink': 'Unlink Google',1854 'acct.google_link_hint': 'Link your Google account so you can also sign in with one click via Google (alongside your password).',1855 'acct.google_link': 'Link Google account',1856 1671 'acct.login': 'Sign in', 1857 'acct.login_google_only': ' You are signed in via Google ({email}). There is no separate password.',1672 'acct.login_google_only': 'This account has no password ({email}). Use "Forgot password" to set one.', 1858 1673 'news.this_artist': 'this artist', 1859 1674 'news.form_title': 'Stay in the loop', … … 1951 1766 'adir.page_info': 'Page {page} of {pages}', 1952 1767 'adir.next': 'Next →', 1953 'glog.admin_title': 'This is an administrator account',1954 'glog.admin_body': 'You signed in with Google, but this email address belongs to the administrator of this site. Google sign-in is only for listeners/fans — administrators always use their password (so a Google login can never accidentally grant admin rights).',1955 'glog.admin_li1': '<strong>Are you the administrator?</strong> <a href="/auth/admin">Log in with your username + password</a>.',1956 'glog.admin_li2': '<strong>Want to sign in with Google from now on?</strong> Log in with your password first and <strong>link your Google account</strong> under Account → after that Google sign-in works for you too.',1957 'glog.admin_li3': '<strong>Want to sign in as a fan?</strong> Use a <strong>different Google account</strong> (not your administrator address).',1958 'glog.session_title': 'Login interrupted',1959 'glog.session_body': 'The Google login was interrupted or the session had expired. Just try again.',1960 'glog.email_title': 'No verified email address',1961 'glog.email_body': 'Your Google account has no verified email address. Verify your address with Google.',1962 'glog.linked_title': 'Address already linked',1963 'glog.linked_body': 'This email address is already linked to another Google account. Use that account, or contact the administrator.',1964 'glog.unavailable_title': 'Google sign-in unavailable',1965 'glog.unavailable_body': 'Google sign-in has not (yet) been set up on this site.',1966 'glog.failed_title': 'Google sign-in failed',1967 'glog.failed_body': 'Something went wrong signing in with Google. Please try again.',1968 1768 'pusr.post_one': 'post', 1969 1769 'pusr.post_many': 'posts', … … 2101 1901 'admin.b_makesite': '🎨 Seite erstellen', 'admin.b_circle': '🔗 Kreis', 'admin.b_stats': '📊 Statistik', 2102 1902 'admin.b_newsletter': '✉️ Newsletter', 'admin.b_perskit': '📰 Pressekit', 'admin.b_downloads': '⬇ Downloads', 2103 'admin.b_linkbio': '🔗 Link-in-Bio', 'admin.b_agenda': '📅 Termine', 'admin.b_google': '🔑 Google',1903 'admin.b_linkbio': '🔗 Link-in-Bio', 'admin.b_agenda': '📅 Termine', 2104 1904 'admin.b_updates': '🔄 Updates', 'admin.b_help': '📖 Anleitung', 'admin.b_fediverse': 'Meine Antworten', 2105 1905 'admin.st_users': 'Nutzer', 'admin.st_sites': 'Seiten', 'admin.st_posts': 'Beiträge', 'admin.st_published': 'Veröffentlicht', … … 2117 1917 'auth.password': 'Passwort', 2118 1918 'auth.forgot': 'Passwort vergessen?', 2119 'auth.google_btn': 'Mit Google anmelden',2120 1919 'auth.public_sub': 'Melde dich an, um zu kommentieren und Favoriten zu speichern.', 2121 1920 'auth.admin_box_q': 'Administrator?', 2122 1921 'auth.admin_box_sub': 'Mit Benutzername & Passwort anmelden', 2123 'auth.google_unavail': 'Google-Anmeldung ist auf dieser Seite noch nicht eingerichtet.',2124 1922 'auth.create_admin': 'Administrator anlegen', 2125 1923 'auth.reg_intro': 'Ersteinrichtung — lege dein Administrator-Konto an. Das geht nur einmal.', … … 2165 1963 'aset.solo': 'Solo', 2166 1964 'aset.solo_title': 'eine Site (deine).', 2167 'aset.solo_desc': 'Kein Benutzerverzeichnis, kein Site-Wechsel. Besucher können sich aber mit Google anmelden, um zu kommentieren.', 2168 'aset.hub': 'Hub', 2169 'aset.hub_title': 'Unternehmens-Site mit', 1965 'aset.solo_desc': 'Kein Benutzerverzeichnis, kein Site-Wechsel.', 2170 1966 'aset.premium_badge': 'Premium', 2171 'aset.hub_desc': 'Du (Admin) weist Benutzern einen eigenen Klonkt Hub zu. Geschlossener Kreis: keine offene Registrierung.',2172 'aset.hub_locked_note': 'Erfordert Premium — verbinde Patreon auf dieser Seite.',2173 1967 'aset.circle': 'Kreise', 2174 1968 'aset.circle_title': 'Solo + Föderation.', 2175 1969 'aset.circle_desc': 'Eine eigene Site, die die öffentlichen Beiträge anderer Klonkt-Sites anzeigt. Asymmetrisch: Du bestimmst, wer in deinem Kreis ist.', 2176 1970 'aset.save': 'Speichern', 2177 'aset.hub_home': 'Hub-Startseite',2178 'aset.hub_home_help_1': 'Die öffentliche Hub-Seite',2179 'aset.hub_home_help_2': 'ist generisch — sie gehört keinem einzelnen Benutzer. Hier legst du Name und Intro fest. Dein eigener Klonkt Hub bleibt separat unter',2180 1971 'aset.name': 'Name', 2181 1972 'aset.name_ph': 'z. B. Studio Noord', … … 2208 1999 'aset.patreon_not_connected': 'Noch nicht verbunden.', 2209 2000 'aset.patreon_connect': 'Patreon verbinden', 2210 'aset.google_login': 'Google-Login (Besucher)',2211 'aset.google_login_help': 'Lass Besucher sich mit Google anmelden, um zu kommentieren — mit deinem eigenen Google-Cloud-Client.',2212 2001 'aset.status_set': 'Status: eingerichtet', 2213 2002 'aset.not_set_yet': 'Noch nicht eingerichtet.', 2214 'aset.google_login_setup': 'Google-Login einrichten',2215 2003 'aset.newsletter': 'Newsletter', 2216 2004 'aset.newsletter_help_1': 'Zeige ein', … … 2281 2069 'asite.moderation_moderate': 'Moderieren (zuerst in die Warteschlange)', 2282 2070 'asite.enable_audio': 'Audioplayer + Embeds aktivieren', 2283 'asite.enable_prutter': 'Prutter (DMs zwischen Mitgliedern) aktivieren',2284 'asite.enable_prutter_hint': '— Hub-Funktion, Premium',2285 2071 'asite.links': 'Social- / Streaming-Links', 2286 2072 'asite.links_hint': 'Werden als Marken-Icons im Profilkopf gezeigt. Füge so viele hinzu, wie du möchtest.', … … 2349 2135 'aseo.verify_yandex': 'Yandex', 2350 2136 'aseo.save': 'SEO speichern', 2351 'agoog.title': 'Google-Anmeldung',2352 'agoog.intro': 'Damit können sich Besucher mit ihrem <strong>Google-Konto</strong> anmelden, um zu kommentieren. Du richtest das einmalig mit deinem eigenen (kostenlosen) Google-Konto ein — etwa 5 Minuten, keine Kreditkarte oder kostenpflichtiger Dienst nötig.',2353 'agoog.g1': 'Öffne die Google Cloud Console und melde dich an. Erstelle oben ein <strong>neues Projekt</strong> (Projekt auswählen → Neues Projekt), gib ihm einen Namen und klicke auf <strong>Erstellen</strong>.',2354 'agoog.g2': 'Gehe im linken Menü zu <strong>APIs und Dienste → OAuth-Zustimmungsbildschirm</strong>. Wähle <strong>Extern</strong>, trage den App-Namen + deine E-Mail ein und speichere. Falls nach Testnutzern gefragt wird, füge dich selbst hinzu.',2355 'agoog.g3': 'Gehe zu <strong>APIs und Dienste → Anmeldedaten → Anmeldedaten erstellen → OAuth-Client-ID</strong> und wähle den Typ <strong>Webanwendung</strong>.',2356 'agoog.g4': 'Füge unter <strong>Autorisierte Weiterleitungs-URIs</strong> genau diese Adresse ein und klicke auf <strong>Erstellen</strong>:',2357 'agoog.g5': 'Google zeigt nun eine <strong>Client-ID</strong> und ein <strong>Client-Secret</strong>. Kopiere sie in die Felder unten und klicke auf <strong>Speichern</strong>. Fertig!',2358 'agoog.copy': 'Kopieren',2359 'agoog.copied': 'Kopiert ✓',2360 'agoog.warn_short': 'Achtung: muss <strong>exakt</strong> stimmen — mit <code>https://</code>, der richtigen Domain und <strong>ohne</strong> Schrägstrich am Ende. Andernfalls bekommst du „Error 400: redirect_uri_mismatch“.',2361 'agoog.need_baseurl': 'Lege zuerst <code>PUBLIC_BASE_URL</code> fest (die öffentliche URL deiner Seite) — daraus wird diese Adresse abgeleitet.',2362 'agoog.no_api_note': '<strong>Tipp:</strong> du musst keine APIs aktivieren (keine „People API“ usw.). Nur der Zustimmungsbildschirm + der OAuth-Client sind nötig.',2363 'agoog.back': 'Einstellungen',2364 'agoog.card_title': 'Google-Anmeldung (Besucher)',2365 'agoog.card_help_pre': 'Lass Besucher sich mit Google anmelden, um zu kommentieren — mit deinem',2366 'agoog.card_help_own': 'eigenen',2367 'agoog.card_help_mid': 'Google-Cloud-Client. Erstelle einen unter',2368 'agoog.card_help_post': '(OAuth-Client-ID, Typ „Web application“).',2369 'agoog.status_set': 'Status: eingerichtet ✓',2370 'agoog.status_unset': 'Noch nicht eingerichtet.',2371 'agoog.guide_summary': 'Wie richte ich das ein? (Schritt für Schritt)',2372 'agoog.step1_pre': 'Gehe zur',2373 'agoog.step1_post': 'und erstelle (oder wähle) ein Projekt.',2374 'agoog.step2_usertype': 'User type',2375 'agoog.step2_scopes_pre': 'Füge die Scopes',2376 'agoog.step2_scopes_and': 'und',2377 'agoog.step2_scopes_post': 'hinzu.',2378 'agoog.step2_testmode': '(Im Testmodus: füge dich selbst als Testnutzer hinzu.)',2379 'agoog.step3_type': 'Typ',2380 'agoog.step4_pre': 'Unter',2381 'agoog.step4_post': ': füge die Redirect-URI unten ein (muss exakt übereinstimmen).',2382 'agoog.step5_pre': 'Kopiere die',2383 'agoog.step5_post': 'die du erhältst, in die Felder unten und klicke auf Speichern.',2384 'agoog.note_label': 'Achtung:',2385 'agoog.note_pre': 'du musst',2386 'agoog.note_noapi': 'keine APIs aktivieren',2387 'agoog.note_mid': '— „Google Cloud APIs“, People API usw. sind',2388 'agoog.note_not': 'nicht',2389 'agoog.note_post': 'erforderlich. Die Anmeldung läuft über OpenID Connect (nur der Zustimmungsbildschirm + der OAuth-Client).',2390 'agoog.redirect_label': 'Redirect-URI — kopiere diese und füge sie in Google ein',2391 'agoog.rstep1_pre': 'Gehe zur',2392 'agoog.rstep2': 'Öffne deine OAuth-Client-ID (Typ „Web application“).',2393 'agoog.rstep3_pre': 'Unter',2394 'agoog.rstep3_mid': 'klicke auf',2395 'agoog.rstep3_post': 'und füge die obige Zeile ein.',2396 'agoog.rstep4_pre': 'Klicke auf',2397 'agoog.rstep4_post': 'und warte ~1 Minute.',2398 'agoog.warn_pre': 'Muss',2399 'agoog.warn_exact': 'exakt',2400 'agoog.warn_mid1': 'stimmen:',2401 'agoog.warn_nohttp': 'kein',2402 'agoog.warn_mid2': ', richtige Domain und',2403 'agoog.warn_noslash': 'kein',2404 'agoog.warn_mid3': 'Schrägstrich am Ende. Andernfalls bekommst du',2405 'agoog.warn_error': '„Error 400: redirect_uri_mismatch“',2406 'agoog.set_baseurl_pre': 'Lege zuerst',2407 'agoog.set_baseurl_post': 'fest — daraus wird die Redirect-URI abgeleitet.',2408 'agoog.client_id': 'Client ID',2409 'agoog.client_secret': 'Client Secret',2410 'agoog.client_secret_set': 'eingerichtet; leer lassen = unverändert',2411 'agoog.secret_ph_set': '•••••••• (eingerichtet)',2412 'agoog.save': 'Speichern',2413 'agoog.disconnect': 'Trennen',2414 'agoog.premium_locked': 'Die Premium-Ebene ist ohne Patreon aktiv — der Google-Button bleibt verborgen, bis Premium freigeschaltet ist.',2415 2137 'aaud.title': 'Audio-Tracks', 2416 2138 'aaud.tagline_pre': 'MP3s auf Site-Ebene. Verwende', … … 2723 2445 'ahelp.s_premium_h': 'Premium / Patreon', 2724 2446 'ahelp.s_premium_b': 'Premium-Funktionen (Statistiken, Termine, Downloads, Pressekit, Newsletter, Link-in-Bio, Embed) schaltest du in Verwaltung → Einstellungen frei, indem du Patreon verknüpfst ($16 lebenslang). Updates und die Kern-App bleiben immer kostenlos.', 2725 'ahelp.s_google_h': 'Google-Login (Besucher)',2726 'ahelp.s_google_b': 'Verwaltung → Einstellungen → <strong>Google</strong>. Optional: Lass Besucher/Fans sich mit Google anmelden, um zu kommentieren. Du verwaltest mit deinem Passwort — Google gewährt nie Verwaltungsrechte. Trage deine eigenen Google-Client-Daten ein (pro Seite).',2727 2447 'ahelp.s_updates_h': 'Updates', 2728 2448 'ahelp.s_updates_b': 'Verwaltung → <strong>Updates</strong> (nur God) zeigt die aktuelle Version und ob eine neuere verfügbar ist. Mit „Jetzt aktualisieren“ holst du dir die neueste Version.', … … 2862 2582 'acct.password_min': '(mind. 8 Zeichen)', 2863 2583 'acct.password_confirm': 'Neues Passwort bestätigen', 2864 'acct.google_login': 'Mit Google anmelden',2865 'acct.google_linked': '✓ Dein Google-Konto ist verknüpft — du kannst dich auch mit Google anmelden.',2866 'acct.google_unlink': 'Google trennen',2867 'acct.google_link_hint': 'Verknüpfe dein Google-Konto, damit du dich künftig auch mit einem Klick über Google anmelden kannst (zusätzlich zu deinem Passwort).',2868 'acct.google_link': 'Google-Konto verknüpfen',2869 2584 'acct.login': 'Anmelden', 2870 'acct.login_google_only': 'D u bist über Google angemeldet ({email}). Es gibt kein separates Passwort.',2585 'acct.login_google_only': 'Dieses Konto hat kein Passwort ({email}). Nutze "Passwort vergessen", um eines festzulegen.', 2871 2586 'news.this_artist': 'diese:r Künstler:in', 2872 2587 'news.form_title': 'Bleib auf dem Laufenden', … … 2964 2679 'adir.page_info': 'Seite {page} von {pages}', 2965 2680 'adir.next': 'Weiter →', 2966 'glog.admin_title': 'Dies ist ein Administrator-Konto',2967 'glog.admin_body': 'Du hast dich mit Google angemeldet, aber diese E-Mail-Adresse gehört dem Administrator dieser Seite. Die Google-Anmeldung ist nur für Hörer/Fans — Administratoren verwenden immer ihr Passwort (so kann eine Google-Anmeldung niemals versehentlich Administratorrechte erteilen).',2968 'glog.admin_li1': '<strong>Bist du der Administrator?</strong> <a href="/auth/admin">Melde dich mit Benutzername + Passwort an</a>.',2969 'glog.admin_li2': '<strong>Möchtest du dich künftig mit Google anmelden?</strong> Melde dich zuerst mit Passwort an und <strong>verknüpfe dein Google-Konto</strong> unter Konto → danach funktioniert die Google-Anmeldung auch für dich.',2970 'glog.admin_li3': '<strong>Möchtest du dich als Fan anmelden?</strong> Verwende ein <strong>anderes Google-Konto</strong> (nicht deine Administrator-Adresse).',2971 'glog.session_title': 'Anmeldung abgebrochen',2972 'glog.session_body': 'Die Google-Anmeldung wurde abgebrochen oder die Sitzung war abgelaufen. Versuche es einfach erneut.',2973 'glog.email_title': 'Keine verifizierte E-Mail-Adresse',2974 'glog.email_body': 'Dein Google-Konto hat keine verifizierte E-Mail-Adresse. Verifiziere deine Adresse bei Google.',2975 'glog.linked_title': 'Adresse bereits verknüpft',2976 'glog.linked_body': 'Diese E-Mail-Adresse ist bereits mit einem anderen Google-Konto verknüpft. Verwende dieses Konto oder wende dich an den Administrator.',2977 'glog.unavailable_title': 'Google-Anmeldung nicht verfügbar',2978 'glog.unavailable_body': 'Die Google-Anmeldung wurde auf dieser Seite (noch) nicht eingerichtet.',2979 'glog.failed_title': 'Google-Anmeldung fehlgeschlagen',2980 'glog.failed_body': 'Beim Anmelden mit Google ist etwas schiefgelaufen. Bitte versuche es erneut.',2981 2681 'pusr.post_one': 'Beitrag', 2982 2682 'pusr.post_many': 'Beiträge', -
src/views/pages/auth-login.ejs
r98fe58a r5f483e3 1 1 <% 2 // adminLogin = the hidden admin login page (/auth/admin): shows the 3 // username/password form. The public /auth/login shows visitors 4 // ONLY Google login (listeners/fans). This keeps the admin login 5 // off the page where visitors are directed. 2 // The login page shows the admin username/password form. (Public listener 3 // login via Google was removed — interaction now runs via the fediverse.) 6 4 var _admin = (typeof adminLogin !== 'undefined' && adminLogin); 7 5 %> … … 9 7 <h1><%= _admin ? t('auth.admin_login_title') : t('nav.login') %></h1> 10 8 <% if (typeof success !== 'undefined' && success) { %><div class="alert alert-success"><%= success %></div><% } %> 11 <% 12 var GMAP = { 13 admin: { icon: '🔐', title: t('glog.admin_title'), 14 body: t('glog.admin_body'), 15 list: [t('glog.admin_li1'), t('glog.admin_li2'), t('glog.admin_li3')] }, 16 session: { icon: '⏱️', title: t('glog.session_title'), body: t('glog.session_body') }, 17 email: { icon: '✉️', title: t('glog.email_title'), body: t('glog.email_body') }, 18 linked: { icon: '🔗', title: t('glog.linked_title'), body: t('glog.linked_body') }, 19 unavailable: { icon: '🚫', title: t('glog.unavailable_title'), body: t('glog.unavailable_body') }, 20 failed: { icon: '⚠️', title: t('glog.failed_title'), body: t('glog.failed_body') }, 21 }; 22 var _g = (typeof gerr !== 'undefined' && gerr && GMAP[gerr]) ? GMAP[gerr] : null; 23 %> 24 <% if (_g) { %> 25 <div class="auth-notice"> 26 <div class="auth-notice-icon"><%= _g.icon %></div> 27 <h2 class="auth-notice-title"><%= _g.title %></h2> 28 <p><%= _g.body %></p> 29 <% if (_g.list) { %><ul class="auth-notice-list"><% _g.list.forEach(function(li){ %><li><%- li %></li><% }); %></ul><% } %> 30 </div> 31 <% } else if (error) { %><div class="alert alert-error"><%= error %></div><% } %> 9 <% if (error) { %><div class="alert alert-error"><%= error %></div><% } %> 32 10 33 11 <% if (_admin) { %> … … 51 29 </div> 52 30 53 <style>54 .auth-notice { border: 1px solid rgba(128,128,128,.28); border-radius: 14px; padding: 18px 20px; margin-bottom: 18px; background: rgba(128,128,128,.06); }55 .auth-notice-icon { font-size: 26px; }56 .auth-notice-title { font-size: 17px; margin: 4px 0 8px; }57 .auth-notice p { margin: 0 0 10px; line-height: 1.55; opacity: .9; }58 .auth-notice-list { margin: 0; padding-left: 18px; line-height: 1.6; }59 .auth-notice-list li { margin: 4px 0; }60 .auth-sub { color: var(--ink-muted); margin: 0 0 1rem; text-align: center; }61 /* Google button is white → keep text dark at all times, including hover (the global62 a.btn:hover rule would otherwise make it near-white on white = unreadable). */63 a.btn-google, a.btn-google:hover { color: #1f1f1f; }64 .auth-admin-box {65 display: flex; align-items: center; gap: .75rem;66 margin-top: 1.25rem; padding: .8rem 1rem;67 border: 1px solid var(--rule); border-radius: 12px;68 background: var(--paper-2); color: var(--ink); text-decoration: none;69 transition: border-color 120ms, background 120ms;70 }71 .auth-admin-box:hover { border-color: var(--accent); background: var(--paper); }72 .auth-admin-box-icon { font-size: 1.3rem; }73 .auth-admin-box-text { display: flex; flex-direction: column; line-height: 1.3; flex: 1; }74 .auth-admin-box-text small { color: var(--ink-muted); font-size: .8rem; }75 .auth-admin-box-arrow { color: var(--ink-muted); font-size: 1.1rem; }76 </style>
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)