fix(oauth2): replace localStorage with sessionStorage in callback component (#2790)
This commit is contained in:
@@ -33,7 +33,7 @@ export class AuthService {
|
|||||||
async login() {
|
async login() {
|
||||||
const codeVerifier = this.generateRandomString();
|
const codeVerifier = this.generateRandomString();
|
||||||
const codeChallenge = await this.generateCodeChallenge(codeVerifier);
|
const codeChallenge = await this.generateCodeChallenge(codeVerifier);
|
||||||
localStorage.setItem('code_verifier', codeVerifier);
|
sessionStorage.setItem('code_verifier', codeVerifier);
|
||||||
const url =
|
const url =
|
||||||
`${this.authUrl}` +
|
`${this.authUrl}` +
|
||||||
`?client_id=${encodeURIComponent(this.clientId)}` +
|
`?client_id=${encodeURIComponent(this.clientId)}` +
|
||||||
@@ -105,56 +105,51 @@ export class AuthService {
|
|||||||
return base64;
|
return base64;
|
||||||
}
|
}
|
||||||
|
|
||||||
exchangeCodeForTokens(code: string, codeVerifier: string | null) {
|
async exchangeCodeForTokens(code: string, codeVerifier: string | null): Promise<void> {
|
||||||
const payload = {
|
const payload = {
|
||||||
code: code,
|
code: code,
|
||||||
code_verifier: codeVerifier || ''
|
code_verifier: codeVerifier || ''
|
||||||
};
|
};
|
||||||
|
|
||||||
fetch(this.api + 'authentication/token', {
|
try {
|
||||||
method: 'POST',
|
const response = await fetch(this.api + 'authentication/token', {
|
||||||
headers: {
|
method: 'POST',
|
||||||
'Content-Type': 'application/json'
|
headers: {
|
||||||
},
|
'Content-Type': 'application/json'
|
||||||
body: JSON.stringify(payload)
|
},
|
||||||
})
|
body: JSON.stringify(payload)
|
||||||
.then((res) => {
|
|
||||||
if (!res.ok) {
|
|
||||||
throw new Error(`Error exchanging code: ${res.status} ${res.statusText}`);
|
|
||||||
}
|
|
||||||
return res.json();
|
|
||||||
})
|
|
||||||
.then(
|
|
||||||
(tokens: {
|
|
||||||
access_token: string;
|
|
||||||
id_token: string;
|
|
||||||
refresh_token: string;
|
|
||||||
expires_in: number;
|
|
||||||
token_type: string;
|
|
||||||
}) => {
|
|
||||||
const token: OAuth2Token = {
|
|
||||||
access_token: tokens.access_token,
|
|
||||||
token_type: tokens.token_type,
|
|
||||||
refresh_token: tokens.refresh_token,
|
|
||||||
expires_in: tokens.expires_in,
|
|
||||||
scope: 'Bearer'
|
|
||||||
};
|
|
||||||
|
|
||||||
localStorage.setItem('id_token', tokens.id_token);
|
|
||||||
localStorage.setItem('mifosXZitadel', 'true');
|
|
||||||
sessionStorage.setItem('mifosXZitadelTokenDetails', JSON.stringify(token));
|
|
||||||
localStorage.setItem('refresh_token', tokens.refresh_token);
|
|
||||||
this.scheduleRefresh(tokens.expires_in);
|
|
||||||
localStorage.removeItem('auth_code');
|
|
||||||
localStorage.removeItem('code_verifier');
|
|
||||||
this.userdetails();
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.catch((error) => {
|
|
||||||
localStorage.removeItem('auth_code');
|
|
||||||
localStorage.removeItem('code_verifier');
|
|
||||||
window.location.href = '/#/login';
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Error exchanging code: ${response.status} ${response.statusText}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const tokens: {
|
||||||
|
access_token: string;
|
||||||
|
id_token: string;
|
||||||
|
refresh_token: string;
|
||||||
|
expires_in: number;
|
||||||
|
token_type: string;
|
||||||
|
} = await response.json();
|
||||||
|
|
||||||
|
const token: OAuth2Token = {
|
||||||
|
access_token: tokens.access_token,
|
||||||
|
token_type: tokens.token_type,
|
||||||
|
refresh_token: tokens.refresh_token,
|
||||||
|
expires_in: tokens.expires_in,
|
||||||
|
scope: 'Bearer'
|
||||||
|
};
|
||||||
|
|
||||||
|
sessionStorage.setItem('mifosXZitadelTokenDetails', JSON.stringify(token));
|
||||||
|
localStorage.setItem('id_token', tokens.id_token);
|
||||||
|
localStorage.setItem('refresh_token', tokens.refresh_token);
|
||||||
|
localStorage.setItem('mifosXZitadel', 'true');
|
||||||
|
this.scheduleRefresh(tokens.expires_in);
|
||||||
|
await this.userdetails();
|
||||||
|
} catch (error) {
|
||||||
|
window.location.href = '/#/login';
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
userdetails() {
|
userdetails() {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { AuthService } from '../auth.service';
|
import { AuthService } from '../auth.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -9,15 +9,27 @@ import { AuthService } from '../auth.service';
|
|||||||
export class CallbackComponent implements OnInit {
|
export class CallbackComponent implements OnInit {
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
|
private router: Router,
|
||||||
private authService: AuthService
|
private authService: AuthService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
async ngOnInit(): Promise<void> {
|
||||||
let code = localStorage.getItem('auth_code');
|
try {
|
||||||
|
const code = sessionStorage.getItem('auth_code');
|
||||||
if (code) {
|
if (code) {
|
||||||
const codeVerifier = localStorage.getItem('code_verifier');
|
const codeVerifier = sessionStorage.getItem('code_verifier');
|
||||||
this.authService.exchangeCodeForTokens(code, codeVerifier);
|
try {
|
||||||
|
await this.authService.exchangeCodeForTokens(code, codeVerifier);
|
||||||
|
} finally {
|
||||||
|
// Clean up sensitive data immediately after use
|
||||||
|
sessionStorage.removeItem('auth_code');
|
||||||
|
sessionStorage.removeItem('code_verifier');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Authentication failed:', error);
|
||||||
|
// Navigate to login page
|
||||||
|
this.router.navigate(['/login']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@
|
|||||||
}
|
}
|
||||||
const code = getQueryParam('code');
|
const code = getQueryParam('code');
|
||||||
if (code) {
|
if (code) {
|
||||||
localStorage.setItem('auth_code', code);
|
sessionStorage.setItem('auth_code', code);
|
||||||
window.location.href = '/#/callback';
|
window.location.href = '/#/callback';
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user