Debug para tokens de Alai

This commit is contained in:
2026-05-04 13:39:54 +02:00
parent 331d920379
commit 113d9f3786
19 changed files with 272 additions and 45 deletions

View File

@@ -15,6 +15,8 @@ export class AlaiTokenManager implements JWTProvider<{}> {
if (res.error != undefined) {
console.error("Error obteniendo el token de ALAI", res.error)
} else {
this.authToken = new JWTToken(res.data.accessToken)
}
}

View File

@@ -0,0 +1,50 @@
import { JWTToken } from "sim-shared/domain/JWT.js";
import { JWTProvider } from "sim-shared/infrastructure/HTTPClient.js";
import { LegacyJWTTokenRepository } from "#infrastructure/LegacyJWTTokensRepository.js";
import { env } from "#config/env/env.js";
const tokenDir = String(env.ALAI_CERTIFICATES_DIR)
const tokenFile = ".debugToken"
/**
* Usa un token guardado a mano en archivo para no gastar tokens de Alai
*/
export class DebugTokenManager implements JWTProvider<{}> {
isRefreshing: boolean = false;
authToken: JWTToken<{}> | undefined;
private async getNewAuthToken() {
// TODO: Si no funcionase hay que reprogramar los mensajes para ser
// consumidos mas tarde.
const res = LegacyJWTTokenRepository.getTokenFromFile(tokenDir, tokenFile)
if (res.error != undefined) {
console.error("Error obteniendo el token de ALAI", res.error)
} else {
this.authToken = new JWTToken(res.data)
console.log("[d] Token DEBUG: ", this.authToken)
}
}
public tryRefreshToken(): Promise<JWTToken<{}>> {
// En Alai no existe el concepto de refresh, se solicita otro token nuevo
return this.getAccessToken()
};
public async getAccessToken(): Promise<JWTToken<{}>> {
// Caso 1: El token actual es valido
if (this.authToken != undefined && !this.authToken.isExpired()) {
return this.authToken
} else {
// Caso 2: El token actual no existe o ha expirado
await this.getNewAuthToken()
}
// Si después de todo no se ha generado el token es un error catastrofico
if (this.authToken == undefined) throw new Error("Error obteniendo tokens de auth")
return this.authToken
};
}

View File

@@ -74,7 +74,6 @@ export class SimAlaiController {
iccid: iccid,
correlation_id: correlation_id
}))
return res;
}
}
@@ -99,6 +98,7 @@ export class SimAlaiController {
}
}
/*
public reActivate() {
return async (msg: ConsumeMessage) => {
console.log("Evento reActivate ", msg.fields)
@@ -113,6 +113,7 @@ export class SimAlaiController {
return res;
}
}
*/
/**
* Select especificamente por REST para evitar pasar por las colas.
@@ -136,7 +137,7 @@ export class SimAlaiController {
// TODO: Automatizar la paginacion
//const usecaseRes = this.uscases.selectMany({ iccid })
} else {
const usecaseRes = await this.uscases.selectOne({ iccid })
const usecaseRes = await this.uscases.selectOne(iccid)
if (usecaseRes.error != undefined) {
res.status(500).json(usecaseRes)
return;
@@ -150,28 +151,29 @@ export class SimAlaiController {
}
}
public selectPageREST() {
return async (req: Request, res: Response) => {
const { offset, limit, filter, orderBy } = req.query
const params = {
offset: (offset != undefined) ? Number(offset) : undefined,
limit: (limit != undefined) ? Number(limit) : undefined,
filter: (filter != undefined) ? String(filter) : undefined,
orderBy: (orderBy != undefined) ? String(orderBy) : undefined
}
const usecaseRes = await this.uscases.selectPage(params)
if (usecaseRes.error != undefined) {
res.status(500).json(usecaseRes)
return;
} else {
res.status(200).send(usecaseRes.data)
return;
/**
public selectPageREST() {
return async (req: Request, res: Response) => {
const { offset, limit, filter, orderBy } = req.query
const params = {
offset: (offset != undefined) ? Number(offset) : undefined,
limit: (limit != undefined) ? Number(limit) : undefined,
filter: (filter != undefined) ? String(filter) : undefined,
orderBy: (orderBy != undefined) ? String(orderBy) : undefined
}
const usecaseRes = await this.uscases.selectPage(params)
if (usecaseRes.error != undefined) {
res.status(500).json(usecaseRes)
return;
} else {
res.status(200).send(usecaseRes.data)
return;
}
}
}
}
**/
}

View File

@@ -14,15 +14,15 @@ type FuncType = ((m: ConsumeMessage) => Promise<Result<string, any>>)
export class SimAlaiRouter {
private readonly routes: Map<string, FuncType>;
// WIP
constructor(
private readonly simController: SimAlaiController,
private readonly eventBus: EventBus
) {
this.routes = new Map<string, FuncType>([
//["select", undefined],
["activate", this.simController.activate()],
["pause", this.simController.suspend()],
["reactivate", this.simController.reActivate()],
//["reactivate", this.simController.reActivate()],
//["cancel", this.simController.terminate()],
//["preActivate", this.simController.preActivate()]
]);

View File

@@ -59,6 +59,10 @@ export class SimAlaiUsecases {
return order
}
/**
* Gestiona el ciclo de vida de una petición. No aplica
* a peticiones de lectura (no pasan por la cola y no generan un order)
*/
public usecaseTemplate<T, R>(
func: (_: T) => Promise<Result<string, R>>,
args: T,
@@ -70,6 +74,8 @@ export class SimAlaiUsecases {
this.setRunning(correlation_id)
.then()
.catch(e => console.error("Error actualizando el order", e))
else
console.warn("[!] Se ha lanzado una caso de uso sin correlation_id")
try {
const res = await func(args)
@@ -129,4 +135,9 @@ export class SimAlaiUsecases {
return reserved
}, args.iccid, args.correlation_id)
}
public async selectOne(iccid: string) {
const sim = await this.alaiRepository.getSimByICCID(iccid)
return sim
}
}

View File

@@ -13,6 +13,10 @@ export type SSLCert = {
keypem: string
}
/**
* TODO:
* - Se ha usado https.Agent en su lugar, eliminar si no se usa
*/
export class SSLCertificateLoader {
constructor(