v0.7.0 d244a03

session.proto RawHistoryFolder

1// SPDX-License-Identifier: MIT
2
3syntax = "proto3";
4
5package ermite;
6
7import "google/protobuf/timestamp.proto";
8
9// SessionService manages the owner's browser sessions and passkeys. The
10// browser itself never calls it: it signs in by opening the link that
11// CreateLoginLink returns, or with a passkey on the web's sign-in page, and
12// signs out by posting to the web's logout route. Registering a passkey and
13// signing in with one are browser-only ceremonies and are not part of this
14// API.
15//
16// Every RPC is owner-only: it needs the root token, or a stored token that
17// holds every scope and is not restricted to repositories. Any other caller
18// gets permission_denied. Sessions do not go through this API: the Connect
19// API accepts bearer tokens only and ignores cookies.
20//
21// Servers that implement this service list "session" in
22// GetVersionResponse.features. They also list "passkeys" when passkeys are
23// available (they need an https public URL with a DNS host name); without it,
24// ListPasskeys and RemovePasskey fail with failed_precondition.
25service SessionService {
26  // CreateLoginLink creates a one-time link that signs the owner's browser
27  // in. The link is valid for a short time (about a minute), can be used
28  // once, and is kept in memory only: a server restart voids it. Opening it
29  // shows a confirmation page; only confirming it consumes the link and sets
30  // the session. Creating a new link does not void an earlier one. Fails with
31  // resource_exhausted when too many links are pending.
32  rpc CreateLoginLink(CreateLoginLinkRequest) returns (CreateLoginLinkResponse);
33  // SignOutEverywhere ends every browser session at once, including those on
34  // other devices. Pending login links are not affected. Tokens are not
35  // affected either: revoke them with TokenService.
36  rpc SignOutEverywhere(SignOutEverywhereRequest) returns (SignOutEverywhereResponse);
37  // ListPasskeys lists the owner's registered passkeys, oldest first. Fails
38  // with failed_precondition when the server has passkeys disabled.
39  rpc ListPasskeys(ListPasskeysRequest) returns (ListPasskeysResponse);
40  // RemovePasskey removes one passkey. It also signs out every browser
41  // session, on every device, like SignOutEverywhere. Fails with not_found
42  // for an unknown id, invalid_argument for an id that is not base64url, and
43  // failed_precondition when the server has passkeys disabled.
44  rpc RemovePasskey(RemovePasskeyRequest) returns (RemovePasskeyResponse);
45}
46
47// CreateLoginLinkRequest is empty.
48message CreateLoginLinkRequest {}
49
50// CreateLoginLinkResponse holds the link.
51message CreateLoginLinkResponse {
52  // Url is the absolute link to open in a browser, on the public URL of the
53  // server. It holds a secret: clients print it to the terminal and nowhere
54  // else, and never log it.
55  string url = 1;
56  // ExpiresAt is when the link stops working if it is not used.
57  google.protobuf.Timestamp expires_at = 2;
58}
59
60// SignOutEverywhereRequest is empty.
61message SignOutEverywhereRequest {}
62
63// SignOutEverywhereResponse is empty.
64message SignOutEverywhereResponse {}
65
66// Passkey is a WebAuthn credential that can sign the owner in. It never
67// carries key material.
68message Passkey {
69  // Id is the credential id, base64url without padding. Pass it to
70  // RemovePasskey.
71  string id = 1;
72  // Name is the label the owner gave the passkey when registering it.
73  string name = 2;
74  // CreatedAt is when the passkey was registered.
75  google.protobuf.Timestamp created_at = 3;
76  // LastUsedAt is when the passkey last signed the owner in. It is unset
77  // when the passkey was never used.
78  google.protobuf.Timestamp last_used_at = 4;
79  // Synced is true when the authenticator reports the credential as backed
80  // up (the backup state flag), for example a passkey synced by a platform or
81  // a password manager.
82  bool synced = 5;
83}
84
85// ListPasskeysRequest is empty.
86message ListPasskeysRequest {}
87
88// ListPasskeysResponse holds the passkeys.
89message ListPasskeysResponse {
90  // Passkeys are the registered passkeys, oldest first.
91  repeated Passkey passkeys = 1;
92}
93
94// RemovePasskeyRequest names the passkey to remove.
95message RemovePasskeyRequest {
96  // Id is the credential id from Passkey.id.
97  string id = 1;
98}
99
100// RemovePasskeyResponse is empty.
101message RemovePasskeyResponse {}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 2

Tags 18

↑↓ moveenter openesc close