@eva_solutions/auth-sdk 0.0.0-stage → 3.0.0-dev-20261107051125
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/CHANGELOG.md +290 -0
- package/LICENSE +21 -0
- package/README.md +481 -2
- package/dist/admin/index.cjs +4 -0
- package/dist/admin/index.d.cts +2 -0
- package/dist/admin/index.d.ts +2 -0
- package/dist/admin/index.js +1 -0
- package/dist/admin-DjvuvuI8.js +408 -0
- package/dist/admin-DjvuvuI8.js.map +1 -0
- package/dist/admin-Q6lbWqLM.cjs +419 -0
- package/dist/admin-Q6lbWqLM.cjs.map +1 -0
- package/dist/api-path-2Ulruz7R.cjs +34 -0
- package/dist/api-path-2Ulruz7R.cjs.map +1 -0
- package/dist/api-path-B-vSkL2H.js +29 -0
- package/dist/api-path-B-vSkL2H.js.map +1 -0
- package/dist/auth-19r-Q6X2.js +84 -0
- package/dist/auth-19r-Q6X2.js.map +1 -0
- package/dist/auth-DX1N5JA4.cjs +131 -0
- package/dist/auth-DX1N5JA4.cjs.map +1 -0
- package/dist/auth-handlers-B3iJaPln.js +343 -0
- package/dist/auth-handlers-B3iJaPln.js.map +1 -0
- package/dist/auth-handlers-BTbXKJms.d.ts +15 -0
- package/dist/auth-handlers-BTbXKJms.d.ts.map +1 -0
- package/dist/auth-handlers-CDzGFDTu.cjs +404 -0
- package/dist/auth-handlers-CDzGFDTu.cjs.map +1 -0
- package/dist/auth-handlers-DRUUTEtW.d.cts +15 -0
- package/dist/auth-handlers-DRUUTEtW.d.cts.map +1 -0
- package/dist/catalog-CHPqldcj.cjs +172 -0
- package/dist/catalog-CHPqldcj.cjs.map +1 -0
- package/dist/catalog-CIqpzgsM.d.cts +75 -0
- package/dist/catalog-CIqpzgsM.d.cts.map +1 -0
- package/dist/catalog-CIqpzgsM.d.ts +75 -0
- package/dist/catalog-CIqpzgsM.d.ts.map +1 -0
- package/dist/catalog-DqPhtCKZ.js +95 -0
- package/dist/catalog-DqPhtCKZ.js.map +1 -0
- package/dist/config-D6Tr7ev6.d.cts +95 -0
- package/dist/config-D6Tr7ev6.d.cts.map +1 -0
- package/dist/config-rl4_-VAq.d.ts +95 -0
- package/dist/config-rl4_-VAq.d.ts.map +1 -0
- package/dist/constants-BE1_9Tod.cjs +52 -0
- package/dist/constants-BE1_9Tod.cjs.map +1 -0
- package/dist/constants-BY7QZokc.js +29 -0
- package/dist/constants-BY7QZokc.js.map +1 -0
- package/dist/constants-CcbhOaAP.cjs +153 -0
- package/dist/constants-CcbhOaAP.cjs.map +1 -0
- package/dist/constants-rNuD5qJn.js +94 -0
- package/dist/constants-rNuD5qJn.js.map +1 -0
- package/dist/contracts/index.cjs +1006 -0
- package/dist/contracts/index.cjs.map +1 -0
- package/dist/contracts/index.d.cts +488 -0
- package/dist/contracts/index.d.cts.map +1 -0
- package/dist/contracts/index.d.ts +488 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +817 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/cookies-DCIcr7uy.cjs +94 -0
- package/dist/cookies-DCIcr7uy.cjs.map +1 -0
- package/dist/cookies-DKEC7AWv.js +71 -0
- package/dist/cookies-DKEC7AWv.js.map +1 -0
- package/dist/delegated-token-CVNbMNfy.js +426 -0
- package/dist/delegated-token-CVNbMNfy.js.map +1 -0
- package/dist/delegated-token-DHSK4rHI.cjs +461 -0
- package/dist/delegated-token-DHSK4rHI.cjs.map +1 -0
- package/dist/error-helpers-BenWu-_u.d.ts +105 -0
- package/dist/error-helpers-BenWu-_u.d.ts.map +1 -0
- package/dist/error-helpers-KBHUbkOM.d.cts +105 -0
- package/dist/error-helpers-KBHUbkOM.d.cts.map +1 -0
- package/dist/error-helpers-XCh4ZJ-g.cjs +282 -0
- package/dist/error-helpers-XCh4ZJ-g.cjs.map +1 -0
- package/dist/error-helpers-lnwgNOw9.js +145 -0
- package/dist/error-helpers-lnwgNOw9.js.map +1 -0
- package/dist/error-messages-CGpW1fsg.d.cts +48 -0
- package/dist/error-messages-CGpW1fsg.d.cts.map +1 -0
- package/dist/error-messages-CGpW1fsg.d.ts +48 -0
- package/dist/error-messages-CGpW1fsg.d.ts.map +1 -0
- package/dist/event-codes-BBJHon-I.cjs +48 -0
- package/dist/event-codes-BBJHon-I.cjs.map +1 -0
- package/dist/event-codes-BgcJWsov.d.cts +42 -0
- package/dist/event-codes-BgcJWsov.d.cts.map +1 -0
- package/dist/event-codes-BgcJWsov.d.ts +42 -0
- package/dist/event-codes-BgcJWsov.d.ts.map +1 -0
- package/dist/event-codes-DR5_VlaR.js +43 -0
- package/dist/event-codes-DR5_VlaR.js.map +1 -0
- package/dist/generic/index.cjs +91 -0
- package/dist/generic/index.cjs.map +1 -0
- package/dist/generic/index.d.cts +27 -0
- package/dist/generic/index.d.cts.map +1 -0
- package/dist/generic/index.d.ts +27 -0
- package/dist/generic/index.d.ts.map +1 -0
- package/dist/generic/index.js +80 -0
- package/dist/generic/index.js.map +1 -0
- package/dist/hono/index.cjs +309 -0
- package/dist/hono/index.cjs.map +1 -0
- package/dist/hono/index.d.cts +272 -0
- package/dist/hono/index.d.cts.map +1 -0
- package/dist/hono/index.d.ts +272 -0
- package/dist/hono/index.d.ts.map +1 -0
- package/dist/hono/index.js +290 -0
- package/dist/hono/index.js.map +1 -0
- package/dist/hono-openapi/index.cjs +326 -0
- package/dist/hono-openapi/index.cjs.map +1 -0
- package/dist/hono-openapi/index.d.cts +14 -0
- package/dist/hono-openapi/index.d.cts.map +1 -0
- package/dist/hono-openapi/index.d.ts +14 -0
- package/dist/hono-openapi/index.d.ts.map +1 -0
- package/dist/hono-openapi/index.js +307 -0
- package/dist/hono-openapi/index.js.map +1 -0
- package/dist/http-client-BVF3iktR.cjs +211 -0
- package/dist/http-client-BVF3iktR.cjs.map +1 -0
- package/dist/http-client-Da0-OMfc.js +206 -0
- package/dist/http-client-Da0-OMfc.js.map +1 -0
- package/dist/index-BYzDaMR9.d.ts +312 -0
- package/dist/index-BYzDaMR9.d.ts.map +1 -0
- package/dist/index-CNNMCrdl.d.ts +66 -0
- package/dist/index-CNNMCrdl.d.ts.map +1 -0
- package/dist/index-DBZoLU4E.d.ts +240 -0
- package/dist/index-DBZoLU4E.d.ts.map +1 -0
- package/dist/index-DcvQWByo.d.cts +66 -0
- package/dist/index-DcvQWByo.d.cts.map +1 -0
- package/dist/index-Dold-Ycb.d.cts +1711 -0
- package/dist/index-Dold-Ycb.d.cts.map +1 -0
- package/dist/index-Dold-Ycb.d.ts +1711 -0
- package/dist/index-Dold-Ycb.d.ts.map +1 -0
- package/dist/index-jAO62-OD.d.cts +240 -0
- package/dist/index-jAO62-OD.d.cts.map +1 -0
- package/dist/index-o7nXcl7z.d.cts +312 -0
- package/dist/index-o7nXcl7z.d.cts.map +1 -0
- package/dist/index.cjs +89 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +114 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +114 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/jwt-BBNqk0TV.cjs +155 -0
- package/dist/jwt-BBNqk0TV.cjs.map +1 -0
- package/dist/jwt-DhqgH94B.js +150 -0
- package/dist/jwt-DhqgH94B.js.map +1 -0
- package/dist/key-resolver-CESqj4-P.cjs +45 -0
- package/dist/key-resolver-CESqj4-P.cjs.map +1 -0
- package/dist/key-resolver-D56I2Zpz.js +34 -0
- package/dist/key-resolver-D56I2Zpz.js.map +1 -0
- package/dist/parse-error-response-6qOQS5y9.cjs +316 -0
- package/dist/parse-error-response-6qOQS5y9.cjs.map +1 -0
- package/dist/parse-error-response-BM9-kjs0.js +239 -0
- package/dist/parse-error-response-BM9-kjs0.js.map +1 -0
- package/dist/path-segment-C25i6aaH.cjs +29 -0
- package/dist/path-segment-C25i6aaH.cjs.map +1 -0
- package/dist/path-segment-CyqnaFrP.js +24 -0
- package/dist/path-segment-CyqnaFrP.js.map +1 -0
- package/dist/react/index.cjs +336 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.cts +151 -0
- package/dist/react/index.d.cts.map +1 -0
- package/dist/react/index.d.ts +151 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +300 -0
- package/dist/react/index.js.map +1 -0
- package/dist/refresh-dedup-CKaHHe7m.js +14 -0
- package/dist/refresh-dedup-CKaHHe7m.js.map +1 -0
- package/dist/refresh-dedup-CLdACQXR.cjs +19 -0
- package/dist/refresh-dedup-CLdACQXR.cjs.map +1 -0
- package/dist/rolldown-runtime-CmQyd0Gu.cjs +27 -0
- package/dist/routes-DpAzgY1V.cjs +424 -0
- package/dist/routes-DpAzgY1V.cjs.map +1 -0
- package/dist/routes-F1g5aVqP.js +347 -0
- package/dist/routes-F1g5aVqP.js.map +1 -0
- package/dist/s2s/index.cjs +24 -0
- package/dist/s2s/index.d.cts +5 -0
- package/dist/s2s/index.d.ts +5 -0
- package/dist/s2s/index.js +5 -0
- package/dist/s2s-6wbotr78.cjs +926 -0
- package/dist/s2s-6wbotr78.cjs.map +1 -0
- package/dist/s2s-B_0SIQzn.js +897 -0
- package/dist/s2s-B_0SIQzn.js.map +1 -0
- package/dist/sign-C7y6xdvT.cjs +324 -0
- package/dist/sign-C7y6xdvT.cjs.map +1 -0
- package/dist/sign-HFtcYwa-.js +259 -0
- package/dist/sign-HFtcYwa-.js.map +1 -0
- package/dist/tokens-C1nzkn21.cjs +232 -0
- package/dist/tokens-C1nzkn21.cjs.map +1 -0
- package/dist/tokens-C3Z40qd7.js +107 -0
- package/dist/tokens-C3Z40qd7.js.map +1 -0
- package/dist/types-B5sf7kKE.d.cts +52 -0
- package/dist/types-B5sf7kKE.d.cts.map +1 -0
- package/dist/types-CLOIHzRu.d.ts +96 -0
- package/dist/types-CLOIHzRu.d.ts.map +1 -0
- package/dist/types-CQTZdZIF.d.ts +52 -0
- package/dist/types-CQTZdZIF.d.ts.map +1 -0
- package/dist/types-DGeQ8j4k.d.cts +538 -0
- package/dist/types-DGeQ8j4k.d.cts.map +1 -0
- package/dist/types-DIUWza9-.d.ts +538 -0
- package/dist/types-DIUWza9-.d.ts.map +1 -0
- package/dist/types-qh6ANBCV.d.cts +96 -0
- package/dist/types-qh6ANBCV.d.cts.map +1 -0
- package/dist/webhooks/index.cjs +8 -0
- package/dist/webhooks/index.d.cts +5 -0
- package/dist/webhooks/index.d.ts +5 -0
- package/dist/webhooks/index.js +4 -0
- package/dist/webhooks-B5sAWC9W.js +74 -0
- package/dist/webhooks-B5sAWC9W.js.map +1 -0
- package/dist/webhooks-Cx11psg1.cjs +79 -0
- package/dist/webhooks-Cx11psg1.cjs.map +1 -0
- package/package.json +192 -3
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
import { t as ADMIN_ROUTES } from "./routes-F1g5aVqP.js";
|
|
2
|
+
import { t as apiPath } from "./api-path-B-vSkL2H.js";
|
|
3
|
+
import { t as parseErrorResponse, u as validateHttpsUrl } from "./parse-error-response-BM9-kjs0.js";
|
|
4
|
+
import { t as encodePathSegment } from "./path-segment-CyqnaFrP.js";
|
|
5
|
+
import { i as signS2SHeaders } from "./sign-HFtcYwa-.js";
|
|
6
|
+
// src/admin/client.ts
|
|
7
|
+
/**
|
|
8
|
+
* Cliente Admin para provisioning de service clients y gestión de usuarios
|
|
9
|
+
* en el Auth Service.
|
|
10
|
+
*
|
|
11
|
+
* REQ-ADMIN-01, REQ-ADMIN-02, REQ-ADMIN-03, REQ-ADMIN-04, REQ-ADMIN-05 LOCKED.
|
|
12
|
+
* REQ-RESTORE-01 LOCKED: endpoint POST /admin/users/:id/restore.
|
|
13
|
+
*
|
|
14
|
+
* Autenticación: firma HMAC S2S de un service client con la marca `esAdmin` (la superficie
|
|
15
|
+
* `/admin` de Auth es la única, junto con el pedido de token, que conserva la firma). Una persona,
|
|
16
|
+
* un client: el API registra el slug que firmó como `actor`.
|
|
17
|
+
*
|
|
18
|
+
* Endpoints:
|
|
19
|
+
* POST /admin/service-clients → createServiceClient
|
|
20
|
+
* GET /admin/service-clients → listServiceClients
|
|
21
|
+
* GET /admin/service-clients/:slug → getServiceClient
|
|
22
|
+
* PATCH /admin/service-clients/:slug → updateServiceClient
|
|
23
|
+
* DELETE /admin/service-clients/:slug → deleteServiceClient (204)
|
|
24
|
+
* POST /admin/service-clients/:slug/rotate-secret → rotateServiceClientSecret
|
|
25
|
+
* GET /admin/service-clients/:slug/grants → listServiceClientGrants
|
|
26
|
+
* PUT /admin/service-clients/:slug/grants → setServiceClientGrant
|
|
27
|
+
* DELETE /admin/service-clients/:slug/grants/:audience → deleteServiceClientGrant (204)
|
|
28
|
+
* GET /admin/service-clients/:slug/delegations → listServiceClientDelegations
|
|
29
|
+
* PUT /admin/service-clients/:slug/delegations → setServiceClientDelegation
|
|
30
|
+
* DELETE /admin/service-clients/:slug/delegations/:audience → deleteServiceClientDelegation (204)
|
|
31
|
+
* GET /admin/productos/:slug/permisos-autorizables → getProductoPermisosAutorizables
|
|
32
|
+
* PUT /admin/productos/:slug/permisos-autorizables → setProductoPermisosAutorizables
|
|
33
|
+
* POST /admin/empresas/:id/titular → reassignEmpresaTitular
|
|
34
|
+
* POST /admin/empresas/:id/baja → bajaEmpresa
|
|
35
|
+
* POST /admin/empresas/:id/reactivar → reactivarEmpresa
|
|
36
|
+
* PUT /admin/empresas/:id/productos/:producto → setContratacion
|
|
37
|
+
* GET /admin/productos → listProductos
|
|
38
|
+
* POST /admin/productos → createProducto (201)
|
|
39
|
+
* PATCH /admin/productos/:slug → updateProducto
|
|
40
|
+
* POST /admin/users/:id/restore → restoreUser
|
|
41
|
+
* POST /admin/webhooks/republish-pending → republishPendingWebhooks
|
|
42
|
+
* POST /admin/maintenance/cleanup → maintenanceCleanup
|
|
43
|
+
*
|
|
44
|
+
* Los paths salen de `ADMIN_ROUTES` (contrato compartido) vía `apiPath`; el slug y el id se
|
|
45
|
+
* codifican como UN segmento con `encodePathSegment` (el mismo helper del cliente S2S) antes de
|
|
46
|
+
* insertarlos. Un slug/id vacío, `.`, `..` o que no sea string devuelve un `Result` de error
|
|
47
|
+
* (`kind: 'sdk'`, `reason: 'malformed'`) sin hacer la request.
|
|
48
|
+
*/
|
|
49
|
+
const encoder = new TextEncoder();
|
|
50
|
+
/**
|
|
51
|
+
* Realiza un fetch autenticado S2S firmando el request con HMAC-SHA-256.
|
|
52
|
+
* Retorna `Result<T>` con la propiedad `data` del body de respuesta.
|
|
53
|
+
*/
|
|
54
|
+
async function adminFetch({ config, method, pathname, rawQuery = "", body }) {
|
|
55
|
+
try {
|
|
56
|
+
const bodyBytes = body !== void 0 ? encoder.encode(JSON.stringify(body)) : /* @__PURE__ */ new Uint8Array(0);
|
|
57
|
+
const url = rawQuery ? `${config.baseUrl}${pathname}?${rawQuery}` : `${config.baseUrl}${pathname}`;
|
|
58
|
+
const target = new URL(url);
|
|
59
|
+
const headers = {
|
|
60
|
+
"content-type": "application/json",
|
|
61
|
+
...await signS2SHeaders({
|
|
62
|
+
method,
|
|
63
|
+
path: target.pathname,
|
|
64
|
+
rawQuery: target.search.slice(1),
|
|
65
|
+
bodyBytes,
|
|
66
|
+
clientId: config.clientId,
|
|
67
|
+
secretHex: config.secretHex
|
|
68
|
+
})
|
|
69
|
+
};
|
|
70
|
+
const res = await fetch(url, {
|
|
71
|
+
method,
|
|
72
|
+
headers,
|
|
73
|
+
body: bodyBytes.length > 0 ? JSON.stringify(body) : void 0,
|
|
74
|
+
signal: AbortSignal.timeout(1e4)
|
|
75
|
+
});
|
|
76
|
+
if (!res.ok) {
|
|
77
|
+
const responseBody = await res.json().catch(() => null);
|
|
78
|
+
return {
|
|
79
|
+
ok: false,
|
|
80
|
+
error: parseErrorResponse(res.status, responseBody)
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (res.status === 204) return {
|
|
84
|
+
ok: true,
|
|
85
|
+
data: void 0
|
|
86
|
+
};
|
|
87
|
+
return {
|
|
88
|
+
ok: true,
|
|
89
|
+
data: (await res.json()).data
|
|
90
|
+
};
|
|
91
|
+
} catch (err) {
|
|
92
|
+
return {
|
|
93
|
+
ok: false,
|
|
94
|
+
error: {
|
|
95
|
+
kind: "sdk",
|
|
96
|
+
reason: "network",
|
|
97
|
+
message: err instanceof Error ? err.message : "Network error",
|
|
98
|
+
status: 0
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Result de error para un slug/id que no se puede usar como segmento del path. Se devuelve antes
|
|
105
|
+
* de armar la URL: `apiPath` lanzaría con un param ausente y la promesa se rechazaría.
|
|
106
|
+
*/
|
|
107
|
+
function invalidParamResult(method, param) {
|
|
108
|
+
return {
|
|
109
|
+
ok: false,
|
|
110
|
+
error: {
|
|
111
|
+
kind: "sdk",
|
|
112
|
+
reason: "malformed",
|
|
113
|
+
message: `${method}: ${param} inválido (no puede ser vacío, "." ni "..")`,
|
|
114
|
+
status: 0
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Crea un cliente Admin para provisioning del Auth Service.
|
|
120
|
+
*
|
|
121
|
+
* ADVERTENCIA: solo usar desde backends o herramientas de operador seguras — el secret del
|
|
122
|
+
* service client admin nunca debe exponerse en el cliente/browser.
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```ts
|
|
126
|
+
* const admin = createAdminClient({
|
|
127
|
+
* clientId: process.env.AUTH_ADMIN_SLUG,
|
|
128
|
+
* secretHex: process.env.AUTH_ADMIN_SECRET,
|
|
129
|
+
* baseUrl: 'https://auth.miapp.com',
|
|
130
|
+
* })
|
|
131
|
+
* const result = await admin.createServiceClient({ slug: 'mi-servicio' })
|
|
132
|
+
* if (!result.ok) return handleError(result.error)
|
|
133
|
+
* console.log('Secret (guardar ahora):', result.data.secret)
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
function createAdminClient(config) {
|
|
137
|
+
validateHttpsUrl(config.baseUrl, "AdminClientConfig.baseUrl");
|
|
138
|
+
return {
|
|
139
|
+
async createServiceClient(input) {
|
|
140
|
+
return adminFetch({
|
|
141
|
+
config,
|
|
142
|
+
method: "POST",
|
|
143
|
+
pathname: apiPath(ADMIN_ROUTES.createServiceClient),
|
|
144
|
+
body: input
|
|
145
|
+
});
|
|
146
|
+
},
|
|
147
|
+
async listServiceClients() {
|
|
148
|
+
return adminFetch({
|
|
149
|
+
config,
|
|
150
|
+
method: "GET",
|
|
151
|
+
pathname: apiPath(ADMIN_ROUTES.listServiceClients)
|
|
152
|
+
});
|
|
153
|
+
},
|
|
154
|
+
async getServiceClient(slug) {
|
|
155
|
+
const segment = encodePathSegment(slug);
|
|
156
|
+
if (segment === null) return invalidParamResult("getServiceClient", "slug");
|
|
157
|
+
return adminFetch({
|
|
158
|
+
config,
|
|
159
|
+
method: "GET",
|
|
160
|
+
pathname: apiPath(ADMIN_ROUTES.getServiceClient, { slug: segment })
|
|
161
|
+
});
|
|
162
|
+
},
|
|
163
|
+
async updateServiceClient(slug, input) {
|
|
164
|
+
const segment = encodePathSegment(slug);
|
|
165
|
+
if (segment === null) return invalidParamResult("updateServiceClient", "slug");
|
|
166
|
+
return adminFetch({
|
|
167
|
+
config,
|
|
168
|
+
method: "PATCH",
|
|
169
|
+
pathname: apiPath(ADMIN_ROUTES.updateServiceClient, { slug: segment }),
|
|
170
|
+
body: input
|
|
171
|
+
});
|
|
172
|
+
},
|
|
173
|
+
async deleteServiceClient(slug) {
|
|
174
|
+
const segment = encodePathSegment(slug);
|
|
175
|
+
if (segment === null) return invalidParamResult("deleteServiceClient", "slug");
|
|
176
|
+
return adminFetch({
|
|
177
|
+
config,
|
|
178
|
+
method: "DELETE",
|
|
179
|
+
pathname: apiPath(ADMIN_ROUTES.deleteServiceClient, { slug: segment })
|
|
180
|
+
});
|
|
181
|
+
},
|
|
182
|
+
async rotateServiceClientSecret(slug) {
|
|
183
|
+
const segment = encodePathSegment(slug);
|
|
184
|
+
if (segment === null) return invalidParamResult("rotateServiceClientSecret", "slug");
|
|
185
|
+
return adminFetch({
|
|
186
|
+
config,
|
|
187
|
+
method: "POST",
|
|
188
|
+
pathname: apiPath(ADMIN_ROUTES.rotateServiceClientSecret, { slug: segment })
|
|
189
|
+
});
|
|
190
|
+
},
|
|
191
|
+
async listServiceClientGrants(slug) {
|
|
192
|
+
const segment = encodePathSegment(slug);
|
|
193
|
+
if (segment === null) return invalidParamResult("listServiceClientGrants", "slug");
|
|
194
|
+
return adminFetch({
|
|
195
|
+
config,
|
|
196
|
+
method: "GET",
|
|
197
|
+
pathname: apiPath(ADMIN_ROUTES.listServiceClientGrants, { slug: segment })
|
|
198
|
+
});
|
|
199
|
+
},
|
|
200
|
+
async setServiceClientGrant(slug, input) {
|
|
201
|
+
const segment = encodePathSegment(slug);
|
|
202
|
+
if (segment === null) return invalidParamResult("setServiceClientGrant", "slug");
|
|
203
|
+
return adminFetch({
|
|
204
|
+
config,
|
|
205
|
+
method: "PUT",
|
|
206
|
+
pathname: apiPath(ADMIN_ROUTES.setServiceClientGrant, { slug: segment }),
|
|
207
|
+
body: input
|
|
208
|
+
});
|
|
209
|
+
},
|
|
210
|
+
async deleteServiceClientGrant(slug, audience) {
|
|
211
|
+
const segment = encodePathSegment(slug);
|
|
212
|
+
if (segment === null) return invalidParamResult("deleteServiceClientGrant", "slug");
|
|
213
|
+
const audienceSegment = encodePathSegment(audience);
|
|
214
|
+
if (audienceSegment === null) return invalidParamResult("deleteServiceClientGrant", "audience");
|
|
215
|
+
return adminFetch({
|
|
216
|
+
config,
|
|
217
|
+
method: "DELETE",
|
|
218
|
+
pathname: apiPath(ADMIN_ROUTES.deleteServiceClientGrant, {
|
|
219
|
+
slug: segment,
|
|
220
|
+
audience: audienceSegment
|
|
221
|
+
})
|
|
222
|
+
});
|
|
223
|
+
},
|
|
224
|
+
async listServiceClientDelegations(slug) {
|
|
225
|
+
const segment = encodePathSegment(slug);
|
|
226
|
+
if (segment === null) return invalidParamResult("listServiceClientDelegations", "slug");
|
|
227
|
+
return adminFetch({
|
|
228
|
+
config,
|
|
229
|
+
method: "GET",
|
|
230
|
+
pathname: apiPath(ADMIN_ROUTES.listServiceClientDelegations, { slug: segment })
|
|
231
|
+
});
|
|
232
|
+
},
|
|
233
|
+
async setServiceClientDelegation(slug, input) {
|
|
234
|
+
const segment = encodePathSegment(slug);
|
|
235
|
+
if (segment === null) return invalidParamResult("setServiceClientDelegation", "slug");
|
|
236
|
+
return adminFetch({
|
|
237
|
+
config,
|
|
238
|
+
method: "PUT",
|
|
239
|
+
pathname: apiPath(ADMIN_ROUTES.setServiceClientDelegation, { slug: segment }),
|
|
240
|
+
body: input
|
|
241
|
+
});
|
|
242
|
+
},
|
|
243
|
+
async deleteServiceClientDelegation(slug, audience) {
|
|
244
|
+
const segment = encodePathSegment(slug);
|
|
245
|
+
if (segment === null) return invalidParamResult("deleteServiceClientDelegation", "slug");
|
|
246
|
+
const audienceSegment = encodePathSegment(audience);
|
|
247
|
+
if (audienceSegment === null) return invalidParamResult("deleteServiceClientDelegation", "audience");
|
|
248
|
+
return adminFetch({
|
|
249
|
+
config,
|
|
250
|
+
method: "DELETE",
|
|
251
|
+
pathname: apiPath(ADMIN_ROUTES.deleteServiceClientDelegation, {
|
|
252
|
+
slug: segment,
|
|
253
|
+
audience: audienceSegment
|
|
254
|
+
})
|
|
255
|
+
});
|
|
256
|
+
},
|
|
257
|
+
async getProductoPermisosAutorizables(slug) {
|
|
258
|
+
const segment = encodePathSegment(slug);
|
|
259
|
+
if (segment === null) return invalidParamResult("getProductoPermisosAutorizables", "slug");
|
|
260
|
+
return adminFetch({
|
|
261
|
+
config,
|
|
262
|
+
method: "GET",
|
|
263
|
+
pathname: apiPath(ADMIN_ROUTES.getProductoPermisosAutorizables, { slug: segment })
|
|
264
|
+
});
|
|
265
|
+
},
|
|
266
|
+
async setProductoPermisosAutorizables(slug, input) {
|
|
267
|
+
const segment = encodePathSegment(slug);
|
|
268
|
+
if (segment === null) return invalidParamResult("setProductoPermisosAutorizables", "slug");
|
|
269
|
+
return adminFetch({
|
|
270
|
+
config,
|
|
271
|
+
method: "PUT",
|
|
272
|
+
pathname: apiPath(ADMIN_ROUTES.setProductoPermisosAutorizables, { slug: segment }),
|
|
273
|
+
body: input
|
|
274
|
+
});
|
|
275
|
+
},
|
|
276
|
+
async reassignEmpresaTitular(empresaId, input) {
|
|
277
|
+
const segment = encodePathSegment(empresaId);
|
|
278
|
+
if (segment === null) return invalidParamResult("reassignEmpresaTitular", "empresaId");
|
|
279
|
+
return adminFetch({
|
|
280
|
+
config,
|
|
281
|
+
method: "POST",
|
|
282
|
+
pathname: apiPath(ADMIN_ROUTES.reassignEmpresaTitular, { id: segment }),
|
|
283
|
+
body: input
|
|
284
|
+
});
|
|
285
|
+
},
|
|
286
|
+
async bajaEmpresa(empresaId) {
|
|
287
|
+
const segment = encodePathSegment(empresaId);
|
|
288
|
+
if (segment === null) return invalidParamResult("bajaEmpresa", "empresaId");
|
|
289
|
+
return adminFetch({
|
|
290
|
+
config,
|
|
291
|
+
method: "POST",
|
|
292
|
+
pathname: apiPath(ADMIN_ROUTES.bajaEmpresa, { id: segment })
|
|
293
|
+
});
|
|
294
|
+
},
|
|
295
|
+
async reactivarEmpresa(empresaId) {
|
|
296
|
+
const segment = encodePathSegment(empresaId);
|
|
297
|
+
if (segment === null) return invalidParamResult("reactivarEmpresa", "empresaId");
|
|
298
|
+
return adminFetch({
|
|
299
|
+
config,
|
|
300
|
+
method: "POST",
|
|
301
|
+
pathname: apiPath(ADMIN_ROUTES.reactivarEmpresa, { id: segment })
|
|
302
|
+
});
|
|
303
|
+
},
|
|
304
|
+
async setContratacion(empresaId, producto, input) {
|
|
305
|
+
const segment = encodePathSegment(empresaId);
|
|
306
|
+
if (segment === null) return invalidParamResult("setContratacion", "empresaId");
|
|
307
|
+
const productoSegment = encodePathSegment(producto);
|
|
308
|
+
if (productoSegment === null) return invalidParamResult("setContratacion", "producto");
|
|
309
|
+
return adminFetch({
|
|
310
|
+
config,
|
|
311
|
+
method: "PUT",
|
|
312
|
+
pathname: apiPath(ADMIN_ROUTES.setContratacion, {
|
|
313
|
+
id: segment,
|
|
314
|
+
producto: productoSegment
|
|
315
|
+
}),
|
|
316
|
+
body: input
|
|
317
|
+
});
|
|
318
|
+
},
|
|
319
|
+
async listProductos() {
|
|
320
|
+
return adminFetch({
|
|
321
|
+
config,
|
|
322
|
+
method: "GET",
|
|
323
|
+
pathname: apiPath(ADMIN_ROUTES.listProductos)
|
|
324
|
+
});
|
|
325
|
+
},
|
|
326
|
+
async createProducto(input) {
|
|
327
|
+
return adminFetch({
|
|
328
|
+
config,
|
|
329
|
+
method: "POST",
|
|
330
|
+
pathname: apiPath(ADMIN_ROUTES.createProducto),
|
|
331
|
+
body: input
|
|
332
|
+
});
|
|
333
|
+
},
|
|
334
|
+
async updateProducto(slug, input) {
|
|
335
|
+
const segment = encodePathSegment(slug);
|
|
336
|
+
if (segment === null) return invalidParamResult("updateProducto", "slug");
|
|
337
|
+
return adminFetch({
|
|
338
|
+
config,
|
|
339
|
+
method: "PATCH",
|
|
340
|
+
pathname: apiPath(ADMIN_ROUTES.updateProducto, { slug: segment }),
|
|
341
|
+
body: input
|
|
342
|
+
});
|
|
343
|
+
},
|
|
344
|
+
async restoreUser(userId) {
|
|
345
|
+
const segment = encodePathSegment(userId);
|
|
346
|
+
if (segment === null) return invalidParamResult("restoreUser", "userId");
|
|
347
|
+
return adminFetch({
|
|
348
|
+
config,
|
|
349
|
+
method: "POST",
|
|
350
|
+
pathname: apiPath(ADMIN_ROUTES.restoreUser, { id: segment })
|
|
351
|
+
});
|
|
352
|
+
},
|
|
353
|
+
async republishPendingWebhooks(query) {
|
|
354
|
+
const params = new URLSearchParams();
|
|
355
|
+
if (query?.older_than_minutes !== void 0) params.set("older_than_minutes", String(query.older_than_minutes));
|
|
356
|
+
if (query?.limit !== void 0) params.set("limit", String(query.limit));
|
|
357
|
+
return adminFetch({
|
|
358
|
+
config,
|
|
359
|
+
method: "POST",
|
|
360
|
+
pathname: apiPath(ADMIN_ROUTES.republishPendingWebhooks),
|
|
361
|
+
rawQuery: params.toString()
|
|
362
|
+
});
|
|
363
|
+
},
|
|
364
|
+
async maintenanceCleanup(query) {
|
|
365
|
+
const params = new URLSearchParams();
|
|
366
|
+
if (query?.limit !== void 0) params.set("limit", String(query.limit));
|
|
367
|
+
return adminFetch({
|
|
368
|
+
config,
|
|
369
|
+
method: "POST",
|
|
370
|
+
pathname: apiPath(ADMIN_ROUTES.maintenanceCleanup),
|
|
371
|
+
rawQuery: params.toString()
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
// src/admin/error-codes.ts
|
|
377
|
+
/**
|
|
378
|
+
* Códigos de error específicos del módulo Admin.
|
|
379
|
+
*
|
|
380
|
+
* Complementan a `ERROR_CODES` (core) para errores que solo ocurren
|
|
381
|
+
* en operaciones de provisioning de service clients.
|
|
382
|
+
*
|
|
383
|
+
* @example
|
|
384
|
+
* ```ts
|
|
385
|
+
* import { ADMIN_ERROR_CODES } from '@eva_solutions/auth-sdk/admin'
|
|
386
|
+
*
|
|
387
|
+
* if (!result.ok && result.error.code === ADMIN_ERROR_CODES.service_client_already_exists) {
|
|
388
|
+
* return res.status(409).json({ error: 'El service client ya existe' })
|
|
389
|
+
* }
|
|
390
|
+
* ```
|
|
391
|
+
*/
|
|
392
|
+
const ADMIN_ERROR_CODES = {
|
|
393
|
+
service_client_already_exists: "service_client_already_exists",
|
|
394
|
+
service_client_not_found: "service_client_not_found",
|
|
395
|
+
/**
|
|
396
|
+
* `rotate-secret` perdió contra otra rotación concurrente del mismo service client (409).
|
|
397
|
+
* El perdedor no recibe secret; es reintentable.
|
|
398
|
+
*/
|
|
399
|
+
service_client_secret_rotation_conflict: "service_client_secret_rotation_conflict",
|
|
400
|
+
/**
|
|
401
|
+
* La operación dejaría al sistema sin ningún service client admin habilitado (409): borrar,
|
|
402
|
+
* deshabilitar o quitarle `esAdmin` al último. No se aplica; habilita o crea otro admin.
|
|
403
|
+
*/
|
|
404
|
+
last_admin_client: "last_admin_client"
|
|
405
|
+
};
|
|
406
|
+
export { createAdminClient as n, ADMIN_ERROR_CODES as t };
|
|
407
|
+
|
|
408
|
+
//# sourceMappingURL=admin-DjvuvuI8.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-DjvuvuI8.js","names":[],"sources":["../src/admin/client.ts","../src/admin/error-codes.ts"],"sourcesContent":["/**\n * Cliente Admin para provisioning de service clients y gestión de usuarios\n * en el Auth Service.\n *\n * REQ-ADMIN-01, REQ-ADMIN-02, REQ-ADMIN-03, REQ-ADMIN-04, REQ-ADMIN-05 LOCKED.\n * REQ-RESTORE-01 LOCKED: endpoint POST /admin/users/:id/restore.\n *\n * Autenticación: firma HMAC S2S de un service client con la marca `esAdmin` (la superficie\n * `/admin` de Auth es la única, junto con el pedido de token, que conserva la firma). Una persona,\n * un client: el API registra el slug que firmó como `actor`.\n *\n * Endpoints:\n * POST /admin/service-clients → createServiceClient\n * GET /admin/service-clients → listServiceClients\n * GET /admin/service-clients/:slug → getServiceClient\n * PATCH /admin/service-clients/:slug → updateServiceClient\n * DELETE /admin/service-clients/:slug → deleteServiceClient (204)\n * POST /admin/service-clients/:slug/rotate-secret → rotateServiceClientSecret\n * GET /admin/service-clients/:slug/grants → listServiceClientGrants\n * PUT /admin/service-clients/:slug/grants → setServiceClientGrant\n * DELETE /admin/service-clients/:slug/grants/:audience → deleteServiceClientGrant (204)\n * GET /admin/service-clients/:slug/delegations → listServiceClientDelegations\n * PUT /admin/service-clients/:slug/delegations → setServiceClientDelegation\n * DELETE /admin/service-clients/:slug/delegations/:audience → deleteServiceClientDelegation (204)\n * GET /admin/productos/:slug/permisos-autorizables → getProductoPermisosAutorizables\n * PUT /admin/productos/:slug/permisos-autorizables → setProductoPermisosAutorizables\n * POST /admin/empresas/:id/titular → reassignEmpresaTitular\n * POST /admin/empresas/:id/baja → bajaEmpresa\n * POST /admin/empresas/:id/reactivar → reactivarEmpresa\n * PUT /admin/empresas/:id/productos/:producto → setContratacion\n * GET /admin/productos → listProductos\n * POST /admin/productos → createProducto (201)\n * PATCH /admin/productos/:slug → updateProducto\n * POST /admin/users/:id/restore → restoreUser\n * POST /admin/webhooks/republish-pending → republishPendingWebhooks\n * POST /admin/maintenance/cleanup → maintenanceCleanup\n *\n * Los paths salen de `ADMIN_ROUTES` (contrato compartido) vía `apiPath`; el slug y el id se\n * codifican como UN segmento con `encodePathSegment` (el mismo helper del cliente S2S) antes de\n * insertarlos. Un slug/id vacío, `.`, `..` o que no sea string devuelve un `Result` de error\n * (`kind: 'sdk'`, `reason: 'malformed'`) sin hacer la request.\n */\n\nimport { ADMIN_ROUTES } from '@eva_solutions/auth-contracts'\nimport { apiPath } from '../api-path'\nimport { validateHttpsUrl } from '../config'\nimport { parseErrorResponse } from '../parse-error-response'\nimport { encodePathSegment } from '../path-segment'\nimport { signS2SHeaders } from '../s2s/sign'\nimport type { Result } from '../types'\nimport type {\n AdminClientConfig,\n AdminContratacionResult,\n AdminEmpresaEstadoResult,\n AdminSetContratacionInput,\n ListServiceClientDelegationsResult,\n ProductoPermisosAutorizablesResult,\n ReassignEmpresaTitularInput,\n ReassignEmpresaTitularResult,\n ServiceClientDelegation,\n SetProductoPermisosAutorizablesInput,\n SetServiceClientDelegationInput,\n ServiceClientPublic,\n CreateServiceClientInput,\n CreateProductoInput,\n CreateServiceClientResult,\n ListProductosResult,\n ListServiceClientGrantsResult,\n ProductoResult,\n UpdateProductoInput,\n ServiceClientGrant,\n SetServiceClientGrantInput,\n UpdateServiceClientInput,\n UpdateServiceClientResult,\n RotateSecretResult,\n RestoreUserResult,\n MaintenanceCleanupQuery,\n MaintenanceCleanupResult,\n RepublishPendingWebhooksQuery,\n RepublishPendingWebhooksResult,\n} from './types'\n\nconst encoder = new TextEncoder()\n\n/**\n * Tipo del cliente Admin retornado por `createAdminClient`.\n */\nexport type AdminClient = {\n createServiceClient(\n input: CreateServiceClientInput,\n ): Promise<Result<CreateServiceClientResult>>\n listServiceClients(): Promise<Result<{ clientes: ServiceClientPublic[] }>>\n getServiceClient(\n slug: string,\n ): Promise<Result<{ cliente: ServiceClientPublic }>>\n updateServiceClient(\n slug: string,\n input: UpdateServiceClientInput,\n ): Promise<Result<UpdateServiceClientResult>>\n deleteServiceClient(slug: string): Promise<Result<void>>\n rotateServiceClientSecret(slug: string): Promise<Result<RotateSecretResult>>\n listServiceClientGrants(\n slug: string,\n ): Promise<Result<ListServiceClientGrantsResult>>\n /** Crea o reemplaza la concesión del client sobre una audiencia. */\n setServiceClientGrant(\n slug: string,\n input: SetServiceClientGrantInput,\n ): Promise<Result<{ grant: ServiceClientGrant }>>\n deleteServiceClientGrant(\n slug: string,\n audience: string,\n ): Promise<Result<void>>\n /** Lista las aristas de delegación del client (token exchange). */\n listServiceClientDelegations(\n slug: string,\n ): Promise<Result<ListServiceClientDelegationsResult>>\n /** Crea o reemplaza la arista del client hacia una audiencia delegable (`scopes`, `requiere_scope_origen`). */\n setServiceClientDelegation(\n slug: string,\n input: SetServiceClientDelegationInput,\n ): Promise<Result<{ delegation: ServiceClientDelegation }>>\n deleteServiceClientDelegation(\n slug: string,\n audience: string,\n ): Promise<Result<void>>\n /** Permisos entre empresas que el producto puede conceder en nombre de sus empresas. */\n getProductoPermisosAutorizables(\n slug: string,\n ): Promise<Result<ProductoPermisosAutorizablesResult>>\n /** Reemplaza la lista de permisos autorizables del producto (vacía = ninguno). */\n setProductoPermisosAutorizables(\n slug: string,\n input: SetProductoPermisosAutorizablesInput,\n ): Promise<Result<ProductoPermisosAutorizablesResult>>\n /** Reasigna el titular de una empresa (disputa de RUC o empresa sin titular). */\n reassignEmpresaTitular(\n empresaId: string,\n input: ReassignEmpresaTitularInput,\n ): Promise<Result<ReassignEmpresaTitularResult>>\n /** Da de baja una empresa (limpia sus sesiones activas; las autorizaciones y contrataciones dejan de valer). */\n bajaEmpresa(empresaId: string): Promise<Result<AdminEmpresaEstadoResult>>\n /** Reactiva una empresa de baja. */\n reactivarEmpresa(empresaId: string): Promise<Result<AdminEmpresaEstadoResult>>\n /** Escribe el estado y el vencimiento de la contratación de un producto por una empresa (hasta que exista facturación, así se activa a mano). */\n setContratacion(\n empresaId: string,\n producto: string,\n input: AdminSetContratacionInput,\n ): Promise<Result<AdminContratacionResult>>\n /** Lista los productos (la audiencia del access token de usuario). */\n listProductos(): Promise<Result<ListProductosResult>>\n /** Crea un producto (201). 409 si el slug existe; 400 si es una audiencia de servicio. */\n createProducto(input: CreateProductoInput): Promise<Result<ProductoResult>>\n /** Actualiza `nombre` o `enabled`. 404 si no existe; 400 con body vacío. No hay delete: se deshabilita. */\n updateProducto(\n slug: string,\n input: UpdateProductoInput,\n ): Promise<Result<ProductoResult>>\n restoreUser(userId: string): Promise<Result<RestoreUserResult>>\n republishPendingWebhooks(\n query?: RepublishPendingWebhooksQuery,\n ): Promise<Result<RepublishPendingWebhooksResult>>\n maintenanceCleanup(\n query?: MaintenanceCleanupQuery,\n ): Promise<Result<MaintenanceCleanupResult>>\n}\n\n// ---------------------------------------------------------------------------\n// Helper interno\n// ---------------------------------------------------------------------------\n\n/**\n * Realiza un fetch autenticado S2S firmando el request con HMAC-SHA-256.\n * Retorna `Result<T>` con la propiedad `data` del body de respuesta.\n */\nasync function adminFetch<T>({\n config,\n method,\n pathname,\n rawQuery = '',\n body,\n}: {\n config: AdminClientConfig\n method: string\n pathname: string\n rawQuery?: string\n body?: unknown\n}): Promise<Result<T>> {\n try {\n const bodyBytes: Uint8Array =\n body !== undefined\n ? encoder.encode(JSON.stringify(body))\n : new Uint8Array(0)\n\n const url = rawQuery\n ? `${config.baseUrl}${pathname}?${rawQuery}`\n : `${config.baseUrl}${pathname}`\n\n // Se firma el pathname y el query de la URL FINAL (incluido el prefijo de `baseUrl`), que es\n // lo que el verificador lee en `request.url`.\n const target = new URL(url)\n const authHeaders = await signS2SHeaders({\n method,\n path: target.pathname,\n rawQuery: target.search.slice(1),\n bodyBytes,\n clientId: config.clientId,\n secretHex: config.secretHex,\n })\n\n const headers: Record<string, string> = {\n 'content-type': 'application/json',\n ...authHeaders,\n }\n\n const res = await fetch(url, {\n method,\n headers,\n body: bodyBytes.length > 0 ? JSON.stringify(body) : undefined,\n signal: AbortSignal.timeout(10_000),\n })\n\n if (!res.ok) {\n const responseBody = await res.json().catch(() => null)\n return { ok: false, error: parseErrorResponse(res.status, responseBody) }\n }\n\n // 204 No Content — Result<void>\n if (res.status === 204) {\n return { ok: true, data: undefined as T }\n }\n\n const json = (await res.json()) as { data: T }\n return { ok: true, data: json.data }\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Network error'\n return {\n ok: false,\n error: {\n kind: 'sdk',\n reason: 'network',\n message,\n status: 0,\n },\n }\n }\n}\n\n/**\n * Result de error para un slug/id que no se puede usar como segmento del path. Se devuelve antes\n * de armar la URL: `apiPath` lanzaría con un param ausente y la promesa se rechazaría.\n */\nfunction invalidParamResult(method: string, param: string): Result<never> {\n return {\n ok: false,\n error: {\n kind: 'sdk',\n reason: 'malformed',\n message: `${method}: ${param} inválido (no puede ser vacío, \".\" ni \"..\")`,\n status: 0,\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Crea un cliente Admin para provisioning del Auth Service.\n *\n * ADVERTENCIA: solo usar desde backends o herramientas de operador seguras — el secret del\n * service client admin nunca debe exponerse en el cliente/browser.\n *\n * @example\n * ```ts\n * const admin = createAdminClient({\n * clientId: process.env.AUTH_ADMIN_SLUG,\n * secretHex: process.env.AUTH_ADMIN_SECRET,\n * baseUrl: 'https://auth.miapp.com',\n * })\n * const result = await admin.createServiceClient({ slug: 'mi-servicio' })\n * if (!result.ok) return handleError(result.error)\n * console.log('Secret (guardar ahora):', result.data.secret)\n * ```\n */\nexport function createAdminClient(config: AdminClientConfig): AdminClient {\n validateHttpsUrl(config.baseUrl, 'AdminClientConfig.baseUrl')\n return {\n async createServiceClient(\n input: CreateServiceClientInput,\n ): Promise<Result<CreateServiceClientResult>> {\n return adminFetch<CreateServiceClientResult>({\n config,\n method: 'POST',\n pathname: apiPath(ADMIN_ROUTES.createServiceClient),\n body: input,\n })\n },\n\n async listServiceClients(): Promise<\n Result<{ clientes: ServiceClientPublic[] }>\n > {\n return adminFetch<{ clientes: ServiceClientPublic[] }>({\n config,\n method: 'GET',\n pathname: apiPath(ADMIN_ROUTES.listServiceClients),\n })\n },\n\n async getServiceClient(\n slug: string,\n ): Promise<Result<{ cliente: ServiceClientPublic }>> {\n const segment = encodePathSegment(slug)\n if (segment === null)\n return invalidParamResult('getServiceClient', 'slug')\n return adminFetch<{ cliente: ServiceClientPublic }>({\n config,\n method: 'GET',\n pathname: apiPath(ADMIN_ROUTES.getServiceClient, { slug: segment }),\n })\n },\n\n async updateServiceClient(\n slug: string,\n input: UpdateServiceClientInput,\n ): Promise<Result<UpdateServiceClientResult>> {\n const segment = encodePathSegment(slug)\n if (segment === null) {\n return invalidParamResult('updateServiceClient', 'slug')\n }\n return adminFetch<UpdateServiceClientResult>({\n config,\n method: 'PATCH',\n pathname: apiPath(ADMIN_ROUTES.updateServiceClient, { slug: segment }),\n body: input,\n })\n },\n\n async deleteServiceClient(slug: string): Promise<Result<void>> {\n const segment = encodePathSegment(slug)\n if (segment === null) {\n return invalidParamResult('deleteServiceClient', 'slug')\n }\n return adminFetch<void>({\n config,\n method: 'DELETE',\n pathname: apiPath(ADMIN_ROUTES.deleteServiceClient, { slug: segment }),\n })\n },\n\n async rotateServiceClientSecret(\n slug: string,\n ): Promise<Result<RotateSecretResult>> {\n const segment = encodePathSegment(slug)\n if (segment === null) {\n return invalidParamResult('rotateServiceClientSecret', 'slug')\n }\n return adminFetch<RotateSecretResult>({\n config,\n method: 'POST',\n pathname: apiPath(ADMIN_ROUTES.rotateServiceClientSecret, {\n slug: segment,\n }),\n })\n },\n\n async listServiceClientGrants(\n slug: string,\n ): Promise<Result<ListServiceClientGrantsResult>> {\n const segment = encodePathSegment(slug)\n if (segment === null) {\n return invalidParamResult('listServiceClientGrants', 'slug')\n }\n return adminFetch<ListServiceClientGrantsResult>({\n config,\n method: 'GET',\n pathname: apiPath(ADMIN_ROUTES.listServiceClientGrants, {\n slug: segment,\n }),\n })\n },\n\n async setServiceClientGrant(\n slug: string,\n input: SetServiceClientGrantInput,\n ): Promise<Result<{ grant: ServiceClientGrant }>> {\n const segment = encodePathSegment(slug)\n if (segment === null) {\n return invalidParamResult('setServiceClientGrant', 'slug')\n }\n return adminFetch<{ grant: ServiceClientGrant }>({\n config,\n method: 'PUT',\n pathname: apiPath(ADMIN_ROUTES.setServiceClientGrant, {\n slug: segment,\n }),\n body: input,\n })\n },\n\n async deleteServiceClientGrant(\n slug: string,\n audience: string,\n ): Promise<Result<void>> {\n const segment = encodePathSegment(slug)\n if (segment === null) {\n return invalidParamResult('deleteServiceClientGrant', 'slug')\n }\n const audienceSegment = encodePathSegment(audience)\n if (audienceSegment === null) {\n return invalidParamResult('deleteServiceClientGrant', 'audience')\n }\n return adminFetch<void>({\n config,\n method: 'DELETE',\n pathname: apiPath(ADMIN_ROUTES.deleteServiceClientGrant, {\n slug: segment,\n audience: audienceSegment,\n }),\n })\n },\n\n async listServiceClientDelegations(\n slug: string,\n ): Promise<Result<ListServiceClientDelegationsResult>> {\n const segment = encodePathSegment(slug)\n if (segment === null) {\n return invalidParamResult('listServiceClientDelegations', 'slug')\n }\n return adminFetch<ListServiceClientDelegationsResult>({\n config,\n method: 'GET',\n pathname: apiPath(ADMIN_ROUTES.listServiceClientDelegations, {\n slug: segment,\n }),\n })\n },\n\n async setServiceClientDelegation(\n slug: string,\n input: SetServiceClientDelegationInput,\n ): Promise<Result<{ delegation: ServiceClientDelegation }>> {\n const segment = encodePathSegment(slug)\n if (segment === null) {\n return invalidParamResult('setServiceClientDelegation', 'slug')\n }\n return adminFetch<{ delegation: ServiceClientDelegation }>({\n config,\n method: 'PUT',\n pathname: apiPath(ADMIN_ROUTES.setServiceClientDelegation, {\n slug: segment,\n }),\n body: input,\n })\n },\n\n async deleteServiceClientDelegation(\n slug: string,\n audience: string,\n ): Promise<Result<void>> {\n const segment = encodePathSegment(slug)\n if (segment === null) {\n return invalidParamResult('deleteServiceClientDelegation', 'slug')\n }\n const audienceSegment = encodePathSegment(audience)\n if (audienceSegment === null) {\n return invalidParamResult('deleteServiceClientDelegation', 'audience')\n }\n return adminFetch<void>({\n config,\n method: 'DELETE',\n pathname: apiPath(ADMIN_ROUTES.deleteServiceClientDelegation, {\n slug: segment,\n audience: audienceSegment,\n }),\n })\n },\n\n async getProductoPermisosAutorizables(\n slug: string,\n ): Promise<Result<ProductoPermisosAutorizablesResult>> {\n const segment = encodePathSegment(slug)\n if (segment === null) {\n return invalidParamResult('getProductoPermisosAutorizables', 'slug')\n }\n return adminFetch<ProductoPermisosAutorizablesResult>({\n config,\n method: 'GET',\n pathname: apiPath(ADMIN_ROUTES.getProductoPermisosAutorizables, {\n slug: segment,\n }),\n })\n },\n\n async setProductoPermisosAutorizables(\n slug: string,\n input: SetProductoPermisosAutorizablesInput,\n ): Promise<Result<ProductoPermisosAutorizablesResult>> {\n const segment = encodePathSegment(slug)\n if (segment === null) {\n return invalidParamResult('setProductoPermisosAutorizables', 'slug')\n }\n return adminFetch<ProductoPermisosAutorizablesResult>({\n config,\n method: 'PUT',\n pathname: apiPath(ADMIN_ROUTES.setProductoPermisosAutorizables, {\n slug: segment,\n }),\n body: input,\n })\n },\n\n async reassignEmpresaTitular(\n empresaId: string,\n input: ReassignEmpresaTitularInput,\n ): Promise<Result<ReassignEmpresaTitularResult>> {\n const segment = encodePathSegment(empresaId)\n if (segment === null) {\n return invalidParamResult('reassignEmpresaTitular', 'empresaId')\n }\n return adminFetch<ReassignEmpresaTitularResult>({\n config,\n method: 'POST',\n pathname: apiPath(ADMIN_ROUTES.reassignEmpresaTitular, { id: segment }),\n body: input,\n })\n },\n\n async bajaEmpresa(\n empresaId: string,\n ): Promise<Result<AdminEmpresaEstadoResult>> {\n const segment = encodePathSegment(empresaId)\n if (segment === null) {\n return invalidParamResult('bajaEmpresa', 'empresaId')\n }\n return adminFetch<AdminEmpresaEstadoResult>({\n config,\n method: 'POST',\n pathname: apiPath(ADMIN_ROUTES.bajaEmpresa, { id: segment }),\n })\n },\n\n async reactivarEmpresa(\n empresaId: string,\n ): Promise<Result<AdminEmpresaEstadoResult>> {\n const segment = encodePathSegment(empresaId)\n if (segment === null) {\n return invalidParamResult('reactivarEmpresa', 'empresaId')\n }\n return adminFetch<AdminEmpresaEstadoResult>({\n config,\n method: 'POST',\n pathname: apiPath(ADMIN_ROUTES.reactivarEmpresa, { id: segment }),\n })\n },\n\n async setContratacion(\n empresaId: string,\n producto: string,\n input: AdminSetContratacionInput,\n ): Promise<Result<AdminContratacionResult>> {\n const segment = encodePathSegment(empresaId)\n if (segment === null) {\n return invalidParamResult('setContratacion', 'empresaId')\n }\n const productoSegment = encodePathSegment(producto)\n if (productoSegment === null) {\n return invalidParamResult('setContratacion', 'producto')\n }\n return adminFetch<AdminContratacionResult>({\n config,\n method: 'PUT',\n pathname: apiPath(ADMIN_ROUTES.setContratacion, {\n id: segment,\n producto: productoSegment,\n }),\n body: input,\n })\n },\n\n async listProductos(): Promise<Result<ListProductosResult>> {\n return adminFetch<ListProductosResult>({\n config,\n method: 'GET',\n pathname: apiPath(ADMIN_ROUTES.listProductos),\n })\n },\n\n async createProducto(\n input: CreateProductoInput,\n ): Promise<Result<ProductoResult>> {\n return adminFetch<ProductoResult>({\n config,\n method: 'POST',\n pathname: apiPath(ADMIN_ROUTES.createProducto),\n body: input,\n })\n },\n\n async updateProducto(\n slug: string,\n input: UpdateProductoInput,\n ): Promise<Result<ProductoResult>> {\n const segment = encodePathSegment(slug)\n if (segment === null) return invalidParamResult('updateProducto', 'slug')\n return adminFetch<ProductoResult>({\n config,\n method: 'PATCH',\n pathname: apiPath(ADMIN_ROUTES.updateProducto, { slug: segment }),\n body: input,\n })\n },\n\n async restoreUser(userId: string): Promise<Result<RestoreUserResult>> {\n const segment = encodePathSegment(userId)\n if (segment === null) return invalidParamResult('restoreUser', 'userId')\n return adminFetch<RestoreUserResult>({\n config,\n method: 'POST',\n pathname: apiPath(ADMIN_ROUTES.restoreUser, { id: segment }),\n })\n },\n\n async republishPendingWebhooks(\n query?: RepublishPendingWebhooksQuery,\n ): Promise<Result<RepublishPendingWebhooksResult>> {\n const params = new URLSearchParams()\n if (query?.older_than_minutes !== undefined) {\n params.set('older_than_minutes', String(query.older_than_minutes))\n }\n if (query?.limit !== undefined) {\n params.set('limit', String(query.limit))\n }\n return adminFetch<RepublishPendingWebhooksResult>({\n config,\n method: 'POST',\n pathname: apiPath(ADMIN_ROUTES.republishPendingWebhooks),\n rawQuery: params.toString(),\n })\n },\n\n async maintenanceCleanup(\n query?: MaintenanceCleanupQuery,\n ): Promise<Result<MaintenanceCleanupResult>> {\n const params = new URLSearchParams()\n if (query?.limit !== undefined) {\n params.set('limit', String(query.limit))\n }\n return adminFetch<MaintenanceCleanupResult>({\n config,\n method: 'POST',\n pathname: apiPath(ADMIN_ROUTES.maintenanceCleanup),\n rawQuery: params.toString(),\n })\n },\n }\n}\n","/**\n * Códigos de error específicos del módulo Admin.\n *\n * Complementan a `ERROR_CODES` (core) para errores que solo ocurren\n * en operaciones de provisioning de service clients.\n *\n * @example\n * ```ts\n * import { ADMIN_ERROR_CODES } from '@eva_solutions/auth-sdk/admin'\n *\n * if (!result.ok && result.error.code === ADMIN_ERROR_CODES.service_client_already_exists) {\n * return res.status(409).json({ error: 'El service client ya existe' })\n * }\n * ```\n */\nexport const ADMIN_ERROR_CODES = {\n service_client_already_exists: 'service_client_already_exists',\n service_client_not_found: 'service_client_not_found',\n /**\n * `rotate-secret` perdió contra otra rotación concurrente del mismo service client (409).\n * El perdedor no recibe secret; es reintentable.\n */\n service_client_secret_rotation_conflict:\n 'service_client_secret_rotation_conflict',\n /**\n * La operación dejaría al sistema sin ningún service client admin habilitado (409): borrar,\n * deshabilitar o quitarle `esAdmin` al último. No se aplica; habilita o crea otro admin.\n */\n last_admin_client: 'last_admin_client',\n} as const\n\n/** Unión de literales de los error codes específicos del módulo Admin. */\nexport type AdminErrorCode =\n (typeof ADMIN_ERROR_CODES)[keyof typeof ADMIN_ERROR_CODES]\n"],"mappings":"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"}
|