343 lines
8.7 KiB
Protocol Buffer
343 lines
8.7 KiB
Protocol Buffer
syntax = "proto3";
|
|
|
|
package forest.v1;
|
|
|
|
import "google/protobuf/timestamp.proto";
|
|
|
|
// UsersService handles user management, authentication, and profile operations.
|
|
service UsersService {
|
|
// Authentication
|
|
rpc Register(RegisterRequest) returns (RegisterResponse);
|
|
rpc Login(LoginRequest) returns (LoginResponse);
|
|
rpc RefreshToken(RefreshTokenRequest) returns (RefreshTokenResponse);
|
|
rpc Logout(LogoutRequest) returns (LogoutResponse);
|
|
|
|
// User CRUD
|
|
rpc GetUser(GetUserRequest) returns (GetUserResponse);
|
|
rpc UpdateUser(UpdateUserRequest) returns (UpdateUserResponse);
|
|
rpc DeleteUser(DeleteUserRequest) returns (DeleteUserResponse);
|
|
rpc ListUsers(ListUsersRequest) returns (ListUsersResponse);
|
|
|
|
// Stats
|
|
rpc GetUserStats(GetUserStatsRequest) returns (GetUserStatsResponse);
|
|
|
|
// Password management
|
|
rpc ChangePassword(ChangePasswordRequest) returns (ChangePasswordResponse);
|
|
|
|
// Email management
|
|
rpc AddEmail(AddEmailRequest) returns (AddEmailResponse);
|
|
rpc VerifyEmail(VerifyEmailRequest) returns (VerifyEmailResponse);
|
|
rpc RemoveEmail(RemoveEmailRequest) returns (RemoveEmailResponse);
|
|
|
|
// Social / OAuth login
|
|
rpc OAuthLogin(OAuthLoginRequest) returns (OAuthLoginResponse);
|
|
rpc LinkOAuthProvider(LinkOAuthProviderRequest) returns (LinkOAuthProviderResponse);
|
|
rpc UnlinkOAuthProvider(UnlinkOAuthProviderRequest) returns (UnlinkOAuthProviderResponse);
|
|
|
|
// Personal access tokens
|
|
rpc CreatePersonalAccessToken(CreatePersonalAccessTokenRequest) returns (CreatePersonalAccessTokenResponse);
|
|
rpc ListPersonalAccessTokens(ListPersonalAccessTokensRequest) returns (ListPersonalAccessTokensResponse);
|
|
rpc DeletePersonalAccessToken(DeletePersonalAccessTokenRequest) returns (DeletePersonalAccessTokenResponse);
|
|
|
|
// Token introspection (requires valid access token)
|
|
rpc TokenInfo(TokenInfoRequest) returns (TokenInfoResponse);
|
|
|
|
// MFA
|
|
rpc SetupMfa(SetupMfaRequest) returns (SetupMfaResponse);
|
|
rpc VerifyMfa(VerifyMfaRequest) returns (VerifyMfaResponse);
|
|
rpc DisableMfa(DisableMfaRequest) returns (DisableMfaResponse);
|
|
}
|
|
|
|
// ─── Core types ──────────────────────────────────────────────────────
|
|
|
|
message User {
|
|
string user_id = 1; // UUID
|
|
string username = 2;
|
|
repeated UserEmail emails = 3;
|
|
repeated OAuthConnection oauth_connections = 4;
|
|
bool mfa_enabled = 5;
|
|
google.protobuf.Timestamp created_at = 6;
|
|
google.protobuf.Timestamp updated_at = 7;
|
|
}
|
|
|
|
message UserEmail {
|
|
string email = 1;
|
|
bool verified = 2;
|
|
}
|
|
|
|
enum OAuthProvider {
|
|
OAUTH_PROVIDER_UNSPECIFIED = 0;
|
|
OAUTH_PROVIDER_GITHUB = 1;
|
|
OAUTH_PROVIDER_GOOGLE = 2;
|
|
OAUTH_PROVIDER_GITLAB = 3;
|
|
OAUTH_PROVIDER_MICROSOFT = 4;
|
|
}
|
|
|
|
message OAuthConnection {
|
|
OAuthProvider provider = 1;
|
|
string provider_user_id = 2;
|
|
string provider_email = 3;
|
|
google.protobuf.Timestamp linked_at = 4;
|
|
}
|
|
|
|
// ─── Authentication ──────────────────────────────────────────────────
|
|
|
|
message RegisterRequest {
|
|
string username = 1;
|
|
string email = 2;
|
|
string password = 3;
|
|
}
|
|
|
|
message RegisterResponse {
|
|
User user = 1;
|
|
AuthTokens tokens = 2;
|
|
}
|
|
|
|
message LoginRequest {
|
|
// Login with either username or email
|
|
oneof identifier {
|
|
string username = 1;
|
|
string email = 2;
|
|
}
|
|
string password = 3;
|
|
}
|
|
|
|
message LoginResponse {
|
|
User user = 1;
|
|
AuthTokens tokens = 2;
|
|
}
|
|
|
|
message RefreshTokenRequest {
|
|
string refresh_token = 1;
|
|
}
|
|
|
|
message RefreshTokenResponse {
|
|
AuthTokens tokens = 1;
|
|
}
|
|
|
|
message LogoutRequest {
|
|
string refresh_token = 1;
|
|
}
|
|
|
|
message LogoutResponse {}
|
|
|
|
message AuthTokens {
|
|
string access_token = 1;
|
|
string refresh_token = 2;
|
|
int64 expires_in_seconds = 3;
|
|
}
|
|
|
|
// ─── Token introspection ─────────────────────────────────────────────
|
|
|
|
message TokenInfoRequest {}
|
|
|
|
message TokenInfoResponse {
|
|
string user_id = 1;
|
|
int64 expires_at = 2; // Unix timestamp (seconds)
|
|
}
|
|
|
|
// ─── User CRUD ───────────────────────────────────────────────────────
|
|
|
|
message GetUserRequest {
|
|
oneof identifier {
|
|
string user_id = 1;
|
|
string username = 2;
|
|
string email = 3;
|
|
}
|
|
}
|
|
|
|
message GetUserResponse {
|
|
User user = 1;
|
|
}
|
|
|
|
message UpdateUserRequest {
|
|
string user_id = 1;
|
|
optional string username = 2;
|
|
}
|
|
|
|
message UpdateUserResponse {
|
|
User user = 1;
|
|
}
|
|
|
|
message DeleteUserRequest {
|
|
string user_id = 1;
|
|
}
|
|
|
|
message DeleteUserResponse {}
|
|
|
|
message ListUsersRequest {
|
|
int32 page_size = 1;
|
|
string page_token = 2;
|
|
optional string search = 3; // search across username, email
|
|
}
|
|
|
|
message ListUsersResponse {
|
|
repeated User users = 1;
|
|
string next_page_token = 2;
|
|
int32 total_count = 3;
|
|
}
|
|
|
|
// ─── Password management ─────────────────────────────────────────────
|
|
|
|
message ChangePasswordRequest {
|
|
string user_id = 1;
|
|
string current_password = 2;
|
|
string new_password = 3;
|
|
}
|
|
|
|
message ChangePasswordResponse {}
|
|
|
|
// ─── Email management ────────────────────────────────────────────────
|
|
|
|
message AddEmailRequest {
|
|
string user_id = 1;
|
|
string email = 2;
|
|
}
|
|
|
|
message AddEmailResponse {
|
|
UserEmail email = 1;
|
|
}
|
|
|
|
message VerifyEmailRequest {
|
|
string user_id = 1;
|
|
string email = 2;
|
|
}
|
|
|
|
message VerifyEmailResponse {}
|
|
|
|
message RemoveEmailRequest {
|
|
string user_id = 1;
|
|
string email = 2;
|
|
}
|
|
|
|
message RemoveEmailResponse {}
|
|
|
|
// ─── OAuth / Social login ────────────────────────────────────────────
|
|
|
|
message OAuthLoginRequest {
|
|
OAuthProvider provider = 1;
|
|
string authorization_code = 2;
|
|
string redirect_uri = 3;
|
|
}
|
|
|
|
message OAuthLoginResponse {
|
|
User user = 1;
|
|
AuthTokens tokens = 2;
|
|
bool is_new_user = 3;
|
|
}
|
|
|
|
message LinkOAuthProviderRequest {
|
|
string user_id = 1;
|
|
OAuthProvider provider = 2;
|
|
string authorization_code = 3;
|
|
string redirect_uri = 4;
|
|
}
|
|
|
|
message LinkOAuthProviderResponse {
|
|
OAuthConnection connection = 1;
|
|
}
|
|
|
|
message UnlinkOAuthProviderRequest {
|
|
string user_id = 1;
|
|
OAuthProvider provider = 2;
|
|
}
|
|
|
|
message UnlinkOAuthProviderResponse {}
|
|
|
|
// ─── Personal access tokens ──────────────────────────────────────────
|
|
|
|
message PersonalAccessToken {
|
|
string token_id = 1; // UUID
|
|
string name = 2;
|
|
repeated string scopes = 3;
|
|
google.protobuf.Timestamp expires_at = 4;
|
|
google.protobuf.Timestamp last_used = 5;
|
|
google.protobuf.Timestamp created_at = 6;
|
|
}
|
|
|
|
message CreatePersonalAccessTokenRequest {
|
|
string user_id = 1;
|
|
string name = 2;
|
|
repeated string scopes = 3;
|
|
// Duration in seconds; 0 = no expiry
|
|
int64 expires_in_seconds = 4;
|
|
}
|
|
|
|
message CreatePersonalAccessTokenResponse {
|
|
PersonalAccessToken token = 1;
|
|
// The raw token value, only returned on creation
|
|
string raw_token = 2;
|
|
}
|
|
|
|
message ListPersonalAccessTokensRequest {
|
|
string user_id = 1;
|
|
}
|
|
|
|
message ListPersonalAccessTokensResponse {
|
|
repeated PersonalAccessToken tokens = 1;
|
|
}
|
|
|
|
message DeletePersonalAccessTokenRequest {
|
|
string token_id = 1;
|
|
}
|
|
|
|
message DeletePersonalAccessTokenResponse {}
|
|
|
|
// ─── Stats ──────────────────────────────────────────────────────────
|
|
|
|
message GetUserStatsRequest {
|
|
oneof identifier {
|
|
string user_id = 1;
|
|
string username = 2;
|
|
}
|
|
}
|
|
|
|
message GetUserStatsResponse {
|
|
UserStats stats = 1;
|
|
}
|
|
|
|
message UserStats {
|
|
int64 total_releases = 1;
|
|
int64 successful_releases = 2;
|
|
int64 failed_releases = 3;
|
|
int64 in_progress_releases = 4;
|
|
int64 total_annotations = 5;
|
|
int64 total_uploads = 6;
|
|
}
|
|
|
|
// ─── MFA ─────────────────────────────────────────────────────────────
|
|
|
|
enum MfaType {
|
|
MFA_TYPE_UNSPECIFIED = 0;
|
|
MFA_TYPE_TOTP = 1;
|
|
}
|
|
|
|
message SetupMfaRequest {
|
|
string user_id = 1;
|
|
MfaType mfa_type = 2;
|
|
}
|
|
|
|
message SetupMfaResponse {
|
|
string mfa_id = 1; // UUID
|
|
// TOTP provisioning URI (otpauth://...)
|
|
string provisioning_uri = 2;
|
|
// Base32-encoded secret for manual entry
|
|
string secret = 3;
|
|
}
|
|
|
|
message VerifyMfaRequest {
|
|
string mfa_id = 1;
|
|
// The TOTP code to verify setup
|
|
string code = 2;
|
|
}
|
|
|
|
message VerifyMfaResponse {}
|
|
|
|
message DisableMfaRequest {
|
|
string user_id = 1;
|
|
// Current TOTP code to confirm disable
|
|
string code = 2;
|
|
}
|
|
|
|
message DisableMfaResponse {}
|