fix(auth): update logout response to include success message and adjust types
fix(tenant): add asset_url to Tenant interface and implement preconnect logic
This commit is contained in:
@@ -241,9 +241,10 @@ export class StoreLayoutComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.authService.logout().subscribe({
|
this.authService.logout().subscribe({
|
||||||
next: () => {
|
next: ({ message }) => {
|
||||||
this.cartService.clearCart();
|
this.cartService.clearCart();
|
||||||
this.isCartOpen.set(false);
|
this.isCartOpen.set(false);
|
||||||
|
this.toastService.success(message || 'Sesión cerrada correctamente.');
|
||||||
|
|
||||||
if (!isLeavingCheckout) {
|
if (!isLeavingCheckout) {
|
||||||
void this.router.navigate(['/']);
|
void this.router.navigate(['/']);
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ export interface LoginResponse {
|
|||||||
user: AuthUser;
|
user: AuthUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface LogoutResponse {
|
||||||
|
message: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface RegisterResponse {
|
export interface RegisterResponse {
|
||||||
message: string;
|
message: string;
|
||||||
data: AuthUser;
|
data: AuthUser;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
AuthUser,
|
AuthUser,
|
||||||
LoginPayload,
|
LoginPayload,
|
||||||
LoginResponse,
|
LoginResponse,
|
||||||
|
LogoutResponse,
|
||||||
RegisterPayload,
|
RegisterPayload,
|
||||||
RegisterResponse,
|
RegisterResponse,
|
||||||
ResetPasswordPayload,
|
ResetPasswordPayload,
|
||||||
@@ -155,14 +156,14 @@ export class AuthService extends BaseApiService {
|
|||||||
.pipe(tap((user) => this.userState.set(user)));
|
.pipe(tap((user) => this.userState.set(user)));
|
||||||
}
|
}
|
||||||
|
|
||||||
logout(): Observable<void> {
|
logout(): Observable<LogoutResponse> {
|
||||||
if (!this.tokenState()) {
|
if (!this.tokenState()) {
|
||||||
this.clearSession();
|
this.clearSession();
|
||||||
return of(void 0);
|
return of({ message: 'Sesión cerrada correctamente.' });
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.http
|
return this.http
|
||||||
.post<void>(`${environment.url}logout`, {})
|
.post<LogoutResponse>(`${environment.url}logout`, {})
|
||||||
.pipe(tap(() => this.clearSession()));
|
.pipe(tap(() => this.clearSession()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ export interface Tenant {
|
|||||||
dominio: string;
|
dominio: string;
|
||||||
base_path?: string;
|
base_path?: string;
|
||||||
site_title?: string | null;
|
site_title?: string | null;
|
||||||
|
asset_url?: string | null;
|
||||||
address?: string | null;
|
address?: string | null;
|
||||||
phone?: string | null;
|
phone?: string | null;
|
||||||
favicon?: string | null;
|
favicon?: string | null;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ const tenant: Tenant = {
|
|||||||
codigo: 'test',
|
codigo: 'test',
|
||||||
nombre: 'Test Tenant',
|
nombre: 'Test Tenant',
|
||||||
dominio: 'localhost',
|
dominio: 'localhost',
|
||||||
|
asset_url: 'https://s3.example.com/assets',
|
||||||
primary_color: '#6376F3',
|
primary_color: '#6376F3',
|
||||||
secondary_color: '#A0A0A0',
|
secondary_color: '#A0A0A0',
|
||||||
danger_color: '#FF8888',
|
danger_color: '#FF8888',
|
||||||
@@ -44,6 +45,7 @@ const tenantResponse: TenantBootstrapResponse = {
|
|||||||
|
|
||||||
describe('TenantService', () => {
|
describe('TenantService', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
document.head.querySelectorAll('link[rel="preconnect"]').forEach((link) => link.remove());
|
||||||
try {
|
try {
|
||||||
window.history.replaceState({}, '', 'http://localhost:4200/');
|
window.history.replaceState({}, '', 'http://localhost:4200/');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -72,6 +74,9 @@ describe('TenantService', () => {
|
|||||||
expect(service.status()).toBe('ready');
|
expect(service.status()).toBe('ready');
|
||||||
expect(service.tenant()).toEqual(tenant);
|
expect(service.tenant()).toEqual(tenant);
|
||||||
expect(service.getTenant()).toEqual(tenant);
|
expect(service.getTenant()).toEqual(tenant);
|
||||||
|
expect(
|
||||||
|
document.head.querySelector('link[rel="preconnect"][href="https://s3.example.com/"]'),
|
||||||
|
).not.toBeNull();
|
||||||
|
|
||||||
httpController.verify();
|
httpController.verify();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { isPlatformBrowser, isPlatformServer } from '@angular/common';
|
import { DOCUMENT, isPlatformBrowser, isPlatformServer } from '@angular/common';
|
||||||
import { HttpErrorResponse } from '@angular/common/http';
|
import { HttpErrorResponse } from '@angular/common/http';
|
||||||
import {
|
import {
|
||||||
inject,
|
inject,
|
||||||
@@ -26,6 +26,7 @@ import {
|
|||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class TenantService extends BaseApiService {
|
export class TenantService extends BaseApiService {
|
||||||
|
private readonly document = inject(DOCUMENT);
|
||||||
private readonly platformId = inject(PLATFORM_ID);
|
private readonly platformId = inject(PLATFORM_ID);
|
||||||
private readonly request = inject(REQUEST, { optional: true });
|
private readonly request = inject(REQUEST, { optional: true });
|
||||||
private readonly responseInit = inject(RESPONSE_INIT, { optional: true });
|
private readonly responseInit = inject(RESPONSE_INIT, { optional: true });
|
||||||
@@ -182,10 +183,40 @@ export class TenantService extends BaseApiService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private setReady(tenant: Tenant): void {
|
private setReady(tenant: Tenant): void {
|
||||||
|
this.ensureAssetPreconnect(tenant.asset_url);
|
||||||
this.tenantState.set(tenant);
|
this.tenantState.set(tenant);
|
||||||
this.statusState.set('ready');
|
this.statusState.set('ready');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ensureAssetPreconnect(assetUrl: string | null | undefined): void {
|
||||||
|
if (!assetUrl) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let origin: string;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const url = new URL(assetUrl);
|
||||||
|
if (url.protocol !== 'http:' && url.protocol !== 'https:') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
origin = url.origin;
|
||||||
|
} catch {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const existingPreconnects =
|
||||||
|
this.document.head.querySelectorAll<HTMLLinkElement>('link[rel="preconnect"]');
|
||||||
|
if ([...existingPreconnects].some((link) => link.href === `${origin}/`)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const link = this.document.createElement('link');
|
||||||
|
link.rel = 'preconnect';
|
||||||
|
link.href = origin;
|
||||||
|
this.document.head.append(link);
|
||||||
|
}
|
||||||
|
|
||||||
private setNotFound(): void {
|
private setNotFound(): void {
|
||||||
this.tenantState.set(null);
|
this.tenantState.set(null);
|
||||||
this.statusState.set('not-found');
|
this.statusState.set('not-found');
|
||||||
|
|||||||
Reference in New Issue
Block a user