moallem all endpoints working

This commit is contained in:
2026-06-14 16:42:52 +03:30
parent 7a6e482586
commit 2212f6da41
18 changed files with 833 additions and 234 deletions

View File

@@ -1,6 +1,10 @@
import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import axios, { AxiosError, AxiosInstance } from 'axios';
import { AxiosError, AxiosInstance } from 'axios';
import {
createOutboundAxiosInstance,
isOutboundHttpDebugEnabled,
} from '../../common/helpers/http-client.helper';
import { InquiryType } from '../../common/enums/inquiry-type.enum';
import { ProviderName } from '../../common/enums/provider-name.enum';
import { AmitisAuthServiceConfig } from '../../config/configuration';
@@ -22,6 +26,8 @@ interface CentInsurTokenResponse {
ExpiresIn?: number | string;
expiresIn?: number | string;
expires_in?: number | string;
IsSucceed?: boolean;
LoginStatus?: number;
data?: CentInsurTokenResponse;
}
@@ -49,7 +55,7 @@ export class AmitisProvider {
private readonly generalTokenService: GeneralTokenService,
) {
this.config = configService.get<AmitisAuthServiceConfig>('amitis')!;
this.httpClient = axios.create({
this.httpClient = createOutboundAxiosInstance({
baseURL: this.config.baseUrl,
timeout: this.config.timeout,
});
@@ -102,25 +108,36 @@ export class AmitisProvider {
username: string,
password: string,
): Promise<string> {
// Use FormData for multipart/form-data format
const FormData = require('form-data');
const formData = new FormData();
formData.append('username', username);
formData.append('password', password);
const loginBody = new URLSearchParams({
username: username.toLowerCase(),
password,
});
try {
const loginUrl = `${this.config.baseUrl}${this.config.loginPath}`;
this.logger.log(
`AMITIS login → POST ${loginUrl} | provider=${providerName} | inquiry=${inquiryType} | username=${username.toLowerCase()}`,
);
const response = await this.httpClient.post<CentInsurTokenResponse>(
this.config.loginPath,
formData,
loginBody.toString(),
{
headers: {
...formData.getHeaders(),
'Content-Type': 'application/x-www-form-urlencoded',
},
},
);
if (isOutboundHttpDebugEnabled()) {
this.logger.log(
`AMITIS login ← ${response.status} | provider=${providerName} | inquiry=${inquiryType} | bodyKeys=${Object.keys(response.data ?? {}).join(',') || 'none'}`,
);
}
const token = this.extractToken(response.data);
await this.saveToken(token, providerName, inquiryType, username, 'login');
await this.saveToken(token, providerName, inquiryType, username, password, 'login');
return token.accessToken;
} catch (error) {
throw this.toAuthError(`AMITIS login failed for ${providerName}/${inquiryType}`, error);
@@ -144,6 +161,7 @@ export class AmitisProvider {
providerName,
inquiryType,
latestToken.username,
latestToken.clientSecret,
'refresh',
);
return token.accessToken;
@@ -160,15 +178,16 @@ export class AmitisProvider {
providerName: ProviderName,
inquiryType: InquiryType,
username: string,
password: string,
scope: string,
): Promise<void> {
await this.generalTokenService.create({
serviceProvider: this.getTokenKey(providerName, inquiryType),
tokenType: token.tokenType,
url: this.config.baseUrl,
clientId: '',
clientSecret: '',
username,
clientId: username.toLowerCase(),
clientSecret: password,
username: username.toLowerCase(),
scope,
accessToken: token.accessToken,
refreshToken: token.refreshToken,
@@ -182,11 +201,21 @@ export class AmitisProvider {
fallbackRefreshToken?: string,
): AmitisAuthToken {
const body = responseBody.data ?? responseBody;
if (body.IsSucceed === false) {
throw new Error(
`AMITIS login rejected (LoginStatus=${body.LoginStatus ?? 'unknown'})`,
);
}
const accessToken =
body.Token ?? body.token ?? body.AccessToken ?? body.accessToken ?? body.access_token;
if (!accessToken) {
throw new Error('AMITIS auth response did not include an access token');
if (!accessToken || !String(accessToken).trim()) {
const bodyPreview = JSON.stringify(responseBody).slice(0, 500);
throw new Error(
`AMITIS auth response did not include an access token | body=${bodyPreview}`,
);
}
const expiresIn = Number(body.ExpiresIn ?? body.expiresIn ?? body.expires_in ?? 20 * 60);
@@ -229,7 +258,13 @@ export class AmitisProvider {
private toAuthError(message: string, error: unknown): Error {
if (error instanceof AxiosError) {
const status = error.response?.status ?? 'NETWORK_ERROR';
return new Error(`${message}: ${status} ${error.message}`);
const body =
error.response?.data !== undefined
? JSON.stringify(error.response.data).slice(0, 500)
: undefined;
return new Error(
body ? `${message}: ${status} ${error.message} | body=${body}` : `${message}: ${status} ${error.message}`,
);
}
if (error instanceof Error) {