pr_01m47d15m3e54sn21z27rpy5n9/packages/contracts/src/identity.ts

170 lines6,487 bytesCodeBlame

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

Initial g1t: services, event bus, intents and attempts1import type { Result } from "./result";
2
Email verification, password reset, and Git for AI scale positioning3export type User = {
4 id: string;
5 username: string;
6 /**
7 * Whether the account's email address is confirmed. Only set on users
8 * resolved from credentials; unverified accounts cannot change anything.
9 */
10 verified?: boolean;
Workspaces own repositories11 /**
12 * The workspaces this user belongs to. Set on users resolved from
13 * credentials, so any service can authorize from it.
14 */
15 workspaces?: Membership[];
Email verification, password reset, and Git for AI scale positioning16};
Initial g1t: services, event bus, intents and attempts17
Workspaces own repositories18/** What a member may do: an owner also manages the workspace's members. */
19export type Role = "owner" | "member";
20
21export type Membership = { slug: string; role: Role };
22
23/**
24 * A workspace: the owner of repositories, and the first segment of their
25 * URLs. A person's own space and a team's are the same thing.
26 */
27export type Workspace = {
28 id: string;
29 slug: string;
30 name: string;
31 /** RFC 3339. */
32 createdAt: string;
33 memberCount: number;
34};
35
36export type Member = { username: string; role: Role };
37
Initial g1t: services, event bus, intents and attempts38/** Who is asking. Every read and write in every service takes one. */
39export type Viewer = User | null;
40
41export type SshKey = {
42 id: string;
43 title: string;
44 fingerprint: string;
RFC 3339 timestamps in identity and repos45 /** RFC 3339. */
46 createdAt: string;
Initial g1t: services, event bus, intents and attempts47};
48
RFC 3339 timestamps in identity and repos49export type AccessToken = { id: string; name: string; createdAt: string };
Initial g1t: services, event bus, intents and attempts50
Device sign-in replaces registering and minting tokens over the API51export type DeviceStart = {
52 /** Secret held by the tool and exchanged for a token once approved. */
53 deviceCode: string;
54 /** Short code shown to the person, e.g. `WDJB-MJHT`. */
55 userCode: string;
56 /** Seconds until both codes stop working. */
57 expiresIn: number;
58 /** Seconds the tool should wait between polls. */
59 interval: number;
60};
61
62export type DeviceRequest = { userCode: string; clientName: string };
63
64export type DeviceClaim =
65 | { status: "pending" | "denied" | "expired" }
66 | { status: "approved"; token: string; user: User };
67
OAuth 2.1 sign-in for MCP clients and other applications68/** What the site passes on once a person has approved an application. */
69export type OAuthApproval = {
70 clientId: string;
71 /** Shown wherever the application's access is listed. */
72 clientName: string;
73 redirectUri: string;
74 /** PKCE challenge, method S256. */
75 codeChallenge: string;
76};
77
78export type OAuthTokens = {
79 accessToken: string;
80 /** Works once; using it returns the next one. */
81 refreshToken: string;
82 /** Seconds until the access token stops working. */
83 expiresIn: number;
84};
85
86/** An application a person has signed in to. */
87export type OAuthGrant = {
88 id: string;
89 clientName: string;
90 /** RFC 3339. */
91 createdAt: string;
92 /** RFC 3339. */
93 lastUsedAt: string;
94};
95
Initial g1t: services, event bus, intents and attempts96/** Accounts, credentials and sessions. */
97export interface IdentityApi {
API and MCP server, Rust identity service, registration, site redesign98 /** Creates an account and signs it in. */
99 register(username: string, email: string, password: string): Promise<Result<{ user: User; sessionToken: string }>>;
Initial g1t: services, event bus, intents and attempts100 /** Verifies a username and password for website sign-in. */
101 signIn(username: string, password: string): Promise<Result<{ user: User; sessionToken: string }>>;
102 signOut(sessionToken: string): Promise<void>;
Email verification, password reset, and Git for AI scale positioning103
104 /** Sends the confirmation email again. */
105 resendVerification(user: User): Promise<Result<boolean>>;
106 /** Confirms the address the emailed token was sent to. */
107 verifyEmail(token: string): Promise<Result<User>>;
108 /** Emails a reset link if the address has an account. Always resolves. */
109 requestPasswordReset(email: string): Promise<boolean>;
110 /** Sets a new password from an emailed token and ends every session. */
111 resetPassword(token: string, password: string): Promise<Result<User>>;
112
Device sign-in replaces registering and minting tokens over the API113 /**
114 * Device sign-in (RFC 8628). A tool starts a request, a person approves
115 * its short code in a browser, and the tool claims an access token.
116 */
117 deviceStart(clientName: string): Promise<DeviceStart>;
118 /** What a user code is asking for, or null if it is not valid. */
119 deviceLookup(userCode: string): Promise<DeviceRequest | null>;
120 deviceResolve(userCode: string, user: User, approve: boolean): Promise<Result<boolean>>;
121 deviceClaim(deviceCode: string): Promise<DeviceClaim>;
122
OAuth 2.1 sign-in for MCP clients and other applications123 /**
124 * OAuth 2.1 for applications that sign a person in through the browser.
125 * The caller has checked the client and its redirect address; this
126 * returns the one-time code the application exchanges for tokens.
127 */
128 oauthAuthorize(user: User, approval: OAuthApproval): Promise<{ code: string }>;
129 /** Redeems a code. It works once, for that client, with the PKCE verifier. */
130 oauthExchange(code: string, codeVerifier: string, clientId: string, redirectUri: string): Promise<Result<OAuthTokens>>;
131 /** Trades a refresh token for new tokens; the old ones stop working. */
132 oauthRefresh(refreshToken: string, clientId: string): Promise<Result<OAuthTokens>>;
133 /** Applications the user has signed in to, most recently used first. */
134 listOAuthGrants(user: User): Promise<OAuthGrant[]>;
135 /** Signs an application out. */
136 revokeOAuthGrant(user: User, id: string): Promise<void>;
137
Workspaces own repositories138 createWorkspace(user: User, slug: string, name: string): Promise<Result<Workspace>>;
139 /** Public details of a workspace, or null. */
140 getWorkspace(slug: string): Promise<Workspace | null>;
141 /** Members only. */
142 listMembers(slug: string, viewer: Viewer): Promise<Result<Member[]>>;
143 /** Owners only. */
144 addMember(actor: User, slug: string, username: string): Promise<Result<boolean>>;
145 /** Owners only. */
146 removeMember(actor: User, slug: string, username: string): Promise<Result<boolean>>;
147
Initial g1t: services, event bus, intents and attempts148 userForSession(sessionToken: string): Promise<Viewer>;
149
150 /** Verifies git credentials: the account password or an access token. */
151 userForGitCredentials(username: string, secret: string): Promise<Viewer>;
API and MCP server, Rust identity service, registration, site redesign152 /** Resolves a `g1t_…` access token, as sent to the API and MCP server. */
153 userForAccessToken(token: string): Promise<Viewer>;
Initial g1t: services, event bus, intents and attempts154 userForSshKey(fingerprint: string): Promise<Viewer>;
155 userByUsername(username: string): Promise<Viewer>;
156
157 listSshKeys(user: User): Promise<SshKey[]>;
158 /** Takes one line in OpenSSH public key format. */
159 addSshKey(user: User, title: string, publicKey: string): Promise<Result<SshKey>>;
160 removeSshKey(user: User, id: string): Promise<void>;
161
162 listAccessTokens(user: User): Promise<AccessToken[]>;
163 /** The plaintext token is returned once and never stored. */
Account dropdown, llms.txt onboarding, hosted agent runner (not yet deployed)164 /**
165 * With `ttlSeconds` the token expires and is left out of the user's list;
166 * that form is used for hosted attempts.
167 */
168 createAccessToken(user: User, name: string, ttlSeconds?: number): Promise<{ token: string; info: AccessToken }>;
Initial g1t: services, event bus, intents and attempts169 removeAccessToken(user: User, id: string): Promise<void>;
170}