mirror of https://github.com/abpframework/abp.git
7 changed files with 190 additions and 54 deletions
@ -1,11 +1,29 @@ |
|||||
import { mergeApplicationConfig, ApplicationConfig } from '@angular/core'; |
import { |
||||
|
mergeApplicationConfig, |
||||
|
ApplicationConfig, |
||||
|
provideAppInitializer, |
||||
|
inject, |
||||
|
PLATFORM_ID, |
||||
|
TransferState |
||||
|
} from '@angular/core'; |
||||
|
import { isPlatformServer } from '@angular/common'; |
||||
|
import { provideServerRendering, withRoutes } from '@angular/ssr'; |
||||
|
|
||||
import { appConfig } from './app.config'; |
import { appConfig } from './app.config'; |
||||
import { provideAbpOAuth } from '@abp/ng.oauth'; |
|
||||
import { withRoutes, provideServerRendering } from '@angular/ssr'; |
|
||||
import { appServerRoutes } from './app.routes.server'; |
import { appServerRoutes } from './app.routes.server'; |
||||
|
import { SSR_FLAG } from '@abp/ng.core'; |
||||
|
|
||||
const serverConfig: ApplicationConfig = { |
const serverConfig: ApplicationConfig = { |
||||
providers: [provideAbpOAuth(), provideServerRendering(withRoutes(appServerRoutes))], |
providers: [ |
||||
|
provideAppInitializer(() => { |
||||
|
const platformId = inject(PLATFORM_ID); |
||||
|
const transferState = inject<TransferState>(TransferState); |
||||
|
if (isPlatformServer(platformId)) { |
||||
|
transferState.set(SSR_FLAG, true); |
||||
|
} |
||||
|
}), |
||||
|
provideServerRendering(withRoutes(appServerRoutes)), |
||||
|
], |
||||
}; |
}; |
||||
|
|
||||
export const config = mergeApplicationConfig(appConfig, serverConfig); |
export const config = mergeApplicationConfig(appConfig, serverConfig); |
||||
|
|||||
@ -0,0 +1,85 @@ |
|||||
|
import { Injectable, PLATFORM_ID, inject } 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); |
||||
|
|
||||
|
get length(): number { |
||||
|
return this.isBrowser ? this.keys().length : 0; |
||||
|
} |
||||
|
|
||||
|
clear(): void { |
||||
|
if (!this.isBrowser) return; |
||||
|
this.keys().forEach(k => this.removeItem(k)); |
||||
|
} |
||||
|
|
||||
|
getItem(key: string): string | null { |
||||
|
if (!this.isBrowser) return null; |
||||
|
const name = key + '='; |
||||
|
const parts = (this.document.cookie || '').split('; '); |
||||
|
for (const p of parts) { |
||||
|
if (p.startsWith(name)) { |
||||
|
return decodeURIComponent(p.slice(name.length)); |
||||
|
} |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
key(index: number): string | null { |
||||
|
if (!this.isBrowser) return null; |
||||
|
return this.keys()[index] ?? null; |
||||
|
} |
||||
|
|
||||
|
removeItem(key: string): void { |
||||
|
if (!this.isBrowser) 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', |
||||
|
secure: true, |
||||
|
// İstersen kalıcı yapmak için maxAge / expires ekleyebilirsin
|
||||
|
// 'max-age': 60 * 60, // 1 saat
|
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
setItemWithExpiry(key: string, value: string, seconds: number): void { |
||||
|
if (!this.isBrowser) return; |
||||
|
this.setCookie(key, encodeURIComponent(value), { |
||||
|
path: '/', |
||||
|
sameSite: 'Lax', |
||||
|
secure: true, |
||||
|
'max-age': Math.max(0, Math.floor(seconds)), |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private keys(): string[] { |
||||
|
const raw = (this.document.cookie || '').split('; ').filter(Boolean); |
||||
|
return raw |
||||
|
.map(c => decodeURIComponent(c.split('=')[0])); |
||||
|
} |
||||
|
|
||||
|
private setCookie(name: string, value: string, opts: { |
||||
|
path?: string; |
||||
|
domain?: string; |
||||
|
secure?: boolean; |
||||
|
sameSite?: 'Lax' | 'Strict' | 'None'; |
||||
|
expires?: Date; |
||||
|
'max-age'?: number; |
||||
|
}) { |
||||
|
let s = `${name}=${value}`; |
||||
|
if (opts.path) s += `; Path=${opts.path}`; |
||||
|
if (opts.domain) s += `; Domain=${opts.domain}`; |
||||
|
if (opts.sameSite) s += `; SameSite=${opts.sameSite}`; |
||||
|
if (opts.secure) s += `; Secure`; |
||||
|
if (opts.expires) s += `; Expires=${opts.expires.toUTCString()}`; |
||||
|
if (typeof opts['max-age'] === 'number') s += `; Max-Age=${opts['max-age']}`; |
||||
|
this.document.cookie = s; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
import { inject, InjectionToken, makeStateKey, PLATFORM_ID, TransferState } from '@angular/core'; |
||||
|
import { isPlatformBrowser } from '@angular/common'; |
||||
|
|
||||
|
export const SSR_FLAG = makeStateKey<boolean>('SSR_FLAG'); |
||||
|
|
||||
|
export const APP_STARTED_WITH_SSR = new InjectionToken<boolean>('APP_STARTED_WITH_SSR', { |
||||
|
providedIn: 'root', |
||||
|
factory: () => { |
||||
|
const platformId = inject(PLATFORM_ID); |
||||
|
if (!isPlatformBrowser(platformId)) return true; |
||||
|
const ts = inject(TransferState); |
||||
|
return ts.get(SSR_FLAG, false); |
||||
|
}, |
||||
|
}); |
||||
@ -1,32 +1,49 @@ |
|||||
import { AbpLocalStorageService } from '@abp/ng.core'; |
import { |
||||
import { Injectable, inject } from '@angular/core'; |
AbpCookieStorageService, |
||||
|
AbpLocalStorageService, |
||||
@Injectable({ |
APP_STARTED_WITH_SSR, |
||||
providedIn: 'root', |
} from '@abp/ng.core'; |
||||
}) |
import { Injectable, inject } from '@angular/core'; |
||||
export class RememberMeService { |
|
||||
readonly #rememberMe = 'remember_me'; |
@Injectable({ |
||||
protected readonly localStorageService = inject(AbpLocalStorageService); |
providedIn: 'root', |
||||
|
}) |
||||
set(remember: boolean) { |
export class RememberMeService { |
||||
this.localStorageService.setItem(this.#rememberMe, JSON.stringify(remember)); |
readonly #rememberMe = 'remember_me'; |
||||
} |
protected readonly localStorageService = inject(AbpLocalStorageService); |
||||
|
protected readonly cookieStorageService = inject(AbpCookieStorageService); |
||||
remove() { |
private appStartedWithSsr = inject(APP_STARTED_WITH_SSR, { optional: true }); |
||||
this.localStorageService.removeItem(this.#rememberMe); |
|
||||
} |
set(remember: boolean) { |
||||
|
if (this.appStartedWithSsr) { |
||||
get() { |
this.cookieStorageService.setItem(this.#rememberMe, JSON.stringify(remember)); |
||||
return Boolean(JSON.parse(this.localStorageService.getItem(this.#rememberMe) || 'false')); |
return; |
||||
} |
} |
||||
|
this.localStorageService.setItem(this.#rememberMe, JSON.stringify(remember)); |
||||
getFromToken(accessToken: string) { |
} |
||||
const tokenBody = accessToken.split('.')[1].replace(/-/g, '+').replace(/_/g, '/'); |
|
||||
try { |
remove() { |
||||
const parsedToken = JSON.parse(atob(tokenBody)); |
if (this.appStartedWithSsr) { |
||||
return Boolean(parsedToken[this.#rememberMe]); |
this.cookieStorageService.removeItem(this.#rememberMe); |
||||
} catch { |
return; |
||||
return false; |
} |
||||
} |
this.localStorageService.removeItem(this.#rememberMe); |
||||
} |
} |
||||
} |
|
||||
|
get() { |
||||
|
if (this.appStartedWithSsr) { |
||||
|
return Boolean(JSON.parse(this.cookieStorageService.getItem(this.#rememberMe) || 'false')); |
||||
|
} |
||||
|
return Boolean(JSON.parse(this.localStorageService.getItem(this.#rememberMe) || 'false')); |
||||
|
} |
||||
|
|
||||
|
getFromToken(accessToken: string) { |
||||
|
const tokenBody = accessToken.split('.')[1].replace(/-/g, '+').replace(/_/g, '/'); |
||||
|
try { |
||||
|
const parsedToken = JSON.parse(atob(tokenBody)); |
||||
|
return Boolean(parsedToken[this.#rememberMe]); |
||||
|
} catch { |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|||||
Loading…
Reference in new issue