@bool-ts/guard-sdk 1.0.0-beta.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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +2 -0
  3. package/dist/constants/enums.d.ts +3 -0
  4. package/dist/constants/index.d.ts +2 -0
  5. package/dist/constants/keys.d.ts +4 -0
  6. package/dist/decorators/actionGuard.decorator.d.ts +1 -0
  7. package/dist/decorators/authState.decorator.d.ts +1 -0
  8. package/dist/decorators/controllerGuard.decorator.d.ts +1 -0
  9. package/dist/decorators/index.d.ts +3 -0
  10. package/dist/entities/index.d.ts +2 -0
  11. package/dist/entities/interceptor.d.ts +5 -0
  12. package/dist/entities/loader.d.ts +4 -0
  13. package/dist/entities/middleware.d.ts +19 -0
  14. package/dist/index.d.ts +5 -0
  15. package/dist/index.js +39 -0
  16. package/dist/index.js.map +57 -0
  17. package/dist/instances/client.d.ts +47 -0
  18. package/dist/instances/index.d.ts +1 -0
  19. package/dist/interfaces/account.interface.d.ts +6 -0
  20. package/dist/interfaces/accountCredential.interface.d.ts +7 -0
  21. package/dist/interfaces/base.d.ts +3 -0
  22. package/dist/interfaces/client.interface.d.ts +48 -0
  23. package/dist/interfaces/index.d.ts +4 -0
  24. package/package.json +50 -0
  25. package/src/constants/enums.ts +3 -0
  26. package/src/constants/index.ts +2 -0
  27. package/src/constants/keys.ts +4 -0
  28. package/src/decorators/actionGuard.decorator.ts +5 -0
  29. package/src/decorators/authState.decorator.ts +4 -0
  30. package/src/decorators/controllerGuard.decorator.ts +5 -0
  31. package/src/decorators/index.ts +3 -0
  32. package/src/entities/index.ts +2 -0
  33. package/src/entities/interceptor.ts +47 -0
  34. package/src/entities/loader.ts +20 -0
  35. package/src/entities/middleware.ts +73 -0
  36. package/src/index.ts +6 -0
  37. package/src/instances/client.ts +314 -0
  38. package/src/instances/index.ts +1 -0
  39. package/src/interfaces/account.interface.ts +7 -0
  40. package/src/interfaces/accountCredential.interface.ts +7 -0
  41. package/src/interfaces/base.ts +3 -0
  42. package/src/interfaces/client.interface.ts +52 -0
  43. package/src/interfaces/index.ts +4 -0
