docs: add test data for login; feat: ID.Not dev flow tweaks; chore: nginx dev host adjustments
All checks were successful
Build and Push to Registry / build-and-push (push) Successful in 47s
All checks were successful
Build and Push to Registry / build-and-push (push) Successful in 47s
This commit is contained in:
parent
7c5c4ab334
commit
ba2c36c014
@ -23,7 +23,7 @@ server {
|
||||
if ($request_method = OPTIONS) {
|
||||
add_header Access-Control-Allow-Origin $cors_origin always;
|
||||
add_header Access-Control-Allow-Credentials "true" always;
|
||||
add_header Access-Control-Allow-Headers "Content-Type, Authorization, x-session-id" always;
|
||||
add_header Access-Control-Allow-Headers "Content-Type, Authorization, x-session-id, x-request-id" always;
|
||||
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
|
||||
add_header Vary "Origin, Access-Control-Request-Method, Access-Control-Request-Headers" always;
|
||||
return 204;
|
||||
@ -32,7 +32,47 @@ server {
|
||||
# En-têtes CORS pour les autres méthodes
|
||||
add_header Access-Control-Allow-Origin $cors_origin always;
|
||||
add_header Access-Control-Allow-Credentials "true" always;
|
||||
add_header Access-Control-Allow-Headers "Content-Type, Authorization, x-session-id" always;
|
||||
add_header Access-Control-Allow-Headers "Content-Type, Authorization, x-session-id, x-request-id" always;
|
||||
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
|
||||
add_header Vary "Origin, Access-Control-Request-Method, Access-Control-Request-Headers" always;
|
||||
add_header X-Request-Id $request_id always;
|
||||
|
||||
proxy_pass http://127.0.0.1:8080;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Request-Id $request_id;
|
||||
}
|
||||
|
||||
# Redirection front (authorized-client) -> backend Express
|
||||
location = /authorized-client {
|
||||
# Masquer les en-têtes CORS envoyés par l'upstream (Express)
|
||||
proxy_hide_header Access-Control-Allow-Origin;
|
||||
proxy_hide_header Access-Control-Allow-Credentials;
|
||||
proxy_hide_header Access-Control-Allow-Headers;
|
||||
proxy_hide_header Access-Control-Allow-Methods;
|
||||
|
||||
# CORS dynamique
|
||||
set $cors_origin "";
|
||||
if ($http_origin ~* ^(https://dev4\.4nkweb\.com|http://local\.4nkweb\.com:3000|http://localhost:3000|https://.*\.4nkweb\.com)$) {
|
||||
set $cors_origin $http_origin;
|
||||
}
|
||||
|
||||
# Préflight OPTIONS
|
||||
if ($request_method = OPTIONS) {
|
||||
add_header Access-Control-Allow-Origin $cors_origin always;
|
||||
add_header Access-Control-Allow-Credentials "true" always;
|
||||
add_header Access-Control-Allow-Headers "Content-Type, Authorization, x-session-id, x-request-id" always;
|
||||
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
|
||||
add_header Vary "Origin, Access-Control-Request-Method, Access-Control-Request-Headers" always;
|
||||
return 204;
|
||||
}
|
||||
|
||||
# En-têtes CORS pour les autres méthodes
|
||||
add_header Access-Control-Allow-Origin $cors_origin always;
|
||||
add_header Access-Control-Allow-Credentials "true" always;
|
||||
add_header Access-Control-Allow-Headers "Content-Type, Authorization, x-session-id, x-request-id" always;
|
||||
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
|
||||
add_header Vary "Origin, Access-Control-Request-Method, Access-Control-Request-Headers" always;
|
||||
add_header X-Request-Id $request_id always;
|
||||
|
337
docs/data_account_test.md
Normal file
337
docs/data_account_test.md
Normal file
@ -0,0 +1,337 @@
|
||||
# Data de test
|
||||
|
||||
## Environnement
|
||||
|
||||
- Environnement : DEV
|
||||
- IDN : IDN96755310A
|
||||
- Environnement de production : Non
|
||||
- Code de l'environnement : DEV
|
||||
- Description : Environnement de developpement
|
||||
- URL : https://lecoffreio.4nkweb.com/*
|
||||
- ID.not : OpenID
|
||||
- API Annuaire : true
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "5207116884324909574",
|
||||
"idn": "APP14191728A",
|
||||
"label": "LeCoffre",
|
||||
"description": "A remplir par le propriétaire",
|
||||
"code": "LECOFFRE",
|
||||
"technologies": [
|
||||
"a préciser"
|
||||
],
|
||||
"status": "ACCEPTED",
|
||||
"environments": [
|
||||
{
|
||||
"id": "5737646715224215506",
|
||||
"idn": "IDN96755310A",
|
||||
"description": "Environnement de developpement ",
|
||||
"code": "DEV",
|
||||
"isProduction": false,
|
||||
"url": "https://lecoffreio.4nkweb.com/*",
|
||||
"deploymentTarget": "2025-04-11",
|
||||
"status": "OK",
|
||||
"hasOpenId": true,
|
||||
"hasSaml": false,
|
||||
"hasDirectoryApi": true,
|
||||
"access": "OPEN",
|
||||
"hasPendingAccess": false
|
||||
}
|
||||
],
|
||||
"owner": {
|
||||
"idn": "IDN369599",
|
||||
"label": "Not.IT (Fonds de dotation technologique porté par les Notaires d'Ille-et-Vilaine)",
|
||||
"intitule": "Not.IT (Fonds de dotation technologique porté par les Notaires d'Ille-et-Vilaine)"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
openId:
|
||||
|
||||
```json
|
||||
{
|
||||
"openIdData": {
|
||||
"idpClientLabel": "1.0",
|
||||
"wellKnownUrl": "https://qual-connexion.idnot.fr/IdPOAuth2/idnot_idp_v1/.well-known/openid-configuration",
|
||||
"logoutUrl": "https://qual-connexion.idnot.fr/user/auth/logout?sourceURL=VOTRE_URL",
|
||||
"callbackUrls": [
|
||||
"https://lecoffreio.4nkweb.com/*",
|
||||
"https://lecoffreio.4nkweb.com/folders",
|
||||
"https://lecoffreio.4nkweb.com/authorized-client",
|
||||
"https://oauth.pstmn.io/v1/browser-callback",
|
||||
"http://local.lecoffreio.4nkweb:3000/*",
|
||||
"https://oauth.pstmn.io/v1/callback",
|
||||
"https://test.lecoffre.io/*",
|
||||
"https://test.lecoffre.io/authorized-client",
|
||||
"http://local.4nkweb.com:3000/authorized-client",
|
||||
"http://local.lecoffreio.4nkweb"
|
||||
],
|
||||
"clientId": ""******"",
|
||||
"clientSecret": "******"
|
||||
},
|
||||
"askedInfos": {
|
||||
"firstname": "Admin",
|
||||
"lastname": "KOGUS",
|
||||
"date": "2025-04-10T14:00:55.458537Z"
|
||||
},
|
||||
"validatedInfos": {
|
||||
"firstname": "Haitam",
|
||||
"lastname": "TANASSA",
|
||||
"date": "2025-04-14T08:18:01.880555Z",
|
||||
"justification": null
|
||||
},
|
||||
"openIdScopes": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"asked": false,
|
||||
"justification": ""
|
||||
}
|
||||
},
|
||||
"scopeStatus": "ACCEPTED"
|
||||
}
|
||||
```
|
||||
|
||||
## Utilisateur
|
||||
|
||||
- Identifiant code : IDN00082246I
|
||||
- Identifiant : marie.curie.519
|
||||
- Nom : Marie Curie
|
||||
- Administrateur @ ABBATE et associés
|
||||
- login : marie.curie.519
|
||||
- pass: "******"
|
||||
|
||||
Infos basiques:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "OK",
|
||||
"success": true,
|
||||
"idn": "IDN00082246I",
|
||||
"civilite": "Madame",
|
||||
"nomDeNaissance": "CURIE",
|
||||
"nomUsuel": "CURIE",
|
||||
"prenom": "Marie",
|
||||
"jourDeNaissance": "08",
|
||||
"moisDeNaissance": "04",
|
||||
"anneeDeNaissance": "1965",
|
||||
"paysDeNaissance": {
|
||||
"nom": null,
|
||||
"code": "France"
|
||||
},
|
||||
"communeDeNaissance": "MONTÉLIMAR",
|
||||
"photo": "",
|
||||
"managedByFicen": true,
|
||||
"completion": 0,
|
||||
"interne": true,
|
||||
"languages": [
|
||||
"FR"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Infos détaillées:
|
||||
|
||||
```json
|
||||
{
|
||||
"firstName": "Marie",
|
||||
"lastName": "CURIE",
|
||||
"activated": true,
|
||||
"langKey": "fr",
|
||||
"authorities": [
|
||||
"ROLE_INTERNE"
|
||||
],
|
||||
"entityAuthorities": [
|
||||
{
|
||||
"oid": "IDN187087",
|
||||
"role": "ROLE_GESTIONNAIRE_NATUREL",
|
||||
"authority": "ROLE_GESTIONNAIRE_NATUREL - IDN187087"
|
||||
}
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"id": "IDN187087",
|
||||
"name": "ABBATE et associés",
|
||||
"logo": null,
|
||||
"adresseGeographique": null,
|
||||
"adressePostale": null,
|
||||
"telephone": "04 94 00 52 90",
|
||||
"email": "abbate.gabolde@notaires.fr",
|
||||
"siteInternet": "www.carqueiranne-abbate-gabolde-servel.notaires.fr",
|
||||
"identifiantNotaconnect": "IDN187087",
|
||||
"nomAbrege": "ABBATE et associés",
|
||||
"courDappel": null,
|
||||
"departementsCouverts": [],
|
||||
"crpcen": "083079",
|
||||
"type": "STON",
|
||||
"typeEntite": "office",
|
||||
"statut": "Pourvu",
|
||||
"residence": "CARQUEIRANNE (83034)",
|
||||
"departementDeResidence": "083 - VAR",
|
||||
"siren": "423762640",
|
||||
"siret": "42376264000013",
|
||||
"idnRattachement": null,
|
||||
"ctmAdrGeoVille": "CARQUEIRANNE",
|
||||
"ctmAdrGeoCodePostal": "83320",
|
||||
"ctmAdrGeo1": null,
|
||||
"ctmAdrGeo2": null,
|
||||
"ctmAdrGeo3": null,
|
||||
"ctmAdrGeo4": null,
|
||||
"ctmAdrGeo5": null,
|
||||
"ctmAdrPostaleCodePostal": "83320",
|
||||
"ctmAdrPostaleVille": "CARQUEIRANNE",
|
||||
"ctmAdrPostale1": null,
|
||||
"ctmAdrPostale2": null,
|
||||
"ctmAdrPostale3": null,
|
||||
"ctmAdrPostale4": "1 AVENUE JEAN JAURES",
|
||||
"ctmAdrPostale5": "BP 14",
|
||||
"ctmDenominationSociale": "SCP Louis ABBATE, Gabriel GABOLDE et Laura SERVEL-SCHROEDER",
|
||||
"ctmDenominationSocialeAbregee": "ABBATE et associés",
|
||||
"ctmIntitule": "ABBATE Louis, GABOLDE Gabriel et SERVEL-SCHROEDER Laura",
|
||||
"ctmFormeJuridique": "SCP",
|
||||
"ctmLibelle": null,
|
||||
"rattachement": {
|
||||
"id": "IDN00082246I_IDN187087",
|
||||
"email": "marie.curie.519@notaires.fr",
|
||||
"blocked": false,
|
||||
"phoneNumber": null,
|
||||
"homePhoneNumber": null,
|
||||
"entityType": "office",
|
||||
"linkType": "Administrateur",
|
||||
"subLinkType": null,
|
||||
"activitiesDomain": [],
|
||||
"mandats": [],
|
||||
"manager": true,
|
||||
"naturalManager": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"idn": "IDN00082246I",
|
||||
"civilite": "Madame",
|
||||
"photo": "",
|
||||
"email": "personaIDN00082246I@portail.com",
|
||||
"pseudo": "marie.curie.519",
|
||||
"backupEmail": "nicolas.cantu@pm.me",
|
||||
"emailValidated": "true"
|
||||
}
|
||||
```
|
||||
|
||||
### Informations de secours
|
||||
|
||||
- Email de récupération : personaIDN00082246I@portail.com
|
||||
- Email de récupération de secours : nicolas.cantu@pm.me
|
||||
|
||||
## Office de rattachement
|
||||
|
||||
```json
|
||||
{
|
||||
"firstName": "Marie",
|
||||
"lastName": "CURIE",
|
||||
"activated": true,
|
||||
"langKey": "fr",
|
||||
"authorities": [
|
||||
"ROLE_INTERNE"
|
||||
],
|
||||
"entityAuthorities": [
|
||||
{
|
||||
"oid": "IDN187087",
|
||||
"role": "ROLE_GESTIONNAIRE_NATUREL",
|
||||
"authority": "ROLE_GESTIONNAIRE_NATUREL - IDN187087"
|
||||
}
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"id": "IDN187087",
|
||||
"name": "ABBATE et associés",
|
||||
"logo": null,
|
||||
"adresseGeographique": null,
|
||||
"adressePostale": null,
|
||||
"telephone": "04 94 00 52 90",
|
||||
"email": "abbate.gabolde@notaires.fr",
|
||||
"siteInternet": "www.carqueiranne-abbate-gabolde-servel.notaires.fr",
|
||||
"identifiantNotaconnect": "IDN187087",
|
||||
"nomAbrege": "ABBATE et associés",
|
||||
"courDappel": null,
|
||||
"departementsCouverts": [],
|
||||
"crpcen": "083079",
|
||||
"type": "STON",
|
||||
"typeEntite": "office",
|
||||
"statut": "Pourvu",
|
||||
"residence": "CARQUEIRANNE (83034)",
|
||||
"departementDeResidence": "083 - VAR",
|
||||
"siren": "423762640",
|
||||
"siret": "42376264000013",
|
||||
"idnRattachement": null,
|
||||
"ctmAdrGeoVille": "CARQUEIRANNE",
|
||||
"ctmAdrGeoCodePostal": "83320",
|
||||
"ctmAdrGeo1": null,
|
||||
"ctmAdrGeo2": null,
|
||||
"ctmAdrGeo3": null,
|
||||
"ctmAdrGeo4": null,
|
||||
"ctmAdrGeo5": null,
|
||||
"ctmAdrPostaleCodePostal": "83320",
|
||||
"ctmAdrPostaleVille": "CARQUEIRANNE",
|
||||
"ctmAdrPostale1": null,
|
||||
"ctmAdrPostale2": null,
|
||||
"ctmAdrPostale3": null,
|
||||
"ctmAdrPostale4": "1 AVENUE JEAN JAURES",
|
||||
"ctmAdrPostale5": "BP 14",
|
||||
"ctmDenominationSociale": "SCP Louis ABBATE, Gabriel GABOLDE et Laura SERVEL-SCHROEDER",
|
||||
"ctmDenominationSocialeAbregee": "ABBATE et associés",
|
||||
"ctmIntitule": "ABBATE Louis, GABOLDE Gabriel et SERVEL-SCHROEDER Laura",
|
||||
"ctmFormeJuridique": "SCP",
|
||||
"ctmLibelle": null,
|
||||
"rattachement": {
|
||||
"id": "IDN00082246I_IDN187087",
|
||||
"email": "marie.curie.519@notaires.fr",
|
||||
"blocked": false,
|
||||
"phoneNumber": null,
|
||||
"homePhoneNumber": null,
|
||||
"entityType": "office",
|
||||
"linkType": "Administrateur",
|
||||
"subLinkType": null,
|
||||
"activitiesDomain": [],
|
||||
"mandats": [],
|
||||
"manager": true,
|
||||
"naturalManager": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"idn": "IDN00082246I",
|
||||
"civilite": "Madame",
|
||||
"photo": "",
|
||||
"email": "personaIDN00082246I@portail.com",
|
||||
"pseudo": "marie.curie.519",
|
||||
"backupEmail": "nicolas.cantu@pm.me",
|
||||
"emailValidated": "true"
|
||||
}
|
||||
```
|
||||
|
||||
### Identifants
|
||||
|
||||
- Identifiant : ID.NOT IDN187087
|
||||
- Type : STON
|
||||
- CRPCEN : 083079
|
||||
- Forme juridique : SCP
|
||||
- Statut : Pourvu
|
||||
- Département de résidence : 083 - VAR
|
||||
- Résidence : CARQUEIRANNE (83034)
|
||||
|
||||
### Contact
|
||||
|
||||
- Téléphone : 0494005290
|
||||
- Email : abbate.gabolde@notaires.fr
|
||||
- Site internet : www.carqueiranne-abbate-gabolde-servel.notaires.fr
|
||||
|
||||
### Adresse géographique
|
||||
|
||||
- Numéro et libellé de la voie : 1 AVENUE JEAN JAURES
|
||||
- Code postal : 83320
|
||||
- Ville : CARQUEIRANNE
|
||||
|
||||
### Adresse postale
|
||||
|
||||
- Numéro et libellé de la voie : 1 AVENUE JEAN JAURES
|
||||
- Complément d'adresse : BP 14
|
||||
- Code postal : 83320
|
||||
- Ville : CARQUEIRANNE
|
@ -97,49 +97,21 @@ export class IdNotController {
|
||||
Logger.info('IdNot authentication initiated', { codePrefix: code.substring(0, 8) + '...' });
|
||||
|
||||
try {
|
||||
// Development fallback: allow authentication without contacting IdNot
|
||||
if (process.env.IDNOT_MOCK === '1') {
|
||||
Logger.warn('IDNOT_MOCK enabled - returning mocked IdNot user without external calls');
|
||||
const idNotUser: IdNotUser = {
|
||||
idNot: 'IDN187087',
|
||||
office: {
|
||||
idNot: 'IDN187087',
|
||||
name: 'STON - CARQUEIRANNE',
|
||||
crpcen: '083079',
|
||||
office_status: 'ACTIVATED' as any,
|
||||
address: { address: 'CARQUEIRANNE', city: 'CARQUEIRANNE', zip_code: 83034 },
|
||||
status: 'ACTIVE'
|
||||
},
|
||||
role: { name: 'admin' },
|
||||
contact: {
|
||||
first_name: 'Test',
|
||||
last_name: 'User',
|
||||
email: 'test@lecoffre.io',
|
||||
phone_number: '+33400000000',
|
||||
cell_phone_number: '+33600000000',
|
||||
civility: 'Monsieur' as any
|
||||
},
|
||||
office_role: { name: 'Notaire' }
|
||||
};
|
||||
|
||||
const authToken = uuidv4();
|
||||
const tokenData: AuthToken = {
|
||||
idNot: idNotUser.idNot,
|
||||
authToken,
|
||||
idNotUser,
|
||||
pairingId: null,
|
||||
defaultStorage: null,
|
||||
createdAt: Date.now(),
|
||||
expiresAt: Date.now() + (24 * 60 * 60 * 1000)
|
||||
};
|
||||
authTokens.push(tokenData);
|
||||
|
||||
return { idNotUser, authToken };
|
||||
}
|
||||
// Mock désactivé: suppression du bypass IDNOT_MOCK
|
||||
|
||||
// Exchange code for tokens
|
||||
const tokens = await IdNotService.exchangeCodeForTokens(code);
|
||||
|
||||
// Optional diagnostic: fetch userinfo to validate access_token
|
||||
try {
|
||||
if (tokens.access_token) {
|
||||
const userinfo = await IdNotService.getUserInfo(tokens.access_token);
|
||||
Logger.info('Userinfo fetched', { userinfoKeys: Object.keys(userinfo || {}) });
|
||||
}
|
||||
} catch (e) {
|
||||
Logger.warn('Userinfo fetch failed (non-blocking)', { error: e instanceof Error ? e.message : String(e) });
|
||||
}
|
||||
|
||||
Logger.info('Token exchange successful', {
|
||||
hasAccessToken: !!tokens.access_token,
|
||||
hasIdToken: !!tokens.id_token,
|
||||
|
@ -40,20 +40,18 @@ export class IdNotCallbackHandlers {
|
||||
|
||||
const payload = StateService.verifyState(state);
|
||||
|
||||
// If external IdNot access is unavailable, allow mock bypass when enabled
|
||||
const mockEnabled = process.env.IDNOT_MOCK === '1';
|
||||
if (mockEnabled) {
|
||||
const { authToken } = await IdNotController.authenticate(code);
|
||||
const url = new URL(payload.next_url);
|
||||
const hash = url.hash ? url.hash.replace(/^#/, '') + `&authToken=${encodeURIComponent(authToken)}` : `authToken=${encodeURIComponent(authToken)}`;
|
||||
const redirectTo = `${url.origin}${url.pathname}${url.search}#${hash}`;
|
||||
return res.redirect(302, redirectTo);
|
||||
}
|
||||
// Mock désactivé: suppression du bypass IDNOT_MOCK
|
||||
|
||||
// Exchange code using existing controller logic to build auth and user
|
||||
const { authToken } = await IdNotController.authenticate(code);
|
||||
|
||||
const url = new URL(payload.next_url);
|
||||
// Normalisation du chemin pour dev4: forcer le préfixe /lecoffre si absent
|
||||
try {
|
||||
if (url.hostname === 'dev4.4nkweb.com' && url.pathname === '/authorized-client') {
|
||||
url.pathname = '/lecoffre/authorized-client';
|
||||
}
|
||||
} catch {}
|
||||
// Prefer fragment to avoid leaking in server logs
|
||||
const hash = url.hash ? url.hash.replace(/^#/, '') + `&authToken=${encodeURIComponent(authToken)}` : `authToken=${encodeURIComponent(authToken)}`;
|
||||
const redirectTo = `${url.origin}${url.pathname}${url.search}#${hash}`;
|
||||
@ -61,5 +59,3 @@ export class IdNotCallbackHandlers {
|
||||
res.redirect(302, redirectTo);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -78,12 +78,57 @@ export class IdNotService {
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
try {
|
||||
const contentType = response.headers.get('content-type') || '';
|
||||
const bodyText = await (response as any).text().catch(() => undefined);
|
||||
const snippet = bodyText ? bodyText.slice(0, 200) : undefined;
|
||||
Logger.error('IdNot token exchange non-OK response', {
|
||||
url: IDNOT_TOKEN_URL,
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
contentType,
|
||||
bodySnippet: snippet
|
||||
});
|
||||
} catch {}
|
||||
throw new Error(`Token exchange failed: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
static async getUserInfo(accessToken: string) {
|
||||
const { IDNOT_USERINFO_URL } = process.env;
|
||||
if (!IDNOT_USERINFO_URL) {
|
||||
throw new Error('Missing IDNOT_USERINFO_URL');
|
||||
}
|
||||
|
||||
const response = await fetch(IDNOT_USERINFO_URL, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Authorization': `Bearer ${accessToken}`
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
try {
|
||||
const contentType = response.headers.get('content-type') || '';
|
||||
const bodyText = await (response as any).text().catch(() => undefined);
|
||||
const snippet = bodyText ? bodyText.slice(0, 200) : undefined;
|
||||
Logger.error('IdNot userinfo non-OK response', {
|
||||
url: IDNOT_USERINFO_URL,
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
contentType,
|
||||
bodySnippet: snippet
|
||||
});
|
||||
} catch {}
|
||||
throw new ExternalServiceError('IdNot', `Failed to fetch userinfo: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
|
||||
return await IdNotService.parseJsonOrThrow(response as any, 'getUserInfo');
|
||||
}
|
||||
|
||||
static async getUserRattachements(idNot: string) {
|
||||
const { IDNOT_API_KEY, IDNOT_ANNUARY_BASE_URL } = process.env;
|
||||
|
||||
@ -139,10 +184,10 @@ export class IdNotService {
|
||||
}
|
||||
|
||||
static async getUserData(profileIdn: string) {
|
||||
const { IDNOT_API_KEY, IDNOT_API_BASE_URL } = process.env;
|
||||
const { IDNOT_API_KEY, IDNOT_ANNUARY_BASE_URL } = process.env;
|
||||
|
||||
if (!IDNOT_API_KEY || !IDNOT_API_BASE_URL) {
|
||||
throw new Error('Missing IDnot API key or base URL');
|
||||
if (!IDNOT_API_KEY || !IDNOT_ANNUARY_BASE_URL) {
|
||||
throw new Error('Missing IDnot API key or annuary base URL');
|
||||
}
|
||||
|
||||
const searchParams = new URLSearchParams({
|
||||
@ -155,8 +200,24 @@ export class IdNotService {
|
||||
if (process.env.IDNOT_CONTEXT_HEADER && process.env.IDNOT_CONTEXT_VALUE) {
|
||||
headers[process.env.IDNOT_CONTEXT_HEADER] = process.env.IDNOT_CONTEXT_VALUE;
|
||||
}
|
||||
const response = await fetch(`${IDNOT_API_BASE_URL}/api/pp/v2/rattachements/${profileIdn}?` + searchParams, { method: 'GET', headers });
|
||||
const fullUrl = `${IDNOT_ANNUARY_BASE_URL}/api/pp/v2/rattachements/${profileIdn}?` + searchParams;
|
||||
const response = await fetch(fullUrl, { method: 'GET', headers });
|
||||
if (!response.ok) {
|
||||
try {
|
||||
const contentType = response.headers.get('content-type') || '';
|
||||
const bodyText = await (response as any).text().catch(() => undefined);
|
||||
const snippet = bodyText ? bodyText.slice(0, 200) : undefined;
|
||||
const safeUrl = fullUrl.replace(/(key=)[^&]+/i, '$1***');
|
||||
Logger.error('IdNot getUserData non-OK response', {
|
||||
context: 'getUserData',
|
||||
profileIdn,
|
||||
url: safeUrl,
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
contentType,
|
||||
bodySnippet: snippet
|
||||
});
|
||||
} catch {}
|
||||
throw new ExternalServiceError('IdNot', `Failed to fetch user data: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
return await IdNotService.parseJsonOrThrow(response as any, 'getUserData');
|
||||
|
Loading…
x
Reference in New Issue
Block a user