21b48d3d53
- iStore service (port 3021): fetches app manifests from git.falahos.my/falahos org via Gitea API, 5-min cache, query/search support - UmmahID login: replaced stub form with Casdoor OAuth2 PKCE flow (RFC 7636), no client secret required; /api/auth/config and /api/auth/token endpoints added to server.cjs - App Manager service (port 3022): installs/uninstalls Docker apps via /var/run/docker.sock, pulls images, starts containers on falah-net, persists state to /data/installed.json - docker-compose.yml: orchestrates falah-app + istore + app-manager with health checks, named volumes, and shared falah-net network - install.sh: one-line curl installer — checks prereqs, clones repo, prompts for credentials, builds and starts all containers - .env.example: all env vars documented (CASDOOR_CLIENT_ID, GITEA_TOKEN, APP_MANAGER_PORT, etc.) - Frontend: IStore overlay now fetches live apps from Gitea, real install/uninstall via App Manager with 2s polling, indeterminate progress bar, Uninstall button for installed apps - app.yml.example: developer manifest spec for publishing to iStore
153 lines
4.2 KiB
TypeScript
153 lines
4.2 KiB
TypeScript
import { useState, useCallback } from 'react'
|
|
import { fetchAuthConfig, initiateLogin } from '../hooks/useAuth'
|
|
|
|
function Logo({ size }: { size: number }) {
|
|
return (
|
|
<div
|
|
style={{
|
|
width: size,
|
|
height: size,
|
|
borderRadius: size * 0.225,
|
|
background: 'linear-gradient(145deg, #10B981, #059669)',
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
fontSize: size * 0.45,
|
|
fontWeight: 800,
|
|
color: 'white',
|
|
flexShrink: 0,
|
|
boxShadow: '0 8px 32px rgba(16,185,129,0.4)',
|
|
}}
|
|
>
|
|
F
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default function Login() {
|
|
const [loading, setLoading] = useState(false)
|
|
const [error, setError] = useState('')
|
|
|
|
const handleSignIn = useCallback(async () => {
|
|
setLoading(true)
|
|
setError('')
|
|
try {
|
|
const config = await fetchAuthConfig()
|
|
await initiateLogin(config)
|
|
// page will redirect — no further state updates needed
|
|
} catch (err) {
|
|
setError(err instanceof Error ? err.message : 'Could not reach auth server')
|
|
setLoading(false)
|
|
}
|
|
}, [])
|
|
|
|
return (
|
|
<div
|
|
style={{
|
|
position: 'absolute',
|
|
inset: 0,
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
padding: 24,
|
|
}}
|
|
>
|
|
<div
|
|
style={{
|
|
width: '100%',
|
|
maxWidth: 400,
|
|
background: 'rgba(12,26,46,0.92)',
|
|
backdropFilter: 'blur(24px)',
|
|
WebkitBackdropFilter: 'blur(24px)',
|
|
border: '1px solid var(--glass-border)',
|
|
borderRadius: 24,
|
|
padding: 40,
|
|
boxShadow: 'var(--shadow-modal)',
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
alignItems: 'center',
|
|
}}
|
|
>
|
|
{/* Arabic */}
|
|
<div
|
|
style={{
|
|
color: 'var(--green)',
|
|
fontSize: 14,
|
|
letterSpacing: 1.5,
|
|
opacity: 0.7,
|
|
marginBottom: 20,
|
|
fontFamily: 'serif',
|
|
}}
|
|
>
|
|
بِسْمِ اللَّهِ
|
|
</div>
|
|
|
|
<Logo size={72} />
|
|
|
|
<h1 style={{ fontSize: 26, fontWeight: 700, color: 'var(--text)', margin: '16px 0 4px' }}>
|
|
Falah OS
|
|
</h1>
|
|
|
|
<p style={{ fontSize: 13, color: 'var(--text-muted)', margin: '0 0 36px', textAlign: 'center' }}>
|
|
Sovereign Digital Economy
|
|
</p>
|
|
|
|
{/* UmmahID sign-in block */}
|
|
<div
|
|
style={{
|
|
width: '100%',
|
|
background: 'rgba(16,185,129,0.06)',
|
|
border: '1px solid rgba(16,185,129,0.18)',
|
|
borderRadius: 16,
|
|
padding: '20px 20px 24px',
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
alignItems: 'center',
|
|
gap: 12,
|
|
marginBottom: 24,
|
|
}}
|
|
>
|
|
<div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
|
|
<span style={{ fontSize: 22 }}>🪪</span>
|
|
<div>
|
|
<div style={{ fontSize: 13, fontWeight: 700, color: 'var(--text)' }}>UmmahID</div>
|
|
<div style={{ fontSize: 11, color: 'var(--text-muted)' }}>Zero-knowledge identity · auth.falahos.my</div>
|
|
</div>
|
|
</div>
|
|
|
|
<button
|
|
onClick={handleSignIn}
|
|
disabled={loading}
|
|
className="btn-primary"
|
|
style={{ width: '100%', marginTop: 4, opacity: loading ? 0.6 : 1 }}
|
|
>
|
|
{loading ? 'Redirecting to UmmahID…' : 'Sign in with UmmahID'}
|
|
</button>
|
|
</div>
|
|
|
|
{error && (
|
|
<div
|
|
style={{
|
|
width: '100%',
|
|
fontSize: 12,
|
|
color: '#F87171',
|
|
background: 'rgba(239,68,68,0.08)',
|
|
border: '1px solid rgba(239,68,68,0.2)',
|
|
borderRadius: 8,
|
|
padding: '10px 14px',
|
|
textAlign: 'center',
|
|
marginBottom: 16,
|
|
}}
|
|
>
|
|
{error}
|
|
</div>
|
|
)}
|
|
|
|
<p style={{ fontSize: 11, color: 'var(--text-dim)', textAlign: 'center', margin: 0 }}>
|
|
Falah OS CE v1.3 · Community Edition
|
|
</p>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|