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 { provideAbpOAuth } from '@abp/ng.oauth'; |
|||
import { withRoutes, provideServerRendering } from '@angular/ssr'; |
|||
import { appServerRoutes } from './app.routes.server'; |
|||
import { SSR_FLAG } from '@abp/ng.core'; |
|||
|
|||
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); |
|||
|
|||
@ -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 { Injectable, inject } from '@angular/core'; |
|||
|
|||
@Injectable({ |
|||
providedIn: 'root', |
|||
}) |
|||
export class RememberMeService { |
|||
readonly #rememberMe = 'remember_me'; |
|||
protected readonly localStorageService = inject(AbpLocalStorageService); |
|||
|
|||
set(remember: boolean) { |
|||
this.localStorageService.setItem(this.#rememberMe, JSON.stringify(remember)); |
|||
} |
|||
|
|||
remove() { |
|||
this.localStorageService.removeItem(this.#rememberMe); |
|||
} |
|||
|
|||
get() { |
|||
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; |
|||
} |
|||
} |
|||
} |
|||
import { |
|||
AbpCookieStorageService, |
|||
AbpLocalStorageService, |
|||
APP_STARTED_WITH_SSR, |
|||
} from '@abp/ng.core'; |
|||
import { Injectable, inject } from '@angular/core'; |
|||
|
|||
@Injectable({ |
|||
providedIn: 'root', |
|||
}) |
|||
export class RememberMeService { |
|||
readonly #rememberMe = 'remember_me'; |
|||
protected readonly localStorageService = inject(AbpLocalStorageService); |
|||
protected readonly cookieStorageService = inject(AbpCookieStorageService); |
|||
private appStartedWithSsr = inject(APP_STARTED_WITH_SSR, { optional: true }); |
|||
|
|||
set(remember: boolean) { |
|||
if (this.appStartedWithSsr) { |
|||
this.cookieStorageService.setItem(this.#rememberMe, JSON.stringify(remember)); |
|||
return; |
|||
} |
|||
this.localStorageService.setItem(this.#rememberMe, JSON.stringify(remember)); |
|||
} |
|||
|
|||
remove() { |
|||
if (this.appStartedWithSsr) { |
|||
this.cookieStorageService.removeItem(this.#rememberMe); |
|||
return; |
|||
} |
|||
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