Skip to content

Commit d050bb4

Browse files
committed
feat: enhance authentication auditing and IP handling
- Implemented client IP resolution in the authentication process, allowing for better tracking of user login attempts. - Added auditing capabilities for authentication events, including success and failure logs with associated IP addresses. - Updated the authentication service to validate client IP against allowed networks, enhancing security measures. - Enhanced the audit schema to include IP information, providing more context for audit logs. - Introduced new unit tests to ensure the reliability of the authentication auditing features and IP validation logic.
1 parent 22b95b6 commit d050bb4

5 files changed

Lines changed: 43 additions & 18 deletions

File tree

apps/api/src/core/audits/audits.controller.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export class AuditsController extends AbstractController {
3939
op: 1,
4040
ip: 1,
4141
agent: 1,
42+
'data.result': 1,
4243
'changes.path': 1,
4344
'changes.type': 1,
4445
metadata: 1,

apps/api/src/core/audits/audits.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export class AuditsService extends AbstractServiceSchema<Audits> {
4545
public async createAuthenticationAudit(params: {
4646
username: string
4747
ip: string | null
48-
result: 'success' | 'failure'
48+
result: 'success' | 'failed'
4949
reason: string
5050
agentId?: Types.ObjectId | string
5151
}): Promise<Audits> {

apps/api/src/core/auth/auth.service.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ export class AuthService extends AbstractService implements OnModuleInit {
8181
await this.auditAuthenticationAttempt({
8282
username,
8383
ip,
84-
result: 'failure',
84+
result: 'failed',
8585
reason: 'invalid_credentials',
8686
agentId: user?._id,
8787
});
@@ -92,7 +92,7 @@ export class AuthService extends AbstractService implements OnModuleInit {
9292
await this.auditAuthenticationAttempt({
9393
username,
9494
ip,
95-
result: 'failure',
95+
result: 'failed',
9696
reason: ip ? 'network_not_allowed' : 'ip_unavailable',
9797
agentId: user?._id,
9898
});
@@ -113,7 +113,7 @@ export class AuthService extends AbstractService implements OnModuleInit {
113113
await this.auditAuthenticationAttempt({
114114
username,
115115
ip,
116-
result: 'failure',
116+
result: 'failed',
117117
reason: 'internal_error',
118118
agentId: user?._id,
119119
});
@@ -146,7 +146,7 @@ export class AuthService extends AbstractService implements OnModuleInit {
146146
protected async auditAuthenticationAttempt(params: {
147147
username: string;
148148
ip: string | null;
149-
result: 'success' | 'failure';
149+
result: 'success' | 'failed';
150150
reason: string;
151151
agentId?: Types.ObjectId | string;
152152
}): Promise<void> {

apps/web/src/composables/useAuditsTable.ts

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,19 @@ export function createDefaultAuditDiffDialogState() {
3737
}
3838
}
3939

40-
export function getAuditOperationLabel(op?: string): string {
40+
export function resolveAuthenticationResult(result?: string): 'success' | 'failed' | null {
41+
if (result === 'success') return 'success'
42+
if (result === 'failed' || result === 'failure') return 'failed'
43+
return null
44+
}
45+
46+
export function getAuditOperationLabel(op?: string, authenticationResult?: string): string {
47+
if (op === 'authentication') {
48+
const resolvedResult = resolveAuthenticationResult(authenticationResult)
49+
if (resolvedResult === 'success') return 'Succès'
50+
if (resolvedResult === 'failed') return 'Fail'
51+
}
52+
4153
switch (op) {
4254
case 'insert':
4355
return 'Creation'
@@ -47,14 +59,19 @@ export function getAuditOperationLabel(op?: string): string {
4759
return 'Suppression'
4860
case 'replace':
4961
return 'Remplacement'
50-
case 'authentication':
51-
return 'Authentification'
5262
default:
5363
return op || 'Inconnue'
5464
}
5565
}
5666

57-
export function getAuditOperationColor(op?: string): string {
67+
export function getAuditOperationColor(op?: string, authenticationResult?: string): string {
68+
if (op === 'authentication') {
69+
const resolvedResult = resolveAuthenticationResult(authenticationResult)
70+
if (resolvedResult === 'success') return 'positive'
71+
if (resolvedResult === 'failed') return 'negative'
72+
return 'grey-6'
73+
}
74+
5875
switch (op) {
5976
case 'insert':
6077
return 'positive'
@@ -64,8 +81,6 @@ export function getAuditOperationColor(op?: string): string {
6481
return 'negative'
6582
case 'replace':
6683
return 'warning'
67-
case 'authentication':
68-
return 'deep-orange'
6984
default:
7085
return 'grey-7'
7186
}

apps/web/src/pages/audits/table.vue

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ q-page.container.q-pa-sm
6060
q-chip(
6161
dense
6262
size='sm'
63-
:color='getOperationColor(props.row?.op)'
63+
:color='getOperationColor(props.row)'
6464
text-color='white'
65-
:label='getOperationLabel(props.row?.op)'
65+
:label='getOperationLabel(props.row)'
6666
)
6767
template(#body-cell-coll='props')
6868
q-td(:props='props')
@@ -80,7 +80,7 @@ q-page.container.q-pa-sm
8080
q-tooltip.text-body2(anchor='top middle' self='bottom middle')
8181
span Voir la fiche identité
8282
q-chip.bg-positive.text-white.q-pa-sm(
83-
v-else-if='props.row?.coll === "Agents" && props.row?.documentId'
83+
v-else-if='["Agents", "auth"].includes(props.row?.coll) && props.row?.documentId'
8484
icon='mdi-account'
8585
clickable
8686
dense
@@ -106,6 +106,14 @@ q-page.container.q-pa-sm
106106
template(#body-cell-changes='props')
107107
q-td(:props='props')
108108
.row.items-center.q-gutter-xs
109+
q-chip(
110+
v-if='!props.row?.changes?.length'
111+
size='sm'
112+
dense
113+
color='grey-4'
114+
text-color='dark'
115+
label='N/A'
116+
)
109117
q-chip(
110118
v-for='(change, idx) in (props.row?.changes || []).slice(0, 4)'
111119
:key='`${props.row?._id}-${idx}-${change?.path || ""}`'
@@ -358,6 +366,7 @@ export default defineNuxtComponent({
358366
window.open(`/identities/table/${row.documentId}`, '_blank')
359367
break
360368
case 'Agents':
369+
case 'auth':
361370
window.open(`/settings/agents/${row.documentId}`, '_blank')
362371
break
363372
@@ -371,11 +380,11 @@ export default defineNuxtComponent({
371380
break
372381
}
373382
},
374-
getOperationLabel(op: string): string {
375-
return getAuditOperationLabel(op)
383+
getOperationLabel(row: any): string {
384+
return getAuditOperationLabel(row?.op, row?.data?.result)
376385
},
377-
getOperationColor(op: string): string {
378-
return getAuditOperationColor(op)
386+
getOperationColor(row: any): string {
387+
return getAuditOperationColor(row?.op, row?.data?.result)
379388
},
380389
formatChangeLabel(change: any): string {
381390
return formatAuditChangeLabel(change)

0 commit comments

Comments
 (0)