@23blocks/block-authentication 0.1.0
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/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/authentication.block.js +102 -0
- package/dist/lib/authentication.block.js.map +1 -0
- package/dist/lib/mappers/api-key.mapper.js +57 -0
- package/dist/lib/mappers/api-key.mapper.js.map +1 -0
- package/dist/lib/mappers/app.mapper.js +98 -0
- package/dist/lib/mappers/app.mapper.js.map +1 -0
- package/dist/lib/mappers/company.mapper.js +128 -0
- package/dist/lib/mappers/company.mapper.js.map +1 -0
- package/dist/lib/mappers/geography.mapper.js +129 -0
- package/dist/lib/mappers/geography.mapper.js.map +1 -0
- package/dist/lib/mappers/guest.mapper.js +176 -0
- package/dist/lib/mappers/guest.mapper.js.map +1 -0
- package/dist/lib/mappers/index.js +18 -0
- package/dist/lib/mappers/index.js.map +1 -0
- package/dist/lib/mappers/subscription.mapper.js +134 -0
- package/dist/lib/mappers/subscription.mapper.js.map +1 -0
- package/dist/lib/mappers/user.mapper.js +163 -0
- package/dist/lib/mappers/user.mapper.js.map +1 -0
- package/dist/lib/mappers/utils.js +54 -0
- package/dist/lib/mappers/utils.js.map +1 -0
- package/dist/lib/services/api-keys.service.js +93 -0
- package/dist/lib/services/api-keys.service.js.map +1 -0
- package/dist/lib/services/apps.service.js +139 -0
- package/dist/lib/services/apps.service.js.map +1 -0
- package/dist/lib/services/auth.service.js +147 -0
- package/dist/lib/services/auth.service.js.map +1 -0
- package/dist/lib/services/geography.service.js +151 -0
- package/dist/lib/services/geography.service.js.map +1 -0
- package/dist/lib/services/guests.service.js +219 -0
- package/dist/lib/services/guests.service.js.map +1 -0
- package/dist/lib/services/index.js +14 -0
- package/dist/lib/services/index.js.map +1 -0
- package/dist/lib/services/roles.service.js +91 -0
- package/dist/lib/services/roles.service.js.map +1 -0
- package/dist/lib/services/subscriptions.service.js +146 -0
- package/dist/lib/services/subscriptions.service.js.map +1 -0
- package/dist/lib/services/users.service.js +116 -0
- package/dist/lib/services/users.service.js.map +1 -0
- package/dist/lib/types/api-key.js +5 -0
- package/dist/lib/types/api-key.js.map +1 -0
- package/dist/lib/types/app.js +5 -0
- package/dist/lib/types/app.js.map +1 -0
- package/dist/lib/types/auth.js +5 -0
- package/dist/lib/types/auth.js.map +1 -0
- package/dist/lib/types/company.js +5 -0
- package/dist/lib/types/company.js.map +1 -0
- package/dist/lib/types/geography.js +5 -0
- package/dist/lib/types/geography.js.map +1 -0
- package/dist/lib/types/guest.js +5 -0
- package/dist/lib/types/guest.js.map +1 -0
- package/dist/lib/types/index.js +4 -0
- package/dist/lib/types/index.js.map +1 -0
- package/dist/lib/types/subscription.js +5 -0
- package/dist/lib/types/subscription.js.map +1 -0
- package/dist/lib/types/user.js +13 -0
- package/dist/lib/types/user.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse a string value, returning null for empty/undefined
|
|
3
|
+
*/ export function parseString(value) {
|
|
4
|
+
if (value === null || value === undefined) {
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
const str = String(value);
|
|
8
|
+
return str.length > 0 ? str : null;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Parse a date value
|
|
12
|
+
*/ export function parseDate(value) {
|
|
13
|
+
if (value === null || value === undefined) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
if (value instanceof Date) {
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
20
|
+
const date = new Date(value);
|
|
21
|
+
return isNaN(date.getTime()) ? null : date;
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Parse a boolean value
|
|
27
|
+
*/ export function parseBoolean(value) {
|
|
28
|
+
if (typeof value === 'boolean') {
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
if (value === 'true' || value === '1' || value === 1) {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Parse an array of strings
|
|
38
|
+
*/ export function parseStringArray(value) {
|
|
39
|
+
if (Array.isArray(value)) {
|
|
40
|
+
return value.map(String);
|
|
41
|
+
}
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Parse a number value
|
|
46
|
+
*/ export function parseNumber(value) {
|
|
47
|
+
if (value === null || value === undefined) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
const num = Number(value);
|
|
51
|
+
return isNaN(num) ? null : num;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/mappers/utils.ts"],"sourcesContent":["/**\n * Parse a string value, returning null for empty/undefined\n */\nexport function parseString(value: unknown): string | null {\n if (value === null || value === undefined) {\n return null;\n }\n const str = String(value);\n return str.length > 0 ? str : null;\n}\n\n/**\n * Parse a date value\n */\nexport function parseDate(value: unknown): Date | null {\n if (value === null || value === undefined) {\n return null;\n }\n\n if (value instanceof Date) {\n return value;\n }\n\n if (typeof value === 'string' || typeof value === 'number') {\n const date = new Date(value);\n return isNaN(date.getTime()) ? null : date;\n }\n\n return null;\n}\n\n/**\n * Parse a boolean value\n */\nexport function parseBoolean(value: unknown): boolean {\n if (typeof value === 'boolean') {\n return value;\n }\n if (value === 'true' || value === '1' || value === 1) {\n return true;\n }\n return false;\n}\n\n/**\n * Parse an array of strings\n */\nexport function parseStringArray(value: unknown): string[] {\n if (Array.isArray(value)) {\n return value.map(String);\n }\n return [];\n}\n\n/**\n * Parse a number value\n */\nexport function parseNumber(value: unknown): number | null {\n if (value === null || value === undefined) {\n return null;\n }\n const num = Number(value);\n return isNaN(num) ? null : num;\n}\n"],"names":["parseString","value","undefined","str","String","length","parseDate","Date","date","isNaN","getTime","parseBoolean","parseStringArray","Array","isArray","map","parseNumber","num","Number"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA;;CAEC,GACD,OAAO,SAASA,YAAYC,KAAc;IACxC,IAAIA,UAAU,QAAQA,UAAUC,WAAW;QACzC,OAAO;IACT;IACA,MAAMC,MAAMC,OAAOH;IACnB,OAAOE,IAAIE,MAAM,GAAG,IAAIF,MAAM;AAChC;AAEA;;CAEC,GACD,OAAO,SAASG,UAAUL,KAAc;IACtC,IAAIA,UAAU,QAAQA,UAAUC,WAAW;QACzC,OAAO;IACT;IAEA,IAAID,iBAAiBM,MAAM;QACzB,OAAON;IACT;IAEA,IAAI,OAAOA,UAAU,YAAY,OAAOA,UAAU,UAAU;QAC1D,MAAMO,OAAO,IAAID,KAAKN;QACtB,OAAOQ,MAAMD,KAAKE,OAAO,MAAM,OAAOF;IACxC;IAEA,OAAO;AACT;AAEA;;CAEC,GACD,OAAO,SAASG,aAAaV,KAAc;IACzC,IAAI,OAAOA,UAAU,WAAW;QAC9B,OAAOA;IACT;IACA,IAAIA,UAAU,UAAUA,UAAU,OAAOA,UAAU,GAAG;QACpD,OAAO;IACT;IACA,OAAO;AACT;AAEA;;CAEC,GACD,OAAO,SAASW,iBAAiBX,KAAc;IAC7C,IAAIY,MAAMC,OAAO,CAACb,QAAQ;QACxB,OAAOA,MAAMc,GAAG,CAACX;IACnB;IACA,OAAO,EAAE;AACX;AAEA;;CAEC,GACD,OAAO,SAASY,YAAYf,KAAc;IACxC,IAAIA,UAAU,QAAQA,UAAUC,WAAW;QACzC,OAAO;IACT;IACA,MAAMe,MAAMC,OAAOjB;IACnB,OAAOQ,MAAMQ,OAAO,OAAOA;AAC7B"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { decodeOne, decodePageResult } from '@23blocks/jsonapi-codec';
|
|
2
|
+
import { apiKeyMapper, apiKeyWithSecretMapper } from '../mappers/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Create the API keys service
|
|
5
|
+
*/ export function createApiKeysService(transport, _config) {
|
|
6
|
+
return {
|
|
7
|
+
async list (params) {
|
|
8
|
+
const queryParams = {};
|
|
9
|
+
if (params == null ? void 0 : params.page) queryParams['page[number]'] = params.page;
|
|
10
|
+
if (params == null ? void 0 : params.perPage) queryParams['page[size]'] = params.perPage;
|
|
11
|
+
if (params == null ? void 0 : params.filter) {
|
|
12
|
+
for (const [key, value] of Object.entries(params.filter)){
|
|
13
|
+
queryParams[`filter[${key}]`] = value;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const response = await transport.get('/api_keys', {
|
|
17
|
+
params: queryParams
|
|
18
|
+
});
|
|
19
|
+
return decodePageResult(response, apiKeyMapper);
|
|
20
|
+
},
|
|
21
|
+
async get (id) {
|
|
22
|
+
const response = await transport.get(`/api_keys/${id}`);
|
|
23
|
+
return decodeOne(response, apiKeyMapper);
|
|
24
|
+
},
|
|
25
|
+
async getByKeyId (keyId) {
|
|
26
|
+
const response = await transport.get(`/api_keys/by_key_id/${keyId}`);
|
|
27
|
+
return decodeOne(response, apiKeyMapper);
|
|
28
|
+
},
|
|
29
|
+
async create (request) {
|
|
30
|
+
const response = await transport.post('/api_keys', {
|
|
31
|
+
name: request.name,
|
|
32
|
+
description: request.description,
|
|
33
|
+
service_account: request.serviceAccount,
|
|
34
|
+
scopes: request.scopes,
|
|
35
|
+
expires_at: request.expiresAt,
|
|
36
|
+
rate_limit_per_minute: request.rateLimitPerMinute,
|
|
37
|
+
rate_limit_per_hour: request.rateLimitPerHour,
|
|
38
|
+
rate_limit_per_day: request.rateLimitPerDay,
|
|
39
|
+
allowed_origins: request.allowedOrigins,
|
|
40
|
+
allowed_ips: request.allowedIps,
|
|
41
|
+
payload: request.payload
|
|
42
|
+
});
|
|
43
|
+
return decodeOne(response, apiKeyWithSecretMapper);
|
|
44
|
+
},
|
|
45
|
+
async update (id, request) {
|
|
46
|
+
const response = await transport.patch(`/api_keys/${id}`, {
|
|
47
|
+
name: request.name,
|
|
48
|
+
description: request.description,
|
|
49
|
+
scopes: request.scopes,
|
|
50
|
+
rate_limit_per_minute: request.rateLimitPerMinute,
|
|
51
|
+
rate_limit_per_hour: request.rateLimitPerHour,
|
|
52
|
+
rate_limit_per_day: request.rateLimitPerDay,
|
|
53
|
+
allowed_origins: request.allowedOrigins,
|
|
54
|
+
allowed_ips: request.allowedIps,
|
|
55
|
+
payload: request.payload
|
|
56
|
+
});
|
|
57
|
+
return decodeOne(response, apiKeyMapper);
|
|
58
|
+
},
|
|
59
|
+
async regenerate (id) {
|
|
60
|
+
const response = await transport.post(`/api_keys/${id}/regenerate`);
|
|
61
|
+
return decodeOne(response, apiKeyWithSecretMapper);
|
|
62
|
+
},
|
|
63
|
+
async revoke (id, request) {
|
|
64
|
+
const response = await transport.post(`/api_keys/${id}/revoke`, {
|
|
65
|
+
reason: request == null ? void 0 : request.reason
|
|
66
|
+
});
|
|
67
|
+
return decodeOne(response, apiKeyMapper);
|
|
68
|
+
},
|
|
69
|
+
async delete (id) {
|
|
70
|
+
await transport.delete(`/api_keys/${id}`);
|
|
71
|
+
},
|
|
72
|
+
async getUsage (id, period = 'week') {
|
|
73
|
+
const response = await transport.get(`/api_keys/${id}/usage`, {
|
|
74
|
+
params: {
|
|
75
|
+
period
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
const attrs = response.data.attributes;
|
|
79
|
+
return {
|
|
80
|
+
apiKeyId: attrs.api_key_id,
|
|
81
|
+
period: attrs.period,
|
|
82
|
+
totalRequests: attrs.total_requests,
|
|
83
|
+
successfulRequests: attrs.successful_requests,
|
|
84
|
+
failedRequests: attrs.failed_requests,
|
|
85
|
+
averageLatency: attrs.average_latency,
|
|
86
|
+
requestsByEndpoint: attrs.requests_by_endpoint,
|
|
87
|
+
requestsByDay: attrs.requests_by_day
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
//# sourceMappingURL=api-keys.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/services/api-keys.service.ts"],"sourcesContent":["import type { Transport, PageResult, ListParams } from '@23blocks/contracts';\nimport { decodeOne, decodePageResult } from '@23blocks/jsonapi-codec';\nimport type {\n ApiKey,\n ApiKeyWithSecret,\n CreateApiKeyRequest,\n UpdateApiKeyRequest,\n RevokeApiKeyRequest,\n} from '../types/index.js';\nimport { apiKeyMapper, apiKeyWithSecretMapper } from '../mappers/index.js';\nimport type { AuthenticationBlockConfig } from '../authentication.block.js';\n\n/**\n * API Keys service\n */\nexport interface ApiKeysService {\n /**\n * List all API keys\n */\n list(params?: ListParams): Promise<PageResult<ApiKey>>;\n\n /**\n * Get an API key by ID\n */\n get(id: string): Promise<ApiKey>;\n\n /**\n * Get an API key by key ID\n */\n getByKeyId(keyId: string): Promise<ApiKey>;\n\n /**\n * Create a new API key (returns secret key only once)\n */\n create(request: CreateApiKeyRequest): Promise<ApiKeyWithSecret>;\n\n /**\n * Update an API key\n */\n update(id: string, request: UpdateApiKeyRequest): Promise<ApiKey>;\n\n /**\n * Regenerate an API key secret (returns new secret only once)\n */\n regenerate(id: string): Promise<ApiKeyWithSecret>;\n\n /**\n * Revoke an API key\n */\n revoke(id: string, request?: RevokeApiKeyRequest): Promise<ApiKey>;\n\n /**\n * Delete an API key permanently\n */\n delete(id: string): Promise<void>;\n\n /**\n * Get usage statistics for an API key\n */\n getUsage(id: string, period?: 'day' | 'week' | 'month'): Promise<ApiKeyUsageStats>;\n}\n\n/**\n * API Key usage statistics\n */\nexport interface ApiKeyUsageStats {\n apiKeyId: string;\n period: string;\n totalRequests: number;\n successfulRequests: number;\n failedRequests: number;\n averageLatency: number;\n requestsByEndpoint: Record<string, number>;\n requestsByDay: Array<{ date: string; count: number }>;\n}\n\n/**\n * Create the API keys service\n */\nexport function createApiKeysService(\n transport: Transport,\n _config: AuthenticationBlockConfig\n): ApiKeysService {\n return {\n async list(params?: ListParams): Promise<PageResult<ApiKey>> {\n const queryParams: Record<string, unknown> = {};\n\n if (params?.page) queryParams['page[number]'] = params.page;\n if (params?.perPage) queryParams['page[size]'] = params.perPage;\n if (params?.filter) {\n for (const [key, value] of Object.entries(params.filter)) {\n queryParams[`filter[${key}]`] = value;\n }\n }\n\n const response = await transport.get<{ data: unknown[]; meta?: unknown }>(\n '/api_keys',\n { params: queryParams as Record<string, string> }\n );\n return decodePageResult(response, apiKeyMapper);\n },\n\n async get(id: string): Promise<ApiKey> {\n const response = await transport.get<{ data: unknown }>(\n `/api_keys/${id}`\n );\n return decodeOne(response, apiKeyMapper);\n },\n\n async getByKeyId(keyId: string): Promise<ApiKey> {\n const response = await transport.get<{ data: unknown }>(\n `/api_keys/by_key_id/${keyId}`\n );\n return decodeOne(response, apiKeyMapper);\n },\n\n async create(request: CreateApiKeyRequest): Promise<ApiKeyWithSecret> {\n const response = await transport.post<{ data: unknown }>(\n '/api_keys',\n {\n name: request.name,\n description: request.description,\n service_account: request.serviceAccount,\n scopes: request.scopes,\n expires_at: request.expiresAt,\n rate_limit_per_minute: request.rateLimitPerMinute,\n rate_limit_per_hour: request.rateLimitPerHour,\n rate_limit_per_day: request.rateLimitPerDay,\n allowed_origins: request.allowedOrigins,\n allowed_ips: request.allowedIps,\n payload: request.payload,\n }\n );\n return decodeOne(response, apiKeyWithSecretMapper);\n },\n\n async update(id: string, request: UpdateApiKeyRequest): Promise<ApiKey> {\n const response = await transport.patch<{ data: unknown }>(\n `/api_keys/${id}`,\n {\n name: request.name,\n description: request.description,\n scopes: request.scopes,\n rate_limit_per_minute: request.rateLimitPerMinute,\n rate_limit_per_hour: request.rateLimitPerHour,\n rate_limit_per_day: request.rateLimitPerDay,\n allowed_origins: request.allowedOrigins,\n allowed_ips: request.allowedIps,\n payload: request.payload,\n }\n );\n return decodeOne(response, apiKeyMapper);\n },\n\n async regenerate(id: string): Promise<ApiKeyWithSecret> {\n const response = await transport.post<{ data: unknown }>(\n `/api_keys/${id}/regenerate`\n );\n return decodeOne(response, apiKeyWithSecretMapper);\n },\n\n async revoke(id: string, request?: RevokeApiKeyRequest): Promise<ApiKey> {\n const response = await transport.post<{ data: unknown }>(\n `/api_keys/${id}/revoke`,\n { reason: request?.reason }\n );\n return decodeOne(response, apiKeyMapper);\n },\n\n async delete(id: string): Promise<void> {\n await transport.delete(`/api_keys/${id}`);\n },\n\n async getUsage(id: string, period: 'day' | 'week' | 'month' = 'week'): Promise<ApiKeyUsageStats> {\n const response = await transport.get<{\n data: {\n attributes: {\n api_key_id: string;\n period: string;\n total_requests: number;\n successful_requests: number;\n failed_requests: number;\n average_latency: number;\n requests_by_endpoint: Record<string, number>;\n requests_by_day: Array<{ date: string; count: number }>;\n };\n };\n }>(`/api_keys/${id}/usage`, { params: { period } });\n\n const attrs = response.data.attributes;\n return {\n apiKeyId: attrs.api_key_id,\n period: attrs.period,\n totalRequests: attrs.total_requests,\n successfulRequests: attrs.successful_requests,\n failedRequests: attrs.failed_requests,\n averageLatency: attrs.average_latency,\n requestsByEndpoint: attrs.requests_by_endpoint,\n requestsByDay: attrs.requests_by_day,\n };\n },\n };\n}\n"],"names":["decodeOne","decodePageResult","apiKeyMapper","apiKeyWithSecretMapper","createApiKeysService","transport","_config","list","params","queryParams","page","perPage","filter","key","value","Object","entries","response","get","id","getByKeyId","keyId","create","request","post","name","description","service_account","serviceAccount","scopes","expires_at","expiresAt","rate_limit_per_minute","rateLimitPerMinute","rate_limit_per_hour","rateLimitPerHour","rate_limit_per_day","rateLimitPerDay","allowed_origins","allowedOrigins","allowed_ips","allowedIps","payload","update","patch","regenerate","revoke","reason","delete","getUsage","period","attrs","data","attributes","apiKeyId","api_key_id","totalRequests","total_requests","successfulRequests","successful_requests","failedRequests","failed_requests","averageLatency","average_latency","requestsByEndpoint","requests_by_endpoint","requestsByDay","requests_by_day"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { decodeOne, decodeMany, decodePageResult } from '@23blocks/jsonapi-codec';
|
|
2
|
+
import { appMapper, blockMapper, serviceMapper } from '../mappers/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Build filter params for list operations
|
|
5
|
+
*/ function buildListParams(params) {
|
|
6
|
+
if (!params) return {};
|
|
7
|
+
const queryParams = {};
|
|
8
|
+
if (params.page) {
|
|
9
|
+
queryParams['page[number]'] = params.page;
|
|
10
|
+
}
|
|
11
|
+
if (params.perPage) {
|
|
12
|
+
queryParams['page[size]'] = params.perPage;
|
|
13
|
+
}
|
|
14
|
+
if (params.sort) {
|
|
15
|
+
const sorts = Array.isArray(params.sort) ? params.sort : [
|
|
16
|
+
params.sort
|
|
17
|
+
];
|
|
18
|
+
queryParams['sort'] = sorts.map((s)=>s.direction === 'desc' ? `-${s.field}` : s.field).join(',');
|
|
19
|
+
}
|
|
20
|
+
if (params.filter) {
|
|
21
|
+
for (const [key, value] of Object.entries(params.filter)){
|
|
22
|
+
queryParams[`filter[${key}]`] = value;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (params.include) {
|
|
26
|
+
queryParams['include'] = params.include.join(',');
|
|
27
|
+
}
|
|
28
|
+
return queryParams;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Create the apps service
|
|
32
|
+
*/ export function createAppsService(transport, _config) {
|
|
33
|
+
return {
|
|
34
|
+
async list (params) {
|
|
35
|
+
const response = await transport.get('/apps', {
|
|
36
|
+
params: buildListParams(params)
|
|
37
|
+
});
|
|
38
|
+
return decodePageResult(response, appMapper);
|
|
39
|
+
},
|
|
40
|
+
async get (id) {
|
|
41
|
+
const response = await transport.get(`/apps/${id}`);
|
|
42
|
+
return decodeOne(response, appMapper);
|
|
43
|
+
},
|
|
44
|
+
async create (request) {
|
|
45
|
+
const response = await transport.post('/apps', {
|
|
46
|
+
name: request.name,
|
|
47
|
+
description: request.description,
|
|
48
|
+
app_type: request.appType,
|
|
49
|
+
oauth_enabled: request.oauthEnabled,
|
|
50
|
+
oauth_access_token_lifetime_hours: request.oauthAccessTokenLifetimeHours,
|
|
51
|
+
oauth_refresh_token_lifetime_days: request.oauthRefreshTokenLifetimeDays,
|
|
52
|
+
rate_limit_per_minute: request.rateLimitPerMinute,
|
|
53
|
+
rate_limit_per_hour: request.rateLimitPerHour,
|
|
54
|
+
webhook_url: request.webhookUrl,
|
|
55
|
+
allowed_origins: request.allowedOrigins,
|
|
56
|
+
metadata: request.metadata
|
|
57
|
+
});
|
|
58
|
+
return decodeOne(response, appMapper);
|
|
59
|
+
},
|
|
60
|
+
async update (id, request) {
|
|
61
|
+
const response = await transport.patch(`/apps/${id}`, {
|
|
62
|
+
name: request.name,
|
|
63
|
+
description: request.description,
|
|
64
|
+
app_type: request.appType,
|
|
65
|
+
oauth_enabled: request.oauthEnabled,
|
|
66
|
+
oauth_access_token_lifetime_hours: request.oauthAccessTokenLifetimeHours,
|
|
67
|
+
oauth_refresh_token_lifetime_days: request.oauthRefreshTokenLifetimeDays,
|
|
68
|
+
rate_limit_per_minute: request.rateLimitPerMinute,
|
|
69
|
+
rate_limit_per_hour: request.rateLimitPerHour,
|
|
70
|
+
webhook_url: request.webhookUrl,
|
|
71
|
+
allowed_origins: request.allowedOrigins,
|
|
72
|
+
metadata: request.metadata,
|
|
73
|
+
status: request.status
|
|
74
|
+
});
|
|
75
|
+
return decodeOne(response, appMapper);
|
|
76
|
+
},
|
|
77
|
+
async delete (id) {
|
|
78
|
+
await transport.delete(`/apps/${id}`);
|
|
79
|
+
},
|
|
80
|
+
async regenerateWebhookSecret (id) {
|
|
81
|
+
const response = await transport.post(`/apps/${id}/regenerate_webhook_secret`);
|
|
82
|
+
return decodeOne(response, appMapper);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Create the blocks service
|
|
88
|
+
*/ export function createBlocksService(transport, _config) {
|
|
89
|
+
return {
|
|
90
|
+
async list (companyId, params) {
|
|
91
|
+
const queryParams = buildListParams(params);
|
|
92
|
+
queryParams['filter[company_unique_id]'] = companyId;
|
|
93
|
+
const response = await transport.get('/blocks', {
|
|
94
|
+
params: queryParams
|
|
95
|
+
});
|
|
96
|
+
return decodePageResult(response, blockMapper);
|
|
97
|
+
},
|
|
98
|
+
async get (id) {
|
|
99
|
+
const response = await transport.get(`/blocks/${id}`);
|
|
100
|
+
return decodeOne(response, blockMapper);
|
|
101
|
+
},
|
|
102
|
+
async add (companyId, blockCode) {
|
|
103
|
+
const response = await transport.post('/blocks', {
|
|
104
|
+
company_unique_id: companyId,
|
|
105
|
+
block_code: blockCode
|
|
106
|
+
});
|
|
107
|
+
return decodeOne(response, blockMapper);
|
|
108
|
+
},
|
|
109
|
+
async remove (id) {
|
|
110
|
+
await transport.delete(`/blocks/${id}`);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Create the services registry service
|
|
116
|
+
*/ export function createServicesRegistryService(transport, _config) {
|
|
117
|
+
return {
|
|
118
|
+
async list (params) {
|
|
119
|
+
const response = await transport.get('/services', {
|
|
120
|
+
params: buildListParams(params)
|
|
121
|
+
});
|
|
122
|
+
return decodePageResult(response, serviceMapper);
|
|
123
|
+
},
|
|
124
|
+
async get (id) {
|
|
125
|
+
const response = await transport.get(`/services/${id}`);
|
|
126
|
+
return decodeOne(response, serviceMapper);
|
|
127
|
+
},
|
|
128
|
+
async getByCode (code) {
|
|
129
|
+
const response = await transport.get(`/services/by_code/${code}`);
|
|
130
|
+
return decodeOne(response, serviceMapper);
|
|
131
|
+
},
|
|
132
|
+
async healthCheck () {
|
|
133
|
+
const response = await transport.get('/services/health');
|
|
134
|
+
return decodeMany(response, serviceMapper);
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
//# sourceMappingURL=apps.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/services/apps.service.ts"],"sourcesContent":["import type { Transport, PageResult, ListParams } from '@23blocks/contracts';\nimport type { JsonApiDocument } from '@23blocks/jsonapi-codec';\nimport { decodeOne, decodeMany, decodePageResult } from '@23blocks/jsonapi-codec';\nimport type { App, Block, Service, CreateAppRequest, UpdateAppRequest } from '../types/index.js';\nimport { appMapper, blockMapper, serviceMapper } from '../mappers/index.js';\nimport type { AuthenticationBlockConfig } from '../authentication.block.js';\n\n/**\n * Apps service interface\n */\nexport interface AppsService {\n /**\n * List apps with pagination\n */\n list(params?: ListParams): Promise<PageResult<App>>;\n\n /**\n * Get an app by ID\n */\n get(id: string): Promise<App>;\n\n /**\n * Create a new app\n */\n create(request: CreateAppRequest): Promise<App>;\n\n /**\n * Update an app\n */\n update(id: string, request: UpdateAppRequest): Promise<App>;\n\n /**\n * Delete an app\n */\n delete(id: string): Promise<void>;\n\n /**\n * Regenerate webhook secret\n */\n regenerateWebhookSecret(id: string): Promise<App>;\n}\n\n/**\n * Blocks service interface\n */\nexport interface BlocksService {\n /**\n * List blocks for a company\n */\n list(companyId: string, params?: ListParams): Promise<PageResult<Block>>;\n\n /**\n * Get a block by ID\n */\n get(id: string): Promise<Block>;\n\n /**\n * Add a block to a company\n */\n add(companyId: string, blockCode: string): Promise<Block>;\n\n /**\n * Remove a block from a company\n */\n remove(id: string): Promise<void>;\n}\n\n/**\n * Services registry service interface\n */\nexport interface ServicesRegistryService {\n /**\n * List registered services\n */\n list(params?: ListParams): Promise<PageResult<Service>>;\n\n /**\n * Get a service by ID\n */\n get(id: string): Promise<Service>;\n\n /**\n * Get a service by code\n */\n getByCode(code: string): Promise<Service>;\n\n /**\n * Health check all services\n */\n healthCheck(): Promise<Service[]>;\n}\n\n/**\n * Build filter params for list operations\n */\nfunction buildListParams(params?: ListParams): Record<string, string | number | boolean | string[] | undefined> {\n if (!params) return {};\n\n const queryParams: Record<string, string | number | boolean | string[] | undefined> = {};\n\n if (params.page) {\n queryParams['page[number]'] = params.page;\n }\n if (params.perPage) {\n queryParams['page[size]'] = params.perPage;\n }\n\n if (params.sort) {\n const sorts = Array.isArray(params.sort) ? params.sort : [params.sort];\n queryParams['sort'] = sorts\n .map((s) => (s.direction === 'desc' ? `-${s.field}` : s.field))\n .join(',');\n }\n\n if (params.filter) {\n for (const [key, value] of Object.entries(params.filter)) {\n queryParams[`filter[${key}]`] = value;\n }\n }\n\n if (params.include) {\n queryParams['include'] = params.include.join(',');\n }\n\n return queryParams;\n}\n\n/**\n * Create the apps service\n */\nexport function createAppsService(\n transport: Transport,\n _config: AuthenticationBlockConfig\n): AppsService {\n return {\n async list(params?: ListParams): Promise<PageResult<App>> {\n const response = await transport.get<JsonApiDocument>(\n '/apps',\n { params: buildListParams(params) }\n );\n return decodePageResult(response, appMapper);\n },\n\n async get(id: string): Promise<App> {\n const response = await transport.get<JsonApiDocument>(`/apps/${id}`);\n return decodeOne(response, appMapper);\n },\n\n async create(request: CreateAppRequest): Promise<App> {\n const response = await transport.post<JsonApiDocument>('/apps', {\n name: request.name,\n description: request.description,\n app_type: request.appType,\n oauth_enabled: request.oauthEnabled,\n oauth_access_token_lifetime_hours: request.oauthAccessTokenLifetimeHours,\n oauth_refresh_token_lifetime_days: request.oauthRefreshTokenLifetimeDays,\n rate_limit_per_minute: request.rateLimitPerMinute,\n rate_limit_per_hour: request.rateLimitPerHour,\n webhook_url: request.webhookUrl,\n allowed_origins: request.allowedOrigins,\n metadata: request.metadata,\n });\n return decodeOne(response, appMapper);\n },\n\n async update(id: string, request: UpdateAppRequest): Promise<App> {\n const response = await transport.patch<JsonApiDocument>(`/apps/${id}`, {\n name: request.name,\n description: request.description,\n app_type: request.appType,\n oauth_enabled: request.oauthEnabled,\n oauth_access_token_lifetime_hours: request.oauthAccessTokenLifetimeHours,\n oauth_refresh_token_lifetime_days: request.oauthRefreshTokenLifetimeDays,\n rate_limit_per_minute: request.rateLimitPerMinute,\n rate_limit_per_hour: request.rateLimitPerHour,\n webhook_url: request.webhookUrl,\n allowed_origins: request.allowedOrigins,\n metadata: request.metadata,\n status: request.status,\n });\n return decodeOne(response, appMapper);\n },\n\n async delete(id: string): Promise<void> {\n await transport.delete(`/apps/${id}`);\n },\n\n async regenerateWebhookSecret(id: string): Promise<App> {\n const response = await transport.post<JsonApiDocument>(\n `/apps/${id}/regenerate_webhook_secret`\n );\n return decodeOne(response, appMapper);\n },\n };\n}\n\n/**\n * Create the blocks service\n */\nexport function createBlocksService(\n transport: Transport,\n _config: AuthenticationBlockConfig\n): BlocksService {\n return {\n async list(companyId: string, params?: ListParams): Promise<PageResult<Block>> {\n const queryParams = buildListParams(params);\n queryParams['filter[company_unique_id]'] = companyId;\n\n const response = await transport.get<JsonApiDocument>(\n '/blocks',\n { params: queryParams }\n );\n return decodePageResult(response, blockMapper);\n },\n\n async get(id: string): Promise<Block> {\n const response = await transport.get<JsonApiDocument>(`/blocks/${id}`);\n return decodeOne(response, blockMapper);\n },\n\n async add(companyId: string, blockCode: string): Promise<Block> {\n const response = await transport.post<JsonApiDocument>('/blocks', {\n company_unique_id: companyId,\n block_code: blockCode,\n });\n return decodeOne(response, blockMapper);\n },\n\n async remove(id: string): Promise<void> {\n await transport.delete(`/blocks/${id}`);\n },\n };\n}\n\n/**\n * Create the services registry service\n */\nexport function createServicesRegistryService(\n transport: Transport,\n _config: AuthenticationBlockConfig\n): ServicesRegistryService {\n return {\n async list(params?: ListParams): Promise<PageResult<Service>> {\n const response = await transport.get<JsonApiDocument>(\n '/services',\n { params: buildListParams(params) }\n );\n return decodePageResult(response, serviceMapper);\n },\n\n async get(id: string): Promise<Service> {\n const response = await transport.get<JsonApiDocument>(`/services/${id}`);\n return decodeOne(response, serviceMapper);\n },\n\n async getByCode(code: string): Promise<Service> {\n const response = await transport.get<JsonApiDocument>(\n `/services/by_code/${code}`\n );\n return decodeOne(response, serviceMapper);\n },\n\n async healthCheck(): Promise<Service[]> {\n const response = await transport.get<JsonApiDocument>('/services/health');\n return decodeMany(response, serviceMapper);\n },\n };\n}\n"],"names":["decodeOne","decodeMany","decodePageResult","appMapper","blockMapper","serviceMapper","buildListParams","params","queryParams","page","perPage","sort","sorts","Array","isArray","map","s","direction","field","join","filter","key","value","Object","entries","include","createAppsService","transport","_config","list","response","get","id","create","request","post","name","description","app_type","appType","oauth_enabled","oauthEnabled","oauth_access_token_lifetime_hours","oauthAccessTokenLifetimeHours","oauth_refresh_token_lifetime_days","oauthRefreshTokenLifetimeDays","rate_limit_per_minute","rateLimitPerMinute","rate_limit_per_hour","rateLimitPerHour","webhook_url","webhookUrl","allowed_origins","allowedOrigins","metadata","update","patch","status","delete","regenerateWebhookSecret","createBlocksService","companyId","add","blockCode","company_unique_id","block_code","remove","createServicesRegistryService","getByCode","code","healthCheck"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { decodeOne } from '@23blocks/jsonapi-codec';
|
|
2
|
+
import { userMapper } from '../mappers/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Create the auth service
|
|
5
|
+
*/ export function createAuthService(transport, _config) {
|
|
6
|
+
return {
|
|
7
|
+
async signIn (request) {
|
|
8
|
+
var _response_meta, _response_meta1, _response_meta2, _response_meta3;
|
|
9
|
+
const response = await transport.post('/auth/sign_in', {
|
|
10
|
+
email: request.email,
|
|
11
|
+
password: request.password
|
|
12
|
+
});
|
|
13
|
+
const user = decodeOne(response, userMapper);
|
|
14
|
+
var _response_meta_access_token, _ref;
|
|
15
|
+
return {
|
|
16
|
+
user,
|
|
17
|
+
accessToken: (_ref = (_response_meta_access_token = (_response_meta = response.meta) == null ? void 0 : _response_meta.access_token) != null ? _response_meta_access_token : (_response_meta1 = response.meta) == null ? void 0 : _response_meta1.token) != null ? _ref : '',
|
|
18
|
+
refreshToken: (_response_meta2 = response.meta) == null ? void 0 : _response_meta2.refresh_token,
|
|
19
|
+
tokenType: 'Bearer',
|
|
20
|
+
expiresIn: (_response_meta3 = response.meta) == null ? void 0 : _response_meta3.expires_in
|
|
21
|
+
};
|
|
22
|
+
},
|
|
23
|
+
async signUp (request) {
|
|
24
|
+
var _response_meta, _response_meta1, _response_meta2;
|
|
25
|
+
const response = await transport.post('/auth', {
|
|
26
|
+
email: request.email,
|
|
27
|
+
password: request.password,
|
|
28
|
+
password_confirmation: request.passwordConfirmation,
|
|
29
|
+
name: request.name,
|
|
30
|
+
username: request.username,
|
|
31
|
+
role_id: request.roleId
|
|
32
|
+
});
|
|
33
|
+
const user = decodeOne(response, userMapper);
|
|
34
|
+
var _response_meta_access_token;
|
|
35
|
+
return {
|
|
36
|
+
user,
|
|
37
|
+
accessToken: (_response_meta_access_token = (_response_meta = response.meta) == null ? void 0 : _response_meta.access_token) != null ? _response_meta_access_token : (_response_meta1 = response.meta) == null ? void 0 : _response_meta1.token,
|
|
38
|
+
message: (_response_meta2 = response.meta) == null ? void 0 : _response_meta2.message
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
async signOut () {
|
|
42
|
+
await transport.delete('/auth/sign_out');
|
|
43
|
+
},
|
|
44
|
+
async validateToken () {
|
|
45
|
+
const response = await transport.get('/auth/validate_token');
|
|
46
|
+
const user = decodeOne(response, userMapper);
|
|
47
|
+
return {
|
|
48
|
+
user,
|
|
49
|
+
valid: true
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
async getCurrentUser () {
|
|
53
|
+
const response = await transport.get('/auth/validate_token', {
|
|
54
|
+
params: {
|
|
55
|
+
include: 'role,user_avatar,user_profile'
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
return decodeOne(response, userMapper);
|
|
59
|
+
},
|
|
60
|
+
async requestPasswordReset (request) {
|
|
61
|
+
await transport.post('/auth/password', {
|
|
62
|
+
email: request.email,
|
|
63
|
+
redirect_url: request.redirectUrl
|
|
64
|
+
});
|
|
65
|
+
},
|
|
66
|
+
async updatePassword (request) {
|
|
67
|
+
await transport.put('/auth/password', {
|
|
68
|
+
password: request.password,
|
|
69
|
+
password_confirmation: request.passwordConfirmation,
|
|
70
|
+
reset_password_token: request.resetPasswordToken,
|
|
71
|
+
current_password: request.currentPassword
|
|
72
|
+
});
|
|
73
|
+
},
|
|
74
|
+
async refreshToken (request) {
|
|
75
|
+
const response = await transport.post('/auth/refresh', {
|
|
76
|
+
refresh_token: request.refreshToken
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
accessToken: response.meta.access_token,
|
|
80
|
+
refreshToken: response.meta.refresh_token,
|
|
81
|
+
tokenType: 'Bearer',
|
|
82
|
+
expiresIn: response.meta.expires_in
|
|
83
|
+
};
|
|
84
|
+
},
|
|
85
|
+
async requestMagicLink (request) {
|
|
86
|
+
await transport.post('/auth/magic_link', {
|
|
87
|
+
email: request.email,
|
|
88
|
+
redirect_url: request.redirectUrl
|
|
89
|
+
});
|
|
90
|
+
},
|
|
91
|
+
async verifyMagicLink (request) {
|
|
92
|
+
var _response_meta, _response_meta1, _response_meta2;
|
|
93
|
+
const response = await transport.post('/auth/magic_link/verify', {
|
|
94
|
+
token: request.token
|
|
95
|
+
});
|
|
96
|
+
const user = decodeOne(response, userMapper);
|
|
97
|
+
var _response_meta_access_token;
|
|
98
|
+
return {
|
|
99
|
+
user,
|
|
100
|
+
accessToken: (_response_meta_access_token = (_response_meta = response.meta) == null ? void 0 : _response_meta.access_token) != null ? _response_meta_access_token : '',
|
|
101
|
+
refreshToken: (_response_meta1 = response.meta) == null ? void 0 : _response_meta1.refresh_token,
|
|
102
|
+
tokenType: 'Bearer',
|
|
103
|
+
expiresIn: (_response_meta2 = response.meta) == null ? void 0 : _response_meta2.expires_in
|
|
104
|
+
};
|
|
105
|
+
},
|
|
106
|
+
async sendInvitation (request) {
|
|
107
|
+
await transport.post('/auth/invitation', {
|
|
108
|
+
email: request.email,
|
|
109
|
+
role_id: request.roleId,
|
|
110
|
+
redirect_url: request.redirectUrl
|
|
111
|
+
});
|
|
112
|
+
},
|
|
113
|
+
async acceptInvitation (request) {
|
|
114
|
+
var _response_meta, _response_meta1, _response_meta2;
|
|
115
|
+
const response = await transport.put('/auth/invitation', {
|
|
116
|
+
invitation_token: request.invitationToken,
|
|
117
|
+
password: request.password,
|
|
118
|
+
password_confirmation: request.passwordConfirmation,
|
|
119
|
+
name: request.name
|
|
120
|
+
});
|
|
121
|
+
const user = decodeOne(response, userMapper);
|
|
122
|
+
var _response_meta_access_token;
|
|
123
|
+
return {
|
|
124
|
+
user,
|
|
125
|
+
accessToken: (_response_meta_access_token = (_response_meta = response.meta) == null ? void 0 : _response_meta.access_token) != null ? _response_meta_access_token : '',
|
|
126
|
+
refreshToken: (_response_meta1 = response.meta) == null ? void 0 : _response_meta1.refresh_token,
|
|
127
|
+
tokenType: 'Bearer',
|
|
128
|
+
expiresIn: (_response_meta2 = response.meta) == null ? void 0 : _response_meta2.expires_in
|
|
129
|
+
};
|
|
130
|
+
},
|
|
131
|
+
async confirmEmail (token) {
|
|
132
|
+
const response = await transport.get('/auth/confirmation', {
|
|
133
|
+
params: {
|
|
134
|
+
confirmation_token: token
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
return decodeOne(response, userMapper);
|
|
138
|
+
},
|
|
139
|
+
async resendConfirmation (email) {
|
|
140
|
+
await transport.post('/auth/confirmation', {
|
|
141
|
+
email
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
//# sourceMappingURL=auth.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/services/auth.service.ts"],"sourcesContent":["import type { Transport } from '@23blocks/contracts';\nimport { decodeOne } from '@23blocks/jsonapi-codec';\nimport type {\n SignInRequest,\n SignInResponse,\n SignUpRequest,\n SignUpResponse,\n PasswordResetRequest,\n PasswordUpdateRequest,\n TokenValidationResponse,\n RefreshTokenRequest,\n RefreshTokenResponse,\n MagicLinkRequest,\n MagicLinkVerifyRequest,\n InvitationRequest,\n AcceptInvitationRequest,\n User,\n} from '../types/index.js';\nimport { userMapper } from '../mappers/index.js';\nimport type { AuthenticationBlockConfig } from '../authentication.block.js';\n\n/**\n * Authentication service\n */\nexport interface AuthService {\n /**\n * Sign in with email and password\n */\n signIn(request: SignInRequest): Promise<SignInResponse>;\n\n /**\n * Sign up a new user\n */\n signUp(request: SignUpRequest): Promise<SignUpResponse>;\n\n /**\n * Sign out the current user\n */\n signOut(): Promise<void>;\n\n /**\n * Validate the current token and get user info\n */\n validateToken(): Promise<TokenValidationResponse>;\n\n /**\n * Get the current authenticated user\n */\n getCurrentUser(): Promise<User>;\n\n /**\n * Request a password reset email\n */\n requestPasswordReset(request: PasswordResetRequest): Promise<void>;\n\n /**\n * Update password (with reset token or current password)\n */\n updatePassword(request: PasswordUpdateRequest): Promise<void>;\n\n /**\n * Refresh the access token\n */\n refreshToken(request: RefreshTokenRequest): Promise<RefreshTokenResponse>;\n\n /**\n * Request a magic link for passwordless login\n */\n requestMagicLink(request: MagicLinkRequest): Promise<void>;\n\n /**\n * Verify a magic link token\n */\n verifyMagicLink(request: MagicLinkVerifyRequest): Promise<SignInResponse>;\n\n /**\n * Send an invitation to a new user\n */\n sendInvitation(request: InvitationRequest): Promise<void>;\n\n /**\n * Accept an invitation\n */\n acceptInvitation(request: AcceptInvitationRequest): Promise<SignInResponse>;\n\n /**\n * Confirm email with token\n */\n confirmEmail(token: string): Promise<User>;\n\n /**\n * Resend confirmation email\n */\n resendConfirmation(email: string): Promise<void>;\n}\n\n/**\n * Create the auth service\n */\nexport function createAuthService(\n transport: Transport,\n _config: AuthenticationBlockConfig\n): AuthService {\n return {\n async signIn(request: SignInRequest): Promise<SignInResponse> {\n const response = await transport.post<{\n data: unknown;\n meta?: { token?: string; access_token?: string; refresh_token?: string; expires_in?: number };\n }>('/auth/sign_in', {\n email: request.email,\n password: request.password,\n });\n\n const user = decodeOne(response, userMapper);\n\n return {\n user,\n accessToken: response.meta?.access_token ?? response.meta?.token ?? '',\n refreshToken: response.meta?.refresh_token,\n tokenType: 'Bearer',\n expiresIn: response.meta?.expires_in,\n };\n },\n\n async signUp(request: SignUpRequest): Promise<SignUpResponse> {\n const response = await transport.post<{\n data: unknown;\n meta?: { token?: string; access_token?: string; message?: string };\n }>('/auth', {\n email: request.email,\n password: request.password,\n password_confirmation: request.passwordConfirmation,\n name: request.name,\n username: request.username,\n role_id: request.roleId,\n });\n\n const user = decodeOne(response, userMapper);\n\n return {\n user,\n accessToken: response.meta?.access_token ?? response.meta?.token,\n message: response.meta?.message,\n };\n },\n\n async signOut(): Promise<void> {\n await transport.delete('/auth/sign_out');\n },\n\n async validateToken(): Promise<TokenValidationResponse> {\n const response = await transport.get<{ data: unknown }>('/auth/validate_token');\n const user = decodeOne(response, userMapper);\n\n return {\n user,\n valid: true,\n };\n },\n\n async getCurrentUser(): Promise<User> {\n const response = await transport.get<{ data: unknown }>(\n '/auth/validate_token',\n { params: { include: 'role,user_avatar,user_profile' } }\n );\n return decodeOne(response, userMapper);\n },\n\n async requestPasswordReset(request: PasswordResetRequest): Promise<void> {\n await transport.post('/auth/password', {\n email: request.email,\n redirect_url: request.redirectUrl,\n });\n },\n\n async updatePassword(request: PasswordUpdateRequest): Promise<void> {\n await transport.put('/auth/password', {\n password: request.password,\n password_confirmation: request.passwordConfirmation,\n reset_password_token: request.resetPasswordToken,\n current_password: request.currentPassword,\n });\n },\n\n async refreshToken(request: RefreshTokenRequest): Promise<RefreshTokenResponse> {\n const response = await transport.post<{\n meta: { access_token: string; refresh_token?: string; expires_in?: number };\n }>('/auth/refresh', {\n refresh_token: request.refreshToken,\n });\n\n return {\n accessToken: response.meta.access_token,\n refreshToken: response.meta.refresh_token,\n tokenType: 'Bearer',\n expiresIn: response.meta.expires_in,\n };\n },\n\n async requestMagicLink(request: MagicLinkRequest): Promise<void> {\n await transport.post('/auth/magic_link', {\n email: request.email,\n redirect_url: request.redirectUrl,\n });\n },\n\n async verifyMagicLink(request: MagicLinkVerifyRequest): Promise<SignInResponse> {\n const response = await transport.post<{\n data: unknown;\n meta?: { access_token?: string; refresh_token?: string; expires_in?: number };\n }>('/auth/magic_link/verify', {\n token: request.token,\n });\n\n const user = decodeOne(response, userMapper);\n\n return {\n user,\n accessToken: response.meta?.access_token ?? '',\n refreshToken: response.meta?.refresh_token,\n tokenType: 'Bearer',\n expiresIn: response.meta?.expires_in,\n };\n },\n\n async sendInvitation(request: InvitationRequest): Promise<void> {\n await transport.post('/auth/invitation', {\n email: request.email,\n role_id: request.roleId,\n redirect_url: request.redirectUrl,\n });\n },\n\n async acceptInvitation(request: AcceptInvitationRequest): Promise<SignInResponse> {\n const response = await transport.put<{\n data: unknown;\n meta?: { access_token?: string; refresh_token?: string; expires_in?: number };\n }>('/auth/invitation', {\n invitation_token: request.invitationToken,\n password: request.password,\n password_confirmation: request.passwordConfirmation,\n name: request.name,\n });\n\n const user = decodeOne(response, userMapper);\n\n return {\n user,\n accessToken: response.meta?.access_token ?? '',\n refreshToken: response.meta?.refresh_token,\n tokenType: 'Bearer',\n expiresIn: response.meta?.expires_in,\n };\n },\n\n async confirmEmail(token: string): Promise<User> {\n const response = await transport.get<{ data: unknown }>('/auth/confirmation', {\n params: { confirmation_token: token },\n });\n return decodeOne(response, userMapper);\n },\n\n async resendConfirmation(email: string): Promise<void> {\n await transport.post('/auth/confirmation', { email });\n },\n };\n}\n"],"names":["decodeOne","userMapper","createAuthService","transport","_config","signIn","request","response","post","email","password","user","accessToken","meta","access_token","token","refreshToken","refresh_token","tokenType","expiresIn","expires_in","signUp","password_confirmation","passwordConfirmation","name","username","role_id","roleId","message","signOut","delete","validateToken","get","valid","getCurrentUser","params","include","requestPasswordReset","redirect_url","redirectUrl","updatePassword","put","reset_password_token","resetPasswordToken","current_password","currentPassword","requestMagicLink","verifyMagicLink","sendInvitation","acceptInvitation","invitation_token","invitationToken","confirmEmail","confirmation_token","resendConfirmation"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|