demo-service: add login link to error page, mount ConfigMap into API container

- Add subtle 'Log in' link to 401/403/404 error page
- Link redirects through pass.junv.cc OAuth with return URL
- Mount error-page-html ConfigMap into API container too (so both
  Caddy and API serve the same updated error page)
- Define error-page-html ConfigMap in repo for ArgoCD management
This commit is contained in:
Junv (via Hermes)
2026-07-13 10:06:18 +10:00
parent 6afccdb765
commit ad1904c441
2 changed files with 82 additions and 0 deletions
+74
View File
@@ -69,6 +69,9 @@ spec:
volumeMounts:
- name: demo-data
mountPath: /data/demos
- name: error-page
mountPath: /app/error-page.html
subPath: error-page.html
resources:
requests:
memory: 64Mi
@@ -92,6 +95,77 @@ spec:
name: error-page-html
---
apiVersion: v1
kind: ConfigMap
metadata:
name: error-page-html
namespace: home-apps
data:
error-page.html: |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Unavailable</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Inter",sans-serif;background:#0b0f19;color:#8b949e;display:flex;align-items:center;justify-content:center;min-height:100vh;overflow:hidden}
canvas{position:fixed;inset:0;z-index:0}
.card{z-index:1;text-align:center;padding:48px 32px;max-width:420px}
h1{font-size:26px;font-weight:600;color:#c9d1d9;margin-bottom:8px}
p{font-size:14px;color:#6e7681;line-height:1.5}
.login{margin-top:24px;display:inline-block;font-size:13px;color:#58a6ff;text-decoration:none;opacity:.7;transition:opacity .2s}
.login:hover{opacity:1;text-decoration:underline}
</style>
</head>
<body>
<canvas id="c"></canvas>
<div class="card">
<h1>This page isn't available right now</h1>
<p>Try again later.</p>
<a class="login" id="loginLink" href="#">Log in</a>
</div>
<script>
const c=document.getElementById('c'),x=c.getContext('2d');
let w,h,particles=[];
function resize(){w=c.width=innerWidth;h=c.height=innerHeight}
resize();addEventListener('resize',resize);
for(let i=0;i<50;i++)particles.push({
x:Math.random()*w,y:Math.random()*h,r:Math.random()*2+1,
vx:(Math.random()-.5)*.4,vy:(Math.random()-.5)*.4,
a:Math.random()*.3+.1,h:Math.random()*360
});
function draw(t){
x.clearRect(0,0,w,h);
for(let p of particles){
p.x+=p.vx;p.y+=p.vy;
if(p.x<0)p.x=w;if(p.x>w)p.x=0;
if(p.y<0)p.y=h;if(p.y>h)p.y=0;
p.h=(p.h+.1)%360;
x.beginPath();x.arc(p.x,p.y,p.r,0,Math.PI*2);
x.fillStyle='hsla('+p.h+',60%,65%,'+p.a+')';x.fill();
}
for(let i=0;i<particles.length;i++){
for(let j=i+1;j<particles.length;j++){
const dx=particles[i].x-particles[j].x,dy=particles[i].y-particles[j].y,d=Math.sqrt(dx*dx+dy*dy);
if(d<120){
x.beginPath();x.moveTo(particles[i].x,particles[i].y);x.lineTo(particles[j].x,particles[j].y);
x.strokeStyle='rgba(88,166,255,'+(.06*(1-d/120))+')';x.lineWidth=.5;x.stroke();
}
}
}
requestAnimationFrame(draw);
}
draw();
document.getElementById('loginLink').addEventListener('click',function(e){
e.preventDefault();
location.href='https://pass.junv.cc/oauth2/start?rd='+encodeURIComponent(location.href);
});
</script>
</body>
</html>
---
apiVersion: v1
kind: Service
metadata:
name: demo-service
+8
View File
@@ -11,6 +11,8 @@ canvas{position:fixed;inset:0;z-index:0}
.card{z-index:1;text-align:center;padding:48px 32px;max-width:420px}
h1{font-size:26px;font-weight:600;color:#c9d1d9;margin-bottom:8px}
p{font-size:14px;color:#6e7681;line-height:1.5}
.login{margin-top:24px;display:inline-block;font-size:13px;color:#58a6ff;text-decoration:none;opacity:.7;transition:opacity .2s}
.login:hover{opacity:1;text-decoration:underline}
</style>
</head>
<body>
@@ -18,6 +20,7 @@ p{font-size:14px;color:#6e7681;line-height:1.5}
<div class="card">
<h1>This page isn't available right now</h1>
<p>Try again later.</p>
<a class="login" id="loginLink" href="#">Log in</a>
</div>
<script>
const c=document.getElementById('c'),x=c.getContext('2d');
@@ -51,6 +54,11 @@ function draw(t){
requestAnimationFrame(draw);
}
draw();
// Login link — reads current URL and redirects through oauth2-proxy
document.getElementById('loginLink').addEventListener('click',function(e){
e.preventDefault();
location.href='https://pass.junv.cc/oauth2/start?rd='+encodeURIComponent(location.href);
});
</script>
</body>
</html>