@fonoster/identity-client 0.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Fonoster Inc
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,111 @@
1
+ import * as grpc from "@grpc/grpc-js";
2
+ export interface CreateUserRequest {
3
+ name: string;
4
+ email: string;
5
+ password: string;
6
+ phone?: string;
7
+ avatar?: string;
8
+ }
9
+ export interface ExchangeCredentialsRequest {
10
+ username: string;
11
+ password: string;
12
+ twoFactorCode?: string;
13
+ }
14
+ export interface ExchangeResponse {
15
+ idToken?: string;
16
+ accessToken: string;
17
+ refreshToken: string;
18
+ }
19
+ export interface Workspace {
20
+ ref: string;
21
+ name: string;
22
+ ownerRef: string;
23
+ accessKeyId: string;
24
+ createdAt?: number;
25
+ updatedAt?: number;
26
+ }
27
+ export interface WorkspaceMember {
28
+ ref: string;
29
+ userRef: string;
30
+ name: string;
31
+ email: string;
32
+ role: string;
33
+ status: string;
34
+ createdAt?: number;
35
+ updatedAt?: number;
36
+ }
37
+ export interface InviteMemberRequest {
38
+ email: string;
39
+ role: string;
40
+ name?: string;
41
+ }
42
+ export interface WorkspaceAccess {
43
+ accessKeyId: string;
44
+ role: string;
45
+ }
46
+ /** Claims carried by an Identity-issued access token. */
47
+ export interface AccessClaims {
48
+ /** User ref (JWT subject). */
49
+ sub: string;
50
+ /** The user's own access key id (US…). */
51
+ accessKeyId: string;
52
+ /** Workspaces the user can act in, with their role. */
53
+ access: WorkspaceAccess[];
54
+ }
55
+ /**
56
+ * Lightweight, stateless client for the Fonoster Identity gRPC service. Targets
57
+ * any Identity endpoint and wraps the callback-based stubs in promises.
58
+ *
59
+ * Authenticated calls accept the caller's access `token` and active `accessKeyId`
60
+ * per call, forwarded as gRPC metadata — so a server can act on behalf of many
61
+ * different callers using one client instance.
62
+ */
63
+ export declare class IdentityClient {
64
+ private readonly client;
65
+ private cachedPublicKey;
66
+ constructor(endpoint: string, credentials?: grpc.ChannelCredentials);
67
+ private unary;
68
+ getPublicKey(): Promise<{
69
+ publicKey: string;
70
+ }>;
71
+ /**
72
+ * Verifies an Identity-issued RS256 access token using Identity's public key
73
+ * (fetched once via `getPublicKey` and cached). Returns the claims, or `null`
74
+ * when the token is missing, malformed, expired, or otherwise invalid.
75
+ */
76
+ verifyToken(token: string): Promise<AccessClaims | null>;
77
+ createUser(request: CreateUserRequest): Promise<{
78
+ ref: string;
79
+ }>;
80
+ exchangeCredentials(request: ExchangeCredentialsRequest): Promise<ExchangeResponse>;
81
+ exchangeRefreshToken(refreshToken: string): Promise<ExchangeResponse>;
82
+ createWorkspace(name: string, token: string): Promise<{
83
+ ref: string;
84
+ }>;
85
+ listWorkspaces(token: string): Promise<{
86
+ items: Workspace[];
87
+ nextPageToken?: string;
88
+ }>;
89
+ getWorkspace(ref: string, token: string): Promise<Workspace>;
90
+ updateWorkspace(ref: string, name: string, token: string): Promise<{
91
+ ref: string;
92
+ }>;
93
+ listWorkspaceMembers(accessKeyId: string, token: string): Promise<{
94
+ items: WorkspaceMember[];
95
+ nextPageToken?: string;
96
+ }>;
97
+ inviteUserToWorkspace(request: InviteMemberRequest, accessKeyId: string, token: string): Promise<{
98
+ userRef: string;
99
+ }>;
100
+ removeUserFromWorkspace(userRef: string, accessKeyId: string, token: string): Promise<{
101
+ userRef: string;
102
+ }>;
103
+ resendWorkspaceMembershipInvitation(userRef: string, accessKeyId: string, token: string): Promise<{
104
+ userRef: string;
105
+ }>;
106
+ sendResetPasswordCode(username: string, resetPasswordUrl: string): Promise<void>;
107
+ resetPassword(username: string, password: string, verificationCode: string): Promise<void>;
108
+ close(): void;
109
+ }
110
+ /** Convenience factory. The endpoint is required — no environment-variable fallback. */
111
+ export declare function createIdentityClient(endpoint: string, credentials?: grpc.ChannelCredentials): IdentityClient;
package/dist/index.js ADDED
@@ -0,0 +1,181 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.IdentityClient = void 0;
40
+ exports.createIdentityClient = createIdentityClient;
41
+ /**
42
+ * Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
43
+ * http://github.com/fonoster/fonoster
44
+ *
45
+ * This file is part of Fonoster
46
+ *
47
+ * Licensed under the MIT License (the "License");
48
+ * you may not use this file except in compliance with
49
+ * the License. You may obtain a copy of the License at
50
+ *
51
+ * https://opensource.org/licenses/MIT
52
+ *
53
+ * Unless required by applicable law or agreed to in writing, software
54
+ * distributed under the License is distributed on an "AS IS" BASIS,
55
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
56
+ * See the License for the specific language governing permissions and
57
+ * limitations under the License.
58
+ */
59
+ const node_path_1 = require("node:path");
60
+ const grpc = __importStar(require("@grpc/grpc-js"));
61
+ const protoLoader = __importStar(require("@grpc/proto-loader"));
62
+ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
63
+ const PROTO_PATH = (0, node_path_1.join)(__dirname, "..", "proto", "identity.proto");
64
+ const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
65
+ keepCase: false,
66
+ longs: String,
67
+ enums: String,
68
+ defaults: false,
69
+ arrays: true,
70
+ oneofs: true
71
+ });
72
+ const proto = grpc.loadPackageDefinition(packageDefinition);
73
+ const IdentityService = proto.fonoster.identity.v1beta2.Identity;
74
+ /**
75
+ * Lightweight, stateless client for the Fonoster Identity gRPC service. Targets
76
+ * any Identity endpoint and wraps the callback-based stubs in promises.
77
+ *
78
+ * Authenticated calls accept the caller's access `token` and active `accessKeyId`
79
+ * per call, forwarded as gRPC metadata — so a server can act on behalf of many
80
+ * different callers using one client instance.
81
+ */
82
+ class IdentityClient {
83
+ constructor(endpoint, credentials = grpc.credentials.createInsecure()) {
84
+ this.cachedPublicKey = null;
85
+ this.client = new IdentityService(endpoint, credentials);
86
+ }
87
+ unary(method, request, meta = {}) {
88
+ const metadata = new grpc.Metadata();
89
+ if (meta.token)
90
+ metadata.set("token", meta.token);
91
+ if (meta.accessKeyId)
92
+ metadata.set("accesskeyid", meta.accessKeyId);
93
+ const client = this.client;
94
+ return new Promise((resolve, reject) => {
95
+ client[method](request, metadata, (err, res) => err ? reject(err) : resolve(res));
96
+ });
97
+ }
98
+ getPublicKey() {
99
+ return this.unary("getPublicKey", {});
100
+ }
101
+ /**
102
+ * Verifies an Identity-issued RS256 access token using Identity's public key
103
+ * (fetched once via `getPublicKey` and cached). Returns the claims, or `null`
104
+ * when the token is missing, malformed, expired, or otherwise invalid.
105
+ */
106
+ async verifyToken(token) {
107
+ try {
108
+ if (!this.cachedPublicKey) {
109
+ const { publicKey } = await this.getPublicKey();
110
+ this.cachedPublicKey = publicKey;
111
+ }
112
+ const decoded = jsonwebtoken_1.default.verify(token, this.cachedPublicKey, {
113
+ algorithms: ["RS256"]
114
+ });
115
+ if (typeof decoded === "string")
116
+ return null;
117
+ const claims = decoded;
118
+ if (!claims.sub || !claims.accessKeyId)
119
+ return null;
120
+ return {
121
+ sub: claims.sub,
122
+ accessKeyId: claims.accessKeyId,
123
+ access: claims.access ?? []
124
+ };
125
+ }
126
+ catch {
127
+ return null;
128
+ }
129
+ }
130
+ createUser(request) {
131
+ return this.unary("createUser", request);
132
+ }
133
+ exchangeCredentials(request) {
134
+ return this.unary("exchangeCredentials", request);
135
+ }
136
+ exchangeRefreshToken(refreshToken) {
137
+ return this.unary("exchangeRefreshToken", { refreshToken });
138
+ }
139
+ createWorkspace(name, token) {
140
+ return this.unary("createWorkspace", { name }, { token });
141
+ }
142
+ listWorkspaces(token) {
143
+ return this.unary("listWorkspaces", {}, { token });
144
+ }
145
+ getWorkspace(ref, token) {
146
+ return this.unary("getWorkspace", { ref }, { token });
147
+ }
148
+ updateWorkspace(ref, name, token) {
149
+ return this.unary("updateWorkspace", { ref, name }, { token });
150
+ }
151
+ listWorkspaceMembers(accessKeyId, token) {
152
+ return this.unary("listWorkspaceMembers", {}, { token, accessKeyId });
153
+ }
154
+ inviteUserToWorkspace(request, accessKeyId, token) {
155
+ return this.unary("inviteUserToWorkspace", request, { token, accessKeyId });
156
+ }
157
+ removeUserFromWorkspace(userRef, accessKeyId, token) {
158
+ return this.unary("removeUserFromWorkspace", { userRef }, { token, accessKeyId });
159
+ }
160
+ resendWorkspaceMembershipInvitation(userRef, accessKeyId, token) {
161
+ return this.unary("resendWorkspaceMembershipInvitation", { userRef }, { token, accessKeyId });
162
+ }
163
+ sendResetPasswordCode(username, resetPasswordUrl) {
164
+ return this.unary("sendResetPasswordCode", { username, resetPasswordUrl });
165
+ }
166
+ resetPassword(username, password, verificationCode) {
167
+ return this.unary("resetPassword", {
168
+ username,
169
+ password,
170
+ verificationCode
171
+ });
172
+ }
173
+ close() {
174
+ this.client.close();
175
+ }
176
+ }
177
+ exports.IdentityClient = IdentityClient;
178
+ /** Convenience factory. The endpoint is required — no environment-variable fallback. */
179
+ function createIdentityClient(endpoint, credentials) {
180
+ return new IdentityClient(endpoint, credentials);
181
+ }
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@fonoster/identity-client",
3
+ "version": "0.19.1",
4
+ "description": "Lightweight client for the Fonoster Identity gRPC service",
5
+ "license": "MIT",
6
+ "main": "dist/index",
7
+ "types": "dist/index",
8
+ "scripts": {
9
+ "prebuild": "rimraf ./dist tsconfig.tsbuildinfo && node scripts/sync-proto.mjs",
10
+ "build": "tsc -p tsconfig.json",
11
+ "clean": "rimraf ./dist node_modules tsconfig.tsbuildinfo proto"
12
+ },
13
+ "dependencies": {
14
+ "@grpc/grpc-js": "~1.10.6",
15
+ "@grpc/proto-loader": "^0.7.15",
16
+ "jsonwebtoken": "^9.0.2"
17
+ },
18
+ "devDependencies": {
19
+ "@types/jsonwebtoken": "^9.0.6",
20
+ "@types/node": "^20.0.0",
21
+ "rimraf": "^5.0.0",
22
+ "typescript": "^5.9.0"
23
+ },
24
+ "files": [
25
+ "dist",
26
+ "proto"
27
+ ],
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
31
+ "gitHead": "4c28def9ff1aebbbaf2e23a8944cf3cf49c4da1e"
32
+ }
@@ -0,0 +1,359 @@
1
+ /*
2
+ * Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
3
+ * http://github.com/fonoster/fonoster
4
+ *
5
+ * This file is part of Fonoster
6
+ *
7
+ * Licensed under the MIT License (the "License");
8
+ * you may not use this file except in compliance with
9
+ * the License. You may obtain a copy of the License at
10
+ *
11
+ * https://opensource.org/licenses/MIT
12
+ *
13
+ * Unless required by applicable law or agreed to in writing, software
14
+ * distributed under the License is distributed on an "AS IS" BASIS,
15
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ */
19
+ syntax = "proto3";
20
+
21
+ package fonoster.identity.v1beta2;
22
+
23
+ import "google/protobuf/empty.proto";
24
+
25
+ service Identity {
26
+ // Workspace actions
27
+ rpc CreateWorkspace (CreateWorkspaceRequest) returns (CreateWorkspaceResponse) {}
28
+ rpc DeleteWorkspace (DeleteWorkspaceRequest) returns (DeleteWorkspaceResponse) {}
29
+ rpc GetWorkspace (GetWorkspaceRequest) returns (Workspace) {}
30
+ rpc ListWorkspaces (ListWorkspacesRequest) returns (ListWorkspacesResponse) {}
31
+ rpc UpdateWorkspace (UpdateWorkspaceRequest) returns (UpdateWorkspaceResponse) {}
32
+ rpc InviteUserToWorkspace (InviteUserToWorkspaceRequest) returns (InviteUserToWorkspaceResponse) {}
33
+ rpc RemoveUserFromWorkspace (RemoveUserFromWorkspaceRequest) returns (RemoveUserFromWorkspaceResponse) {}
34
+ rpc ResendWorkspaceMembershipInvitation (ResendWorkspaceMembershipInvitationRequest) returns (ResendWorkspaceMembershipInvitationResponse) {}
35
+ rpc ListWorkspaceMembers (ListWorkspaceMembersRequest) returns (ListWorkspaceMembersResponse) {}
36
+
37
+ // User specific actions
38
+ rpc CreateUser (CreateUserRequest) returns (CreateUserResponse) {}
39
+ rpc CreateUserWithOauth2Code (CreateUserWithOauth2CodeRequest) returns (ExchangeCredentialsResponse) {}
40
+ rpc GetUser (GetUserRequest) returns (User) {}
41
+ rpc UpdateUser (UpdateUserRequest) returns (UpdateUserResponse) {}
42
+ rpc DeleteUser (DeleteUserRequest) returns (DeleteUserResponse) {}
43
+ rpc SendVerificationCode (SendVerificationCodeRequest) returns (google.protobuf.Empty) {}
44
+ rpc VerifyCode (VerifyCodeRequest) returns (google.protobuf.Empty) {}
45
+ rpc SendResetPasswordCode (SendResetPasswordCodeRequest) returns (google.protobuf.Empty) {}
46
+ rpc ResetPassword (ResetPasswordRequest) returns (google.protobuf.Empty) {}
47
+
48
+ // ApiKey actions
49
+ rpc CreateApiKey (CreateApiKeyRequest) returns (CreateApiKeyResponse) {}
50
+ rpc DeleteApiKey (DeleteApiKeyRequest) returns (DeleteApiKeyResponse) {}
51
+ rpc ListApiKeys (ListApiKeysRequest) returns (ListApiKeysResponse) {}
52
+ rpc RegenerateApiKey (RegenerateApiKeyRequest) returns (RegenerateApiKeyResponse) {}
53
+
54
+ // Token exchange actions
55
+ rpc ExchangeCredentials (ExchangeCredentialsRequest) returns (ExchangeCredentialsResponse) {}
56
+ rpc ExchangeApiKey (ExchangeApiKeyRequest) returns (ExchangeApiKeyResponse) {}
57
+ rpc ExchangeOauth2Code (ExchangeOauth2CodeRequest) returns (ExchangeOauth2CodeResponse) {}
58
+ rpc ExchangeRefreshToken (ExchangeRefreshTokenRequest) returns (ExchangeRefreshTokenResponse) {}
59
+ rpc RevokeToken (RevokeTokenRequest) returns (RevokeTokenResponse) {}
60
+
61
+ // Get the public key for verifying JWTs
62
+ rpc GetPublicKey (google.protobuf.Empty) returns (GetPublicKeyResponse) {}
63
+ }
64
+
65
+ // Workspace Resources
66
+
67
+ message Workspace {
68
+ message Owner {
69
+ string ref = 1;
70
+ string name = 2;
71
+ string email = 3;
72
+ }
73
+
74
+ string ref = 1;
75
+ string name = 2;
76
+ string owner_ref = 3;
77
+ string access_key_id = 4;
78
+ int32 created_at = 5;
79
+ int32 updated_at = 6;
80
+ Owner owner = 7;
81
+ }
82
+
83
+ message CreateWorkspaceRequest {
84
+ string name = 1;
85
+ }
86
+
87
+ message CreateWorkspaceResponse {
88
+ string ref = 1;
89
+ }
90
+
91
+ message DeleteWorkspaceRequest {
92
+ string ref = 1;
93
+ }
94
+
95
+ message DeleteWorkspaceResponse {
96
+ string ref = 1;
97
+ }
98
+
99
+ message GetWorkspaceRequest {
100
+ string ref = 1;
101
+ }
102
+
103
+ message ListWorkspacesRequest {
104
+ string page_token = 1;
105
+ int32 page_size = 2;
106
+ }
107
+
108
+ message ListWorkspacesResponse {
109
+ repeated Workspace items = 1;
110
+ string next_page_token = 2;
111
+ }
112
+
113
+ message UpdateWorkspaceRequest {
114
+ string ref = 1;
115
+ string name = 2;
116
+ }
117
+
118
+ message UpdateWorkspaceResponse {
119
+ string ref = 1;
120
+ }
121
+
122
+ message InviteUserToWorkspaceRequest {
123
+ string email = 1;
124
+ string role = 2;
125
+ string name = 3;
126
+ }
127
+
128
+ message InviteUserToWorkspaceResponse {
129
+ string user_ref = 1;
130
+ }
131
+
132
+ message RemoveUserFromWorkspaceRequest {
133
+ string user_ref = 1;
134
+ }
135
+
136
+ message RemoveUserFromWorkspaceResponse {
137
+ string user_ref = 1;
138
+ }
139
+
140
+ message ResendWorkspaceMembershipInvitationRequest {
141
+ string user_ref = 1;
142
+ }
143
+
144
+ message ResendWorkspaceMembershipInvitationResponse {
145
+ string user_ref = 1;
146
+ }
147
+
148
+ message WorkspaceMember {
149
+ string ref = 1;
150
+ string user_ref = 2;
151
+ string name = 3;
152
+ string email = 4;
153
+ string role = 5;
154
+ string status = 6;
155
+ int32 created_at = 7;
156
+ int32 updated_at = 8;
157
+ }
158
+
159
+ message ListWorkspaceMembersRequest {
160
+ string page_token = 1;
161
+ int32 page_size = 2;
162
+ }
163
+
164
+ message ListWorkspaceMembersResponse {
165
+ repeated WorkspaceMember items = 1;
166
+ string next_page_token = 2;
167
+ }
168
+
169
+ // User Resources
170
+ enum ContactType {
171
+ EMAIL = 0;
172
+ PHONE = 1;
173
+ }
174
+
175
+ message CreateUserRequest {
176
+ string email = 1;
177
+ string phone = 5;
178
+ string password = 2;
179
+ string name = 3;
180
+ string avatar = 4;
181
+ }
182
+
183
+ message CreateUserResponse {
184
+ string ref = 1;
185
+ }
186
+
187
+ message CreateUserWithOauth2CodeRequest {
188
+ string code = 1;
189
+ }
190
+
191
+ message GetUserRequest {
192
+ string ref = 1;
193
+ }
194
+
195
+ message User {
196
+ string ref = 1;
197
+ string email = 2;
198
+ string phone = 7;
199
+ string name = 3;
200
+ string avatar = 4;
201
+ int32 created_at = 5;
202
+ int32 updated_at = 6;
203
+ }
204
+
205
+ message UpdateUserRequest {
206
+ string ref = 1;
207
+ string password = 2;
208
+ string name = 3;
209
+ string avatar = 4;
210
+ string phone = 5;
211
+ }
212
+
213
+ message UpdateUserResponse {
214
+ string ref = 1;
215
+ }
216
+
217
+ message DeleteUserRequest {
218
+ string ref = 1;
219
+ }
220
+
221
+ message DeleteUserResponse {
222
+ string ref = 1;
223
+ }
224
+
225
+ message SendVerificationCodeRequest {
226
+ ContactType contact_type = 1;
227
+ string value = 2;
228
+ }
229
+
230
+ message VerifyCodeRequest {
231
+ string username = 1;
232
+ ContactType contact_type = 2;
233
+ string value = 3;
234
+ string verification_code = 4;
235
+ }
236
+
237
+ message SendResetPasswordCodeRequest {
238
+ string username = 1;
239
+ string reset_password_url = 2;
240
+ }
241
+
242
+ message ResetPasswordRequest {
243
+ string username = 1;
244
+ string password = 2;
245
+ string verification_code = 3;
246
+ }
247
+
248
+ // ApiKey Resources
249
+
250
+ message CreateApiKeyRequest {
251
+ string role = 1;
252
+ int32 expires_at = 2;
253
+ }
254
+
255
+ message CreateApiKeyResponse {
256
+ string ref = 1;
257
+ string access_key_id = 2;
258
+ string access_key_secret = 3;
259
+ }
260
+
261
+ message DeleteApiKeyRequest {
262
+ string ref = 1;
263
+ }
264
+
265
+ message DeleteApiKeyResponse {
266
+ string ref = 1;
267
+ }
268
+
269
+ message ListApiKeysRequest {
270
+ string page_token = 1;
271
+ int32 page_size = 2;
272
+ }
273
+
274
+ message ListApiKeysResponse {
275
+ repeated ApiKey items = 1;
276
+ string next_page_token = 2;
277
+ }
278
+
279
+ message RegenerateApiKeyRequest {
280
+ string ref = 1;
281
+ }
282
+
283
+ message RegenerateApiKeyResponse {
284
+ string ref = 1;
285
+ string access_key_id = 2;
286
+ string access_key_secret = 3;
287
+ }
288
+
289
+ message ApiKey {
290
+ string ref = 1;
291
+ string access_key_id = 2;
292
+ string role = 3;
293
+ int32 expires_at = 4;
294
+ int32 created_at = 5;
295
+ int32 updated_at = 6;
296
+ }
297
+
298
+ // Token Exchange Resources
299
+
300
+ message ExchangeCredentialsRequest {
301
+ string username = 1;
302
+ string password = 2;
303
+ // Required only if the 2FA feature flag is enabled
304
+ string two_factor_code = 3;
305
+ }
306
+
307
+ message ExchangeCredentialsResponse {
308
+ string id_token = 1;
309
+ string access_token = 2;
310
+ string refresh_token = 3;
311
+ }
312
+
313
+ message ExchangeApiKeyRequest {
314
+ string access_key_id = 1;
315
+ string access_key_secret = 2;
316
+ }
317
+
318
+ message ExchangeApiKeyResponse {
319
+ string id_token = 1;
320
+ string access_token = 2;
321
+ string refresh_token = 3;
322
+ }
323
+
324
+ message ExchangeOauth2CodeRequest {
325
+ enum Oauth2Provider {
326
+ GITHUB = 0;
327
+ }
328
+ Oauth2Provider provider = 1;
329
+ string code = 2;
330
+ }
331
+
332
+ message ExchangeOauth2CodeResponse {
333
+ string id_token = 1;
334
+ string access_token = 2;
335
+ string refresh_token = 3;
336
+ }
337
+
338
+ message ExchangeRefreshTokenRequest {
339
+ string refresh_token = 1;
340
+ }
341
+
342
+ message ExchangeRefreshTokenResponse {
343
+ string id_token = 1;
344
+ string access_token = 2;
345
+ string refresh_token = 3;
346
+ }
347
+
348
+ message RevokeTokenRequest {
349
+ string token = 1;
350
+ }
351
+
352
+ message RevokeTokenResponse {
353
+ string token = 1;
354
+ }
355
+
356
+ // Message with response with the public key
357
+ message GetPublicKeyResponse {
358
+ string public_key = 1;
359
+ }