@@ -0,0 +1,47 @@
1
+ import type { IClient, TClientConfigs, TClientOptions } from "../interfaces/client.interface";
2
+ export declare class Client implements IClient {
3
+ #private;
4
+ private readonly configs;
5
+ private readonly options?;
6
+ private token;
7
+ /**
8
+ * Initialize BoolGuard client instance
9
+ * @param configs
10
+ * @param options
11
+ */
12
+ constructor(configs: TClientConfigs, options?: TClientOptions | undefined);
13
+ /**
14
+ * Sign JWT token with Ed25519 algorithm
15
+ * @returns
16
+ */
17
+ signToken(): Promise<string>;
18
+ /**
19
+ * Ping to BoolGuard service to check if the service is reachable
20
+ * This action should be done before any other actions.
21
+ * @returns
22
+ */
23
+ ping(): Promise<boolean>;
24
+ /**
25
+ * Create a new plain account with custom account name
26
+ * @param args
27
+ * @returns
28
+ */
29
+ createPlainAccount({ identity, password, metadata }: Parameters<IClient["createPlainAccount"]>[number]): ReturnType<IClient["createPlainAccount"]>;
30
+ /**
31
+ * Create a new email account, this action will create email record and link to account
32
+ * with random account alias generated by system.
33
+ * @param args
34
+ */
35
+ createEmailAccount({ identity, password, metadata }: Parameters<IClient["createEmailAccount"]>[number]): ReturnType<IClient["createEmailAccount"]>;
36
+ /**
37
+ * Authenticate an account with account name and password
38
+ * This action will return account info and JWT token if successful
39
+ * @param param0
40
+ */
41
+ authenticate({ identity, password }: Parameters<IClient["authenticate"]>[number]): ReturnType<IClient["authenticate"]>;
42
+ /**
43
+ * Authenticate a token and return account info if token is valid
44
+ * @param param0
45
+ */
46
+ verifyToken({ token }: Parameters<IClient["verifyToken"]>[number]): ReturnType<IClient["verifyToken"]>;
47
+ }
@@ -0,0 +1 @@
1
+ export { Client } from "./client";
@@ -0,0 +1,6 @@
1
+ export type TDefaultAccountMetadata = Record<string, string | number | Date | null | undefined>;
2
+ export interface IAccount<T = TDefaultAccountMetadata> {
3
+ uuid: string;
4
+ status: string;
5
+ metadata?: T | null;
6
+ }
@@ -0,0 +1,7 @@
1
+ export interface IAccountCredential {
2
+ uuid: string;
3
+ identity: string;
4
+ status: string;
5
+ type: string;
6
+ isVerified: boolean;
7
+ }
@@ -0,0 +1,3 @@
1
+ export type TApiResponse<T> = Readonly<{
2
+ data: Awaited<ReturnType<T extends (...args: any) => Promise<infer R> ? () => R : never>>;
3
+ }>;
@@ -0,0 +1,48 @@
1
+ import type { IAccount, TDefaultAccountMetadata } from "./account.interface";
2
+ import type { IAccountCredential } from "./accountCredential.interface";
3
+ export type TClientConfigs = {
4
+ tenantId: string;
5
+ appId: string;
6
+ modeId: string;
7
+ secretKey: string;
8
+ };
9
+ export type TClientOptions = {
10
+ version?: 1;
11
+ logs?: boolean;
12
+ };
13
+ export interface IClient<TAccountMetadata extends TDefaultAccountMetadata = TDefaultAccountMetadata> {
14
+ createPlainAccount(args: {
15
+ identity: string;
16
+ password: string;
17
+ metadata?: TAccountMetadata | null;
18
+ }): Promise<Readonly<{
19
+ account: IAccount<TAccountMetadata>;
20
+ credential: IAccountCredential;
21
+ }>>;
22
+ createEmailAccount(args: {
23
+ identity: string;
24
+ password: string | null;
25
+ metadata?: TAccountMetadata | null;
26
+ }): Promise<Readonly<{
27
+ account: IAccount<TAccountMetadata>;
28
+ credential: IAccountCredential;
29
+ }>>;
30
+ authenticate(args: {
31
+ identity: string;
32
+ password?: string | null;
33
+ }): Promise<{
34
+ token: string;
35
+ account: IAccount<TAccountMetadata>;
36
+ credential: IAccountCredential;
37
+ }>;
38
+ verifyToken(args: {
39
+ token: string;
40
+ }): Promise<{
41
+ account: IAccount<TAccountMetadata>;
42
+ credential: IAccountCredential;
43
+ }>;
44
+ }
45
+ export type TAuthState = {
46
+ account: IAccount;
47
+ credential: IAccountCredential;
48
+ };
@@ -0,0 +1,4 @@
1
+ export type { IAccount } from "./account.interface";
2
+ export type { IAccountCredential } from "./accountCredential.interface";
3
+ export type { TApiResponse } from "./base";
4
+ export type { IClient, TAuthState, TClientConfigs, TClientOptions } from "./client.interface";
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "author": "Trần Đức Tâm (Neo)",
3
+ "bugs": {
4
+ "url": "https://github.com/BoolTS/guard-sdk/issues"
5
+ },
6
+ "dependencies": {
7
+ "jose": "^6.1.0",
8
+ "reflect-metadata": "^0.2.2",
9
+ "zod": "^4.1.9"
10
+ },
11
+ "devDependencies": {
12
+ "@types/bun": "latest",
13
+ "typescript": "^5.9.2"
14
+ },
15
+ "files": [
16
+ "./dist",
17
+ "./src"
18
+ ],
19
+ "homepage": "https://github.com/BoolTS/guard-sdk#readme",
20
+ "keywords": [
21
+ "bool",
22
+ "typescript",
23
+ "ts",
24
+ "bun",
25
+ "framework",
26
+ "guards",
27
+ "security",
28
+ "SDK"
29
+ ],
30
+ "license": "MIT",
31
+ "main": "./dist/index.js",
32
+ "name": "@bool-ts/guard-sdk",
33
+ "peerDependencies": {
34
+ "@bool-ts/core": "^2.0.3"
35
+ },
36
+ "private": false,
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "git+https://github.com/BoolTS/guard-sdk.git"
43
+ },
44
+ "scripts": {
45
+ "build": "tsc --emitDeclarationOnly && bun run app.build.ts",
46
+ "test": "bun --hot run __test/index.ts"
47
+ },
48
+ "types": "./dist/index.d.ts",
49
+ "version": "1.0.0-beta.1"
50
+ }
@@ -0,0 +1,3 @@
1
+ export enum ETokenAudiences {
2
+ SYSTEM = "https://api-guard.booljs.com"
3
+ }
@@ -0,0 +1,2 @@
1
+ export * as Enums from "./enums";
2
+ export * as Keys from "./keys";
@@ -0,0 +1,4 @@
1
+ export const authState = Symbol("__boolGuard::authState");
2
+ export const guardMetadata = Symbol("__boolGuard::guardMetadata");
3
+ export const service = Symbol("__boolGuard::authService");
4
+ export const guardClient = Symbol("__boolGuard::guardClient");
@@ -0,0 +1,5 @@
1
+ import { Keys } from "../constants";
2
+
3
+ export const ActionGuard = () => (target: Object, methodName: string) => {
4
+ Reflect.defineMetadata(Keys.guardMetadata, undefined, target, methodName);
5
+ };
@@ -0,0 +1,4 @@
1
+ import { Context } from "@bool-ts/core";
2
+ import { Keys } from "../constants";
3
+
4
+ export const AuthState = () => Context(Keys.authState);
@@ -0,0 +1,5 @@
1
+ import { Keys } from "../constants";
2
+
3
+ export const ControllerGuard = () => (target: Object) => {
4
+ Reflect.defineMetadata(Keys.guardMetadata, undefined, target);
5
+ };
@@ -0,0 +1,3 @@
1
+ export { ActionGuard } from "./actionGuard.decorator";
2
+ export { AuthState } from "./authState.decorator";
3
+ export { ControllerGuard } from "./controllerGuard.decorator";
@@ -0,0 +1,2 @@
1
+ export * from "./interceptor";
2
+ export * from "./middleware";
@@ -0,0 +1,47 @@
1
+ import type { IInterceptor, THttpRouteModel } from "@bool-ts/core";
2
+ import type { TAuthState } from "../interfaces/client.interface";
3
+
4
+ import { Interceptor as BoolInterceptor, HttpClientError, RouteModel } from "@bool-ts/core";
5
+ import { Keys } from "../constants";
6
+ import { AuthState } from "../decorators/authState.decorator";
7
+
8
+ @BoolInterceptor()
9
+ export class Interceptor implements IInterceptor {
10
+ open(
11
+ @RouteModel()
12
+ routeModel: THttpRouteModel,
13
+ @AuthState()
14
+ authState: TAuthState
15
+ ) {
16
+ const actionMetadataKeys = Reflect.getOwnMetadataKeys(
17
+ routeModel.class.prototype,
18
+ routeModel.funcName
19
+ );
20
+
21
+ if (actionMetadataKeys.includes(Keys.authState)) {
22
+ if (!authState) {
23
+ throw new HttpClientError({
24
+ httpCode: 401,
25
+ message: "Unauthorized",
26
+ data: undefined
27
+ });
28
+ }
29
+
30
+ return;
31
+ }
32
+
33
+ const controllerMetadataKeys = Reflect.getOwnMetadataKeys(routeModel.class);
34
+
35
+ if (controllerMetadataKeys.includes(Keys.authState)) {
36
+ if (!authState) {
37
+ throw new HttpClientError({
38
+ httpCode: 401,
39
+ message: "Unauthorized",
40
+ data: undefined
41
+ });
42
+ }
43
+
44
+ return;
45
+ }
46
+ }
47
+ }
@@ -0,0 +1,20 @@
1
+ import type { TClientConfigs, TClientOptions } from "../interfaces/client.interface";
2
+
3
+ import { Keys } from "../constants";
4
+ import { Client } from "../instances/client";
5
+
6
+ export const loader = async (clientConfigs: TClientConfigs, clientOptions?: TClientOptions) => {
7
+ const boolGuardClient = new Client(clientConfigs, clientOptions);
8
+
9
+ await boolGuardClient.signToken();
10
+
11
+ const pingResult = await boolGuardClient.ping();
12
+
13
+ if (!pingResult) {
14
+ throw new Error("Ping to Bool Guard service failed!");
15
+ }
16
+
17
+ return [Keys.guardClient, boolGuardClient];
18
+ };
19
+
20
+ export default loader;
@@ -0,0 +1,73 @@
1
+ import type { IContext, IMiddleware } from "@bool-ts/core";
2
+ import type { IClient, TAuthState } from "../interfaces/client.interface";
3
+
4
+ import { Context, Inject, RequestHeaders } from "@bool-ts/core";
5
+ import { object, string } from "zod/v4";
6
+ import { Keys } from "../constants";
7
+ import { Client } from "../instances";
8
+
9
+ const headersSchema = object({
10
+ authorization: string()
11
+ .startsWith("Bearer ")
12
+ .min(24)
13
+ .transform((value) => {
14
+ const [schema, token] = value.split(" ");
15
+
16
+ return Object.freeze({
17
+ schema,
18
+ token
19
+ });
20
+ })
21
+ });
22
+
23
+ /**
24
+ * Bool guard middleware for Bool Typescript framework
25
+ */
26
+ export class Middleware implements IMiddleware {
27
+ /**
28
+ *
29
+ * @param tenantAppModesService
30
+ */
31
+ constructor(
32
+ @Inject(Client)
33
+ private readonly clientInstance: IClient
34
+ ) {}
35
+
36
+ /**
37
+ *
38
+ * @param context
39
+ * @param requestHeaders
40
+ */
41
+ async start(
42
+ @Context()
43
+ context: IContext,
44
+ @RequestHeaders()
45
+ requestHeaders: Headers
46
+ ) {
47
+ const headersValidation = await headersSchema.safeParseAsync(requestHeaders.toJSON());
48
+
49
+ if (!headersValidation.success) {
50
+ return context.set(Keys.authState, undefined);
51
+ } else {
52
+ const {
53
+ authorization: { token }
54
+ } = headersValidation.data;
55
+
56
+ try {
57
+ const { account, credential } = await this.clientInstance.verifyToken({
58
+ token: token
59
+ });
60
+
61
+ const authState: TAuthState = Object.freeze({
62
+ account: account,
63
+ credential: credential
64
+ });
65
+
66
+ return context.set(Keys.authState, authState);
67
+ } catch (error) {
68
+ console.error(error);
69
+ return context.set(Keys.authState, undefined);
70
+ }
71
+ }
72
+ }
73
+ }
package/src/index.ts ADDED
@@ -0,0 +1,6 @@
1
+ export type * from "./interfaces";
2
+
3
+ export * from "./constants";
4
+ export * from "./decorators";
5
+ export * from "./entities";
6
+ export * from "./instances";
@@ -0,0 +1,314 @@
1
+ import type { TApiResponse } from "../interfaces/base";
2
+ import type { IClient, TClientConfigs, TClientOptions } from "../interfaces/client.interface";
3
+
4
+ import { SignJWT } from "jose";
5
+ import { email } from "zod/v4";
6
+ import { Enums } from "../constants";
7
+
8
+ export class Client implements IClient {
9
+ readonly #baseUri = Enums.ETokenAudiences.SYSTEM;
10
+
11
+ private token: string | undefined;
12
+
13
+ /**
14
+ * Initialize BoolGuard client instance
15
+ * @param configs
16
+ * @param options
17
+ */
18
+ constructor(
19
+ private readonly configs: TClientConfigs,
20
+ private readonly options?: TClientOptions
21
+ ) {}
22
+
23
+ /**
24
+ * Sign JWT token with Ed25519 algorithm
25
+ * @returns
26
+ */
27
+ async signToken() {
28
+ try {
29
+ const rawKey = new Uint8Array(Buffer.from(this.configs.secretKey, "base64"));
30
+ const privateKey = await crypto.subtle.importKey(
31
+ "raw",
32
+ rawKey,
33
+ { name: "HMAC", hash: "SHA-512" },
34
+ false,
35
+ ["sign", "verify"]
36
+ );
37
+
38
+ const jwt = await new SignJWT({
39
+ tenantId: this.configs.tenantId,
40
+ appId: this.configs.appId,
41
+ modeId: this.configs.modeId,
42
+ iss: this.configs.tenantId,
43
+ aud: Enums.ETokenAudiences.SYSTEM
44
+ })
45
+ .setProtectedHeader({ alg: "HS512" })
46
+ .sign(privateKey);
47
+
48
+ this.token = jwt;
49
+
50
+ return jwt;
51
+ } catch (error) {
52
+ if (this.options?.logs) {
53
+ console.error("[BoolGuard] Sign token error:", error);
54
+ }
55
+
56
+ throw error;
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Ping to BoolGuard service to check if the service is reachable
62
+ * This action should be done before any other actions.
63
+ * @returns
64
+ */
65
+ async ping() {
66
+ try {
67
+ const authToken = this.token || (await this.signToken());
68
+
69
+ const requestHeaders = new Headers();
70
+ requestHeaders.append("X-Tenant-ID", this.configs.tenantId);
71
+ requestHeaders.append("X-App-ID", this.configs.appId);
72
+ requestHeaders.append("X-Mode-ID", this.configs.modeId);
73
+ requestHeaders.append("Authorization", `Bearer ${authToken}`);
74
+
75
+ const response = await fetch(
76
+ `${this.#baseUri}/v${this.options?.version}/tenant-app-modes/ping`,
77
+ {
78
+ method: "GET",
79
+ headers: requestHeaders
80
+ }
81
+ );
82
+
83
+ if (!response.ok) {
84
+ throw await response.json();
85
+ }
86
+
87
+ return response.ok;
88
+ } catch (error) {
89
+ if (this.options?.logs) {
90
+ console.error("[BoolGuard] Ping error:", error);
91
+ }
92
+
93
+ return false;
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Create a new plain account with custom account name
99
+ * @param args
100
+ * @returns
101
+ */
102
+ async createPlainAccount({
103
+ identity,
104
+ password,
105
+ metadata
106
+ }: Parameters<IClient["createPlainAccount"]>[number]): ReturnType<
107
+ IClient["createPlainAccount"]
108
+ > {
109
+ try {
110
+ const authToken = this.token || (await this.signToken());
111
+
112
+ const requestHeaders = new Headers();
113
+ requestHeaders.append("X-Tenant-ID", this.configs.tenantId);
114
+ requestHeaders.append("X-App-ID", this.configs.appId);
115
+ requestHeaders.append("X-Mode-ID", this.configs.modeId);
116
+ requestHeaders.append("Authorization", `Bearer ${authToken}`);
117
+ requestHeaders.append("Content-Type", "application/json");
118
+
119
+ const response = await fetch(
120
+ `${this.#baseUri}/v${this.options?.version}/tenant-app-mode-accounts`,
121
+ {
122
+ method: "POST",
123
+ headers: requestHeaders,
124
+ body: JSON.stringify({
125
+ data: {
126
+ type: "plain",
127
+ identity: identity,
128
+ password: password,
129
+ metadata: metadata
130
+ }
131
+ })
132
+ }
133
+ );
134
+
135
+ if (!response.ok) {
136
+ throw await response.json();
137
+ }
138
+
139
+ const { data } = (await response.json()) as TApiResponse<IClient["createPlainAccount"]>;
140
+
141
+ return Object.freeze({
142
+ account: data.account,
143
+ credential: data.credential
144
+ });
145
+ } catch (error) {
146
+ if (this.options?.logs) {
147
+ console.error("[BoolGuard] Create plain account error:", error);
148
+ }
149
+
150
+ throw error;
151
+ }
152
+ }
153
+
154
+ /**
155
+ * Create a new email account, this action will create email record and link to account
156
+ * with random account alias generated by system.
157
+ * @param args
158
+ */
159
+ async createEmailAccount({
160
+ identity,
161
+ password,
162
+ metadata
163
+ }: Parameters<IClient["createEmailAccount"]>[number]): ReturnType<
164
+ IClient["createEmailAccount"]
165
+ > {
166
+ try {
167
+ const authToken = this.token || (await this.signToken());
168
+
169
+ const requestHeaders = new Headers();
170
+ requestHeaders.append("X-Tenant-ID", this.configs.tenantId);
171
+ requestHeaders.append("X-App-ID", this.configs.appId);
172
+ requestHeaders.append("X-Mode-ID", this.configs.modeId);
173
+ requestHeaders.append("Authorization", `Bearer ${authToken}`);
174
+ requestHeaders.append("Content-Type", "application/json");
175
+
176
+ const response = await fetch(
177
+ `${this.#baseUri}/v${this.options?.version}/tenant-app-mode-accounts`,
178
+ {
179
+ method: "POST",
180
+ headers: requestHeaders,
181
+ body: JSON.stringify({
182
+ data: {
183
+ type: "email",
184
+ identity: identity,
185
+ password: password,
186
+ metadata: metadata
187
+ }
188
+ })
189
+ }
190
+ );
191
+
192
+ if (!response.ok) {
193
+ throw await response.json();
194
+ }
195
+
196
+ const { data } = (await response.json()) as TApiResponse<IClient["createEmailAccount"]>;
197
+
198
+ return Object.freeze({
199
+ account: data.account,
200
+ credential: data.credential
201
+ });
202
+ } catch (error) {
203
+ if (this.options?.logs) {
204
+ console.error("[BoolGuard] Create email account error:", error);
205
+ }
206
+
207
+ throw error;
208
+ }
209
+ }
210
+
211
+ /**
212
+ * Authenticate an account with account name and password
213
+ * This action will return account info and JWT token if successful
214
+ * @param param0
215
+ */
216
+ async authenticate({
217
+ identity,
218
+ password
219
+ }: Parameters<IClient["authenticate"]>[number]): ReturnType<IClient["authenticate"]> {
220
+ try {
221
+ const authToken = this.token || (await this.signToken());
222
+ const emailValidation = await email().safeParseAsync(identity);
223
+
224
+ const requestHeaders = new Headers();
225
+ requestHeaders.append("X-Tenant-ID", this.configs.tenantId);
226
+ requestHeaders.append("X-App-ID", this.configs.appId);
227
+ requestHeaders.append("X-Mode-ID", this.configs.modeId);
228
+ requestHeaders.append("Authorization", `Bearer ${authToken}`);
229
+ requestHeaders.append("Content-Type", "application/json");
230
+
231
+ const response = await fetch(
232
+ `${this.#baseUri}/v${this.options?.version}/tenant-app-mode-accounts/authenticate`,
233
+ {
234
+ method: "POST",
235
+ headers: requestHeaders,
236
+ body: JSON.stringify({
237
+ data: {
238
+ type: !emailValidation.success ? "plain" : "email",
239
+ identity: identity,
240
+ password: password
241
+ }
242
+ })
243
+ }
244
+ );
245
+
246
+ if (!response.ok) {
247
+ throw await response.json();
248
+ }
249
+
250
+ const { data } = (await response.json()) as TApiResponse<IClient["authenticate"]>;
251
+
252
+ return Object.freeze({
253
+ account: data.account,
254
+ credential: data.credential,
255
+ token: data.token
256
+ });
257
+ } catch (error) {
258
+ if (this.options?.logs) {
259
+ console.error("[BoolGuard] Authenticate error:", error);
260
+ }
261
+
262
+ throw error;
263
+ }
264
+ }
265
+
266
+ /**
267
+ * Authenticate a token and return account info if token is valid
268
+ * @param param0
269
+ */
270
+ async verifyToken({
271
+ token
272
+ }: Parameters<IClient["verifyToken"]>[number]): ReturnType<IClient["verifyToken"]> {
273
+ try {
274
+ const authToken = this.token || (await this.signToken());
275
+
276
+ const requestHeaders = new Headers();
277
+ requestHeaders.append("X-Tenant-ID", this.configs.tenantId);
278
+ requestHeaders.append("X-App-ID", this.configs.appId);
279
+ requestHeaders.append("X-Mode-ID", this.configs.modeId);
280
+ requestHeaders.append("Authorization", `Bearer ${authToken}`);
281
+ requestHeaders.append("Content-Type", "application/json");
282
+
283
+ const response = await fetch(
284
+ `${this.#baseUri}/v${this.options?.version}/tenant-app-mode-accounts/verify`,
285
+ {
286
+ method: "POST",
287
+ headers: requestHeaders,
288
+ body: JSON.stringify({
289
+ data: {
290
+ token: token
291
+ }
292
+ })
293
+ }
294
+ );
295
+
296
+ if (!response.ok) {
297
+ throw await response.json();
298
+ }
299
+
300
+ const { data } = (await response.json()) as TApiResponse<IClient["verifyToken"]>;
301
+
302
+ return Object.freeze({
303
+ account: data.account,
304
+ credential: data.credential
305
+ });
306
+ } catch (error) {
307
+ if (this.options?.logs) {
308
+ console.error("[BoolGuard] Verify token error:", error);
309
+ }
310
+
311
+ throw error;
312
+ }
313
+ }
314
+ }