| 1 |
{% extends "base.html" %} |
| 2 |
{% block title %}Sign in a device{% endblock %} |
| 3 |
{% block content %} |
| 4 |
{# The mark (docs/backgrounds.md §2): brand only, no data. #} |
| 5 |
<script type="application/json" id="backdrop-data">{"scene":"mark"}</script> |
| 6 |
{% include "backdrop.html" %} |
| 7 |
<div class="head"><h1>Sign in a device <small>an app asked to use your account</small></h1></div> |
| 8 |
{% if let Some(e) = error %}<p class="error">{{ e }}</p>{% endif %} |
| 9 |
{% if let Some(d) = done %} |
| 10 |
<section class="card wide device-done {% if d.approved %}ok{% else %}no{% endif %}"> |
| 11 |
{% if d.approved %} |
| 12 |
<h2><span class="device-mark" aria-hidden="true">✓</span> Signed in</h2> |
| 13 |
<p><strong>{{ d.client }}</strong> is now signed in as <strong>{{ d.username }}</strong>. You can close this page and return to it: it picks up its token by itself, so there is nothing to copy or enter.</p> |
| 14 |
<p class="small mute">It is listed under <a href="/settings/tokens">Settings → Tokens</a>, where you can revoke it.</p> |
| 15 |
{% else %} |
| 16 |
<h2><span class="device-mark" aria-hidden="true">✕</span> Denied</h2> |
| 17 |
<p><strong>{{ d.client }}</strong> was not signed in, and its code no longer works.</p> |
| 18 |
{% endif %} |
| 19 |
<p class="small"><a href="/device">Sign in another device</a></p> |
| 20 |
</section> |
| 21 |
{% else if let Some((d, asked)) = pending %} |
| 22 |
<form class="card wide" method="post" action="/device"> |
| 23 |
<input type="hidden" name="_csrf" value="{{ shell.csrf }}"> |
| 24 |
<input type="hidden" name="code" value="{{ d.user_code }}"> |
| 25 |
<h2><strong>{{ d.client }}</strong> wants to sign in as you</h2> |
| 26 |
<p class="small">Code <code>{{ d.user_code }}</code>, asked for <time title="{{ d.created_ms|when_i }}">{{ d.created_ms|ago_i }}</time>{% if !d.requester.is_empty() %} from <code>{{ d.requester }}</code>{% endif %}.</p> |
| 27 |
<p class="warn small">Approve only a code you started yourself, just now, on your own device. If someone sent you this code or link, deny it: they are asking for access to your account.</p> |
| 28 |
<p class="small">The app gets a token with what you allow here. It expires after 90 days without use, and you can revoke it under Settings → Tokens.</p> |
| 29 |
<label>Allow it to</label> |
| 30 |
<div class="scopes"> |
| 31 |
{% for (name, what) in asked %}<label><input type="checkbox" name="scopes" value="{{ name }}" checked> <code>{{ name }}</code> <span class="small mute">{{ what }}</span></label>{% endfor %} |
| 32 |
</div> |
| 33 |
<button type="submit" name="action" value="approve">APPROVE</button> |
| 34 |
<button type="submit" name="action" value="deny" class="secondary">DENY</button> |
| 35 |
</form> |
| 36 |
{% else %} |
| 37 |
<form class="card" method="post" action="/device"> |
| 38 |
<input type="hidden" name="_csrf" value="{{ shell.csrf }}"> |
| 39 |
<label for="code">The code your app shows</label> |
| 40 |
<input type="text" id="code" name="code" value="{{ code }}" required autofocus autocomplete="off" placeholder="BCDF-GHJK" style="text-transform:uppercase"> |
| 41 |
<button type="submit" name="action" value="lookup">CONTINUE</button> |
| 42 |
</form> |
| 43 |
{% endif %} |
| 44 |
{% endblock %} |