6d796c95ff
- Implemented NetID OAuth provider in app/auth/oauth.py - Added styles for NetID login button in app/static/css/styles.css - Updated login.html to include NetID login option with custom button - Modified docker-compose.yml to include NetID client credentials - Enhanced social login setup documentation to include NetID instructions - Created demo environment configuration file (.env.demo) for easier setup - Updated .env.template to include NetID configuration options - Added comprehensive README.md with project features and setup instructions
184 lines
9.6 KiB
HTML
184 lines
9.6 KiB
HTML
{% extends "base.html" %}
|
|
{% block content %}
|
|
<div class="max-w-md mx-auto my-8">
|
|
<div class="bg-white p-8 rounded-lg shadow-md">
|
|
<h1 class="text-2xl font-bold text-irish-green mb-6 text-center">Log In</h1>
|
|
|
|
<!-- Messages/Alerts -->
|
|
{% if error %}
|
|
<div class="mb-4 p-3 rounded bg-red-100 text-red-700">
|
|
{{ error }}
|
|
|
|
<!-- Display resend verification link if applicable -->
|
|
{% if unverified_user_id %}
|
|
<div class="mt-2 p-2 border-t border-red-200">
|
|
<p class="mb-2 text-sm">Didn't receive the verification email?</p>
|
|
<a href="/auth/resend-verification?user_id={{ unverified_user_id }}"
|
|
class="text-irish-green hover:underline text-sm font-medium">
|
|
Resend verification email to {{ unverified_email }}
|
|
</a>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if message %}
|
|
<div class="mb-4 p-3 rounded bg-green-100 text-green-700">
|
|
{{ message }}
|
|
</div>
|
|
{% endif %}
|
|
|
|
<form action="/auth/login" method="post" class="space-y-4">
|
|
<div>
|
|
<label for="username" class="block text-sm font-medium text-gray-700 mb-1">Username</label>
|
|
<input
|
|
type="text"
|
|
id="username"
|
|
name="username"
|
|
required
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-irish-green focus:border-irish-green"
|
|
>
|
|
</div>
|
|
|
|
<div>
|
|
<label for="password" class="block text-sm font-medium text-gray-700 mb-1">Password</label>
|
|
<input
|
|
type="password"
|
|
id="password"
|
|
name="password"
|
|
required
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-irish-green focus:border-irish-green"
|
|
>
|
|
</div>
|
|
|
|
<!-- Debug info -->
|
|
<div class="text-xs text-gray-500">
|
|
<p>Having trouble logging in? Make sure your browser accepts cookies.</p>
|
|
</div>
|
|
|
|
<div class="flex items-center">
|
|
<input
|
|
type="checkbox"
|
|
id="remember"
|
|
name="remember"
|
|
class="h-4 w-4 text-irish-green focus:ring-irish-green border-gray-300 rounded"
|
|
>
|
|
<label for="remember" class="ml-2 block text-sm text-gray-700">Remember me</label>
|
|
</div>
|
|
|
|
<div class="flex items-center justify-between">
|
|
<button
|
|
type="submit"
|
|
class="bg-irish-green text-white py-2 px-4 rounded-md hover:bg-opacity-90 transition focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-irish-green"
|
|
>
|
|
Log In
|
|
</button>
|
|
<a class="inline-block align-baseline font-bold text-sm text-irish-green hover:text-opacity-75" href="/auth/forgot-password">
|
|
Forgot Password?
|
|
</a>
|
|
</div>
|
|
</form>
|
|
|
|
<div class="mt-6 pt-6 border-t border-gray-200 text-center">
|
|
<p class="text-gray-600">Don't have an account?</p>
|
|
<a href="/auth/register" class="block mt-2 bg-cream-white text-irish-green border border-irish-green py-2 px-4 rounded-md hover:bg-irish-green hover:text-white transition">
|
|
Create an account
|
|
</a>
|
|
</div>
|
|
|
|
<!-- OAuth login options -->
|
|
{% if oauth_providers and oauth_providers|length > 0 %}
|
|
<div class="mt-6 pt-6 border-t border-gray-200">
|
|
<p class="text-center text-gray-600 mb-4">Or sign in with</p>
|
|
|
|
<div class="oauth-buttons-container">
|
|
{% for provider in oauth_providers %}
|
|
{% if provider.id == 'google' %}
|
|
<!-- Custom Google Button -->
|
|
<a href="/auth/oauth-login/{{ provider.id }}" class="block w-full mb-3">
|
|
<button class="gsi-material-button" type="button">
|
|
<div class="gsi-material-button-state"></div>
|
|
<div class="gsi-material-button-content-wrapper">
|
|
<div class="gsi-material-button-icon">
|
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" xmlns:xlink="http://www.w3.org/1999/xlink" style="display: block;">
|
|
<path fill="#EA4335" d="M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z"></path>
|
|
<path fill="#4285F4" d="M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z"></path>
|
|
<path fill="#FBBC05" d="M10.53 28.59c-.48-1.45-.76-2.99-.76-4.59s.27-3.14.76-4.59l-7.98-6.19C.92 16.46 0 20.12 0 24c0 3.88.92 7.54 2.56 10.78l7.97-6.19z"></path>
|
|
<path fill="#34A853" d="M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z"></path>
|
|
<path fill="none" d="M0 0h48v48H0z"></path>
|
|
</svg>
|
|
</div>
|
|
<span class="gsi-material-button-contents">Sign in with Google</span>
|
|
<span style="display: none;">Sign in with Google</span>
|
|
</div>
|
|
</button>
|
|
</a>
|
|
{% elif provider.id == 'facebook' %}
|
|
<!-- Custom Facebook Button according to Meta's guidelines -->
|
|
<a href="/auth/oauth-login/{{ provider.id }}" class="block w-full mb-3">
|
|
<button class="fb-login-button" type="button">
|
|
<div class="fb-icon">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
|
<path d="M9.198 21.5h4v-8.01h3.604l.396-3.98h-4V7.5a1 1 0 0 1 1-1h3v-4h-3a5 5 0 0 0-5 5v2.01h-2l-.396 3.98h2.396v8.01Z" fill="#1877F2" />
|
|
</svg>
|
|
</div>
|
|
<span class="button-text">Continue with Facebook</span>
|
|
</button>
|
|
</a>
|
|
{% elif provider.id == 'linkedin' %}
|
|
<!-- Custom LinkedIn Button -->
|
|
<a href="/auth/oauth-login/{{ provider.id }}" class="block w-full mb-3">
|
|
<button class="linkedin-login-button" type="button">
|
|
<div class="linkedin-icon">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
|
<path d="M19 3a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1-2-2h14m-.5 15.5v-5.3a3.26 3.26 0 0 0-3.26-3.26c-.85 0-1.84.52-2.32 1.3v-1.11h-2.79v8.37h2.79v-4.93c0-.77.62-1.4 1.39-1.4a1.4 1.4 0 0 1 1.4 1.4v4.93h2.79M6.88 8.56a1.68 1.68 0 0 0 1.68-1.68c0-.93-.75-1.69-1.68-1.69a1.69 1.69 0 0 0-1.69 1.69c0 .93.76 1.68 1.69 1.68m1.39 9.94v-8.37H5.5v8.37h2.77z" fill="white" />
|
|
</svg>
|
|
</div>
|
|
<span class="button-text">Sign in with LinkedIn</span>
|
|
</button>
|
|
</a>
|
|
{% elif provider.id == 'github' %}
|
|
<!-- Custom GitHub Button -->
|
|
<a href="/auth/oauth-login/{{ provider.id }}" class="block w-full mb-3">
|
|
<button class="github-login-button" type="button">
|
|
<div class="github-icon">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
|
<path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" fill="white" />
|
|
</svg>
|
|
</div>
|
|
<span class="button-text">Login with GitHub</span>
|
|
</button>
|
|
</a>
|
|
{% elif provider.id == 'netid' %}
|
|
<!-- NetID explanation text -->
|
|
<div class="text-center mb-2 text-xs text-gray-600">
|
|
<p>Login with GMX, WEB.DE, or other email providers via netID</p>
|
|
</div>
|
|
<!-- Custom NetID Button -->
|
|
<a href="/auth/oauth-login/{{ provider.id }}" class="block w-full mb-3">
|
|
<button class="netid-login-button" type="button">
|
|
<div class="netid-icon">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40">
|
|
<path fill="#fff" d="M30.3 4.1a14.5 14.5 0 00-6-2.7C20.7 1 17 2 13.6 5.3L7 12.1l-6.9 7 19.8 19.8 8.8-8.9 5-4.9c3-3.1 4.2-6.7 3.8-10a12.9 12.9 0 00-1-3.8l-2 2a10 10 0 01.6 2c.3 2.7-.5 5.4-3.2 8l-4.9 5-16.3-16.4L15.5 7c3-3 5.7-3.6 8.3-3.1 1.6.2 3.2 1 4.7 2z"></path>
|
|
<path fill="#fff" d="M37.7 1.1l-12.9 13-4.6-4.7-2.3 2.3 6.9 7L40 3.5z"></path>
|
|
</svg>
|
|
</div>
|
|
<span class="button-text">Login mit netID</span>
|
|
</button>
|
|
</a>
|
|
{% else %}
|
|
<!-- Standard Button for other providers -->
|
|
<a href="/auth/oauth-login/{{ provider.id }}"
|
|
class="oauth-button flex items-center justify-center w-full py-2 px-4 rounded-md transition mb-3"
|
|
style="background-color: {{ provider.color }}; color: white;">
|
|
<i class="{{ provider.icon }} mr-2"></i> Sign in with {{ provider.name }}
|
|
</a>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|