From 6c0467ffcec2753b35c2c721e9fa744835be18c6 Mon Sep 17 00:00:00 2001 From: erdemcaygor Date: Tue, 9 Sep 2025 23:50:41 +0300 Subject: [PATCH] cookie-storage and session-state service refactoring --- .../lib/services/cookie-storage.service.ts | 33 ++++++++++++++----- .../src/lib/services/session-state.service.ts | 15 +++++++-- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/cookie-storage.service.ts b/npm/ng-packs/packages/core/src/lib/services/cookie-storage.service.ts index c6d57724d3..2267fd973c 100644 --- a/npm/ng-packs/packages/core/src/lib/services/cookie-storage.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/cookie-storage.service.ts @@ -1,23 +1,25 @@ -import { Injectable, PLATFORM_ID, inject } from '@angular/core'; +import { Injectable, PLATFORM_ID, inject, REQUEST } from '@angular/core'; import { DOCUMENT, isPlatformBrowser } from '@angular/common'; @Injectable({ providedIn: 'root' }) export class AbpCookieStorageService implements Storage { private platformId = inject(PLATFORM_ID); private document = inject(DOCUMENT); - private isBrowser = isPlatformBrowser(this.platformId); + private request = inject(REQUEST); get length(): number { - return this.isBrowser ? this.keys().length : 0; + return isPlatformBrowser(this.platformId) ? this.keys().length : this.getCookiesFromRequest()?.size ?? 0; } clear(): void { - if (!this.isBrowser) return; + if (!isPlatformBrowser(this.platformId)) return; this.keys().forEach(k => this.removeItem(k)); } getItem(key: string): string | null { - if (!this.isBrowser) return null; + if (!isPlatformBrowser(this.platformId)) { + return this.getCookiesFromRequest()?.get(key) ?? null; + } const name = key + '='; const parts = (this.document.cookie || '').split('; '); for (const p of parts) { @@ -29,17 +31,16 @@ export class AbpCookieStorageService implements Storage { } key(index: number): string | null { - if (!this.isBrowser) return null; + if (!isPlatformBrowser(this.platformId)) return null; return this.keys()[index] ?? null; } removeItem(key: string): void { - if (!this.isBrowser) return; + if (!isPlatformBrowser(this.platformId)) return; this.setCookie(key, '', { 'max-age': -1, path: '/' }); } setItem(key: string, value: string): void { - if (!this.isBrowser) return; this.setCookie(key, encodeURIComponent(value), { path: '/', sameSite: 'Lax', @@ -48,7 +49,7 @@ export class AbpCookieStorageService implements Storage { } setItemWithExpiry(key: string, value: string, seconds: number): void { - if (!this.isBrowser) return; + if (!isPlatformBrowser(this.platformId)) return; this.setCookie(key, encodeURIComponent(value), { path: '/', sameSite: 'Lax', @@ -80,4 +81,18 @@ export class AbpCookieStorageService implements Storage { if (typeof opts['max-age'] === 'number') s += `; Max-Age=${opts['max-age']}`; this.document.cookie = s; } + + private getCookiesFromRequest(): Map { + const cookies = new Map(); + const cookieHeader = this.request?.headers.get('cookie') ?? ''; + for (const part of cookieHeader.split(';')) { + const i = part.indexOf('='); + if (i > -1) { + const k = part.slice(0, i).trim(); + const v = decodeURIComponent(part.slice(i + 1).trim()); + cookies.set(k, v); + } + } + return cookies; + } } diff --git a/npm/ng-packs/packages/core/src/lib/services/session-state.service.ts b/npm/ng-packs/packages/core/src/lib/services/session-state.service.ts index 7e519dc742..75352d4f18 100644 --- a/npm/ng-packs/packages/core/src/lib/services/session-state.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/session-state.service.ts @@ -7,6 +7,8 @@ import { CurrentTenantDto } from '../proxy/volo/abp/asp-net-core/mvc/multi-tenan import { InternalStore } from '../utils/internal-store-utils'; import { ConfigStateService } from './config-state.service'; import { AbpLocalStorageService } from './local-storage.service'; +import { APP_STARTED_WITH_SSR } from '../tokens'; +import { AbpCookieStorageService } from './cookie-storage.service'; @Injectable({ providedIn: 'root', @@ -14,12 +16,18 @@ import { AbpLocalStorageService } from './local-storage.service'; export class SessionStateService { private configState = inject(ConfigStateService); private localStorageService = inject(AbpLocalStorageService); + private appStartedWithSSR = inject(APP_STARTED_WITH_SSR, { optional: true }); + private cookieStorageService = inject(AbpCookieStorageService); private readonly store = new InternalStore({} as Session.State); protected readonly document = inject(DOCUMENT); private updateLocalStorage = () => { - this.localStorageService.setItem('abpSession', JSON.stringify(this.store.state)); + if (this.appStartedWithSSR) { + this.cookieStorageService.setItem('abpSession', JSON.stringify(this.store.state)); + } else { + this.localStorageService.setItem('abpSession', JSON.stringify(this.store.state)); + } }; constructor() { @@ -28,7 +36,8 @@ export class SessionStateService { } private init() { - const session = this.localStorageService.getItem('abpSession'); + let session: string; + session = this.appStartedWithSSR ? this.cookieStorageService.getItem('abpSession') : this.localStorageService.getItem('abpSession'); if (session) { this.store.set(JSON.parse(session)); } @@ -49,7 +58,7 @@ export class SessionStateService { if (lang.includes(';')) { lang = lang.split(';')[0]; } - + this.setLanguage(lang); }); }