Reads and writes the users table. Its Users carry the password hash and email, so a route strips them with toPublicUser or toSelfUser before answering. routes/users.ts is its main caller; lib/auth.ts checks every token against getSessionState.

Functions

f
assertLocalUser(user: User): void

Throws a 400 when user's account lives on another instance (isRemoteUser), whose password, email, avatar and name are that instance's to change. The routes that change them call it first.

f
createRemoteUser(
request: { username: string; email: string; },
inviterId: string | null
): User

Creates the account of a user from another instance, named username (their handle here, name@host), with no password, for federation-service.ts, which links it to their identity there in the same transaction. inviterId is whoever invited them, or null when their instance is trusted.

f
createUser(
request: RegisterUserRequest,
inviterId: string | null
): Promise<User>

Creates a user with the user role, invited by inviterId, for POST /api/users. The caller has validated request and claimed the invite.

f
getInviteTree(userId: string): Invitee[]

Returns everyone userId invited, and everyone they invited in turn, eleven levels deep at most, in sign-up order, for the profile page's invite tree (GET /api/users/:key/invitees).

f
getSessionState(userId: string):
{ role: Role; tokensValidAfter: string | null; }
| undefined

Returns the user's live role and their last password change, before which their tokens don't count, or undefined when the user is gone, or comes from another instance while an admin blocks it or the deployment turns sign-ins from other instances off (FEDERATION.incoming). lib/auth.ts checks every session and media token against it.

f
getUserByEmail(email: string): User | null

Returns the local user whose email is email, in any case, or null, for requestPasswordReset. An account from another instance has no password here to reset.

f
getUserById(userId: string): User

Returns user userId, with their hash and email.

f
getUserByUsername(username: string): User

Returns the user named username now, in any case, with their hash and email. Signing in takes it: a former name doesn't sign in.

f
listNewUsers(
from: Date,
to: Date
): PublicUser[]

Returns the users who joined from from to to, in sign-up order, each with the name of whoever invited them. The community service gathers them for the /community page and the digests.

f
renameUser(
userId: string,
username: string
): User

Renames user userId to username, for PATCH /api/users/:key/username, which only user:manage may call: users can't rename themselves. Returns them renamed. The old name becomes an alias of theirs for good, so /@old/… still reaches them and nobody else may take it; a change of case alone leaves none, since names are looked up in any case. Taking back a former name of their own is allowed. Their dumps' and playlists' slugs belong to their id, so their paths follow the new name.

f
resolveUserKey(key: string): User

Returns the user an API path's key names: @name by their name, current or former (resolveUsername), anything else by their id. Every route under /api/users/:key resolves its key with it.

f
resolveUsername(username: string): User

Returns the user who is or was named username, in any case, or by the handle another instance gives them (localHandle): a page or an API path naming a user so reaches them, and the caller sends the client on to their current name.

f
revokeSessions(
userId: string,
at: Date,
reason: string
): void

Ends every session of user userId opened before at, closing their sockets with reason: their tokens stop counting (users.tokens_valid_after, which getSessionState reads). A password change calls it, and so does the sign-out of a user from another instance, when that instance says so or an admin blocks it.

f
searchUsers(
query: string,
limit: number
): UserSuggestion[]

Returns up to limit users whose name starts with query, for the editor's

f
searchUsersGlobal(
query: string,
limit: number
): PublicUser[]

Returns up to limit users whose name or description contains query, for the /search page (GET /api/search). They are already public profiles.

f
sendWelcomeEmail(user: User): void

Emails user the welcome message, if email is configured. The register route calls it once the account exists, and doesn't wait: a slow or failing SMTP server mustn't hold up the sign-up, so a failure is only logged.

f
setUserAvatar(
userId: string,
data: Uint8Array
): Promise<User>

Makes the image data user userId's avatar and returns them, for an upload (PUT /api/me/avatar) and for the avatar a user from another instance has there (federation-service.ts). Presence alone would update only the online list, so it also sends user_updated, which reaches every avatar on screen, its bumped updatedAt busting their cache.

f
setUsername(
userId: string,
username: string
): User

Names user userId username, keeping the old name as their alias as renameUser describes, and returns them. The caller has checked the name: renameUser checks a local one, and federation-service.ts the handle of a user renamed on their home instance.

f
updateUser(
userId: string,
request: UpdateUserRequest
): Promise<User>

Applies request to user userId and returns the updated user. It trusts request: the routes pick the fields a caller may change. The username changes through renameUser alone, which keeps the old one as an alias. A new password also ends every session opened before it and closes the user's sockets, so the caller must issue fresh tokens if the user is to stay signed in. A description of null keeps the current one.