Sign-in via django-allauth: emailed one-time codes, GitHub, Discord, and Forgejo instances as OpenID Connect apps registered in admin. Regular users never have a password; sysadmins sign in only at /admin/ and are redirected there from the normal sign-in. Organizations at the URL root with owner and collaborator roles, a per-member project-create grant, and invites by username or email. Email invites carry a bearer token stored only as a hash. The last owner can't leave, be removed or be demoted. Permission checks live in intent/access.py. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
26 lines
947 B
HTML
26 lines
947 B
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Invitations · Intent{% endblock %}
|
|
|
|
{% block content %}
|
|
<h1>Invitations</h1>
|
|
{% if invites %}
|
|
<ul>
|
|
{% for invite in invites %}
|
|
<li>
|
|
<p>
|
|
<strong>{{ invite.org.name }}</strong>, as {{ invite.get_role_display|lower }}
|
|
{% if invite.invited_by %}(invited by {{ invite.invited_by.username }}){% endif %}
|
|
</p>
|
|
<form method="post" action="{% url 'invites:respond' invite_id=invite.pk %}">
|
|
{% csrf_token %}
|
|
<button type="submit" name="action" value="accept">Accept <span class="visually-hidden">{{ invite.org.name }}</span></button>
|
|
<button type="submit" name="action" value="decline">Decline <span class="visually-hidden">{{ invite.org.name }}</span></button>
|
|
</form>
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
{% else %}
|
|
<p>No pending invitations.</p>
|
|
{% endif %}
|
|
{% endblock %}
|