mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-14 09:55:12 +00:00
feat(console): v2 feature cleanup, fix styling issues, instance naming (#3530)
* new console * move npm ci to angular build * rel path for assets * local grpc copy * login policy, rm clear views, features rel path * login_hint param * edit default color values * remove features, zitadel-tier, contact styles * html formatter * rm feature restrictions, fix theming issues * instance naming * statehandler * rm class * rm class * update footer links * statehandler * stroked color Co-authored-by: Livio Amstutz <[email protected]>
This commit is contained in:
co-authored by
Livio Amstutz
parent
f9e79ef8fe
commit
41e60b3d8a
@@ -4,84 +4,84 @@ import { BehaviorSubject, from, merge, Observable, of, Subject } from 'rxjs';
|
||||
import { catchError, filter, finalize, map, mergeMap, switchMap, take, timeout } from 'rxjs/operators';
|
||||
|
||||
import {
|
||||
AddMyAuthFactorOTPRequest,
|
||||
AddMyAuthFactorOTPResponse,
|
||||
AddMyAuthFactorU2FRequest,
|
||||
AddMyAuthFactorU2FResponse,
|
||||
AddMyPasswordlessLinkRequest,
|
||||
AddMyPasswordlessLinkResponse,
|
||||
AddMyPasswordlessRequest,
|
||||
AddMyPasswordlessResponse,
|
||||
GetMyEmailRequest,
|
||||
GetMyEmailResponse,
|
||||
GetMyPasswordComplexityPolicyRequest,
|
||||
GetMyPasswordComplexityPolicyResponse,
|
||||
GetMyPhoneRequest,
|
||||
GetMyPhoneResponse,
|
||||
GetMyProfileRequest,
|
||||
GetMyProfileResponse,
|
||||
GetMyUserRequest,
|
||||
GetMyUserResponse,
|
||||
GetSupportedLanguagesRequest,
|
||||
GetSupportedLanguagesResponse,
|
||||
ListMyAuthFactorsRequest,
|
||||
ListMyAuthFactorsResponse,
|
||||
ListMyLinkedIDPsRequest,
|
||||
ListMyLinkedIDPsResponse,
|
||||
ListMyMembershipsRequest,
|
||||
ListMyMembershipsResponse,
|
||||
ListMyPasswordlessRequest,
|
||||
ListMyPasswordlessResponse,
|
||||
ListMyProjectOrgsRequest,
|
||||
ListMyProjectOrgsResponse,
|
||||
ListMyUserChangesRequest,
|
||||
ListMyUserChangesResponse,
|
||||
ListMyUserGrantsRequest,
|
||||
ListMyUserGrantsResponse,
|
||||
ListMyUserSessionsRequest,
|
||||
ListMyUserSessionsResponse,
|
||||
ListMyZitadelFeaturesRequest,
|
||||
ListMyZitadelFeaturesResponse,
|
||||
ListMyZitadelPermissionsRequest,
|
||||
ListMyZitadelPermissionsResponse,
|
||||
RemoveMyAuthFactorOTPRequest,
|
||||
RemoveMyAuthFactorOTPResponse,
|
||||
RemoveMyAuthFactorU2FRequest,
|
||||
RemoveMyAuthFactorU2FResponse,
|
||||
RemoveMyAvatarRequest,
|
||||
RemoveMyAvatarResponse,
|
||||
RemoveMyLinkedIDPRequest,
|
||||
RemoveMyLinkedIDPResponse,
|
||||
RemoveMyPasswordlessRequest,
|
||||
RemoveMyPasswordlessResponse,
|
||||
RemoveMyPhoneRequest,
|
||||
RemoveMyPhoneResponse,
|
||||
RemoveMyUserRequest,
|
||||
RemoveMyUserResponse,
|
||||
ResendMyEmailVerificationRequest,
|
||||
ResendMyEmailVerificationResponse,
|
||||
ResendMyPhoneVerificationRequest,
|
||||
ResendMyPhoneVerificationResponse,
|
||||
SendMyPasswordlessLinkRequest,
|
||||
SendMyPasswordlessLinkResponse,
|
||||
SetMyEmailRequest,
|
||||
SetMyEmailResponse,
|
||||
SetMyPhoneRequest,
|
||||
SetMyPhoneResponse,
|
||||
UpdateMyPasswordRequest,
|
||||
UpdateMyPasswordResponse,
|
||||
UpdateMyProfileRequest,
|
||||
UpdateMyProfileResponse,
|
||||
UpdateMyUserNameRequest,
|
||||
UpdateMyUserNameResponse,
|
||||
VerifyMyAuthFactorOTPRequest,
|
||||
VerifyMyAuthFactorOTPResponse,
|
||||
VerifyMyAuthFactorU2FRequest,
|
||||
VerifyMyAuthFactorU2FResponse,
|
||||
VerifyMyPasswordlessRequest,
|
||||
VerifyMyPasswordlessResponse,
|
||||
VerifyMyPhoneRequest,
|
||||
VerifyMyPhoneResponse,
|
||||
AddMyAuthFactorOTPRequest,
|
||||
AddMyAuthFactorOTPResponse,
|
||||
AddMyAuthFactorU2FRequest,
|
||||
AddMyAuthFactorU2FResponse,
|
||||
AddMyPasswordlessLinkRequest,
|
||||
AddMyPasswordlessLinkResponse,
|
||||
AddMyPasswordlessRequest,
|
||||
AddMyPasswordlessResponse,
|
||||
GetMyEmailRequest,
|
||||
GetMyEmailResponse,
|
||||
GetMyPasswordComplexityPolicyRequest,
|
||||
GetMyPasswordComplexityPolicyResponse,
|
||||
GetMyPhoneRequest,
|
||||
GetMyPhoneResponse,
|
||||
GetMyProfileRequest,
|
||||
GetMyProfileResponse,
|
||||
GetMyUserRequest,
|
||||
GetMyUserResponse,
|
||||
GetSupportedLanguagesRequest,
|
||||
GetSupportedLanguagesResponse,
|
||||
ListMyAuthFactorsRequest,
|
||||
ListMyAuthFactorsResponse,
|
||||
ListMyLinkedIDPsRequest,
|
||||
ListMyLinkedIDPsResponse,
|
||||
ListMyMembershipsRequest,
|
||||
ListMyMembershipsResponse,
|
||||
ListMyPasswordlessRequest,
|
||||
ListMyPasswordlessResponse,
|
||||
ListMyProjectOrgsRequest,
|
||||
ListMyProjectOrgsResponse,
|
||||
ListMyUserChangesRequest,
|
||||
ListMyUserChangesResponse,
|
||||
ListMyUserGrantsRequest,
|
||||
ListMyUserGrantsResponse,
|
||||
ListMyUserSessionsRequest,
|
||||
ListMyUserSessionsResponse,
|
||||
ListMyZitadelFeaturesRequest,
|
||||
ListMyZitadelFeaturesResponse,
|
||||
ListMyZitadelPermissionsRequest,
|
||||
ListMyZitadelPermissionsResponse,
|
||||
RemoveMyAuthFactorOTPRequest,
|
||||
RemoveMyAuthFactorOTPResponse,
|
||||
RemoveMyAuthFactorU2FRequest,
|
||||
RemoveMyAuthFactorU2FResponse,
|
||||
RemoveMyAvatarRequest,
|
||||
RemoveMyAvatarResponse,
|
||||
RemoveMyLinkedIDPRequest,
|
||||
RemoveMyLinkedIDPResponse,
|
||||
RemoveMyPasswordlessRequest,
|
||||
RemoveMyPasswordlessResponse,
|
||||
RemoveMyPhoneRequest,
|
||||
RemoveMyPhoneResponse,
|
||||
RemoveMyUserRequest,
|
||||
RemoveMyUserResponse,
|
||||
ResendMyEmailVerificationRequest,
|
||||
ResendMyEmailVerificationResponse,
|
||||
ResendMyPhoneVerificationRequest,
|
||||
ResendMyPhoneVerificationResponse,
|
||||
SendMyPasswordlessLinkRequest,
|
||||
SendMyPasswordlessLinkResponse,
|
||||
SetMyEmailRequest,
|
||||
SetMyEmailResponse,
|
||||
SetMyPhoneRequest,
|
||||
SetMyPhoneResponse,
|
||||
UpdateMyPasswordRequest,
|
||||
UpdateMyPasswordResponse,
|
||||
UpdateMyProfileRequest,
|
||||
UpdateMyProfileResponse,
|
||||
UpdateMyUserNameRequest,
|
||||
UpdateMyUserNameResponse,
|
||||
VerifyMyAuthFactorOTPRequest,
|
||||
VerifyMyAuthFactorOTPResponse,
|
||||
VerifyMyAuthFactorU2FRequest,
|
||||
VerifyMyAuthFactorU2FResponse,
|
||||
VerifyMyPasswordlessRequest,
|
||||
VerifyMyPasswordlessResponse,
|
||||
VerifyMyPhoneRequest,
|
||||
VerifyMyPhoneResponse,
|
||||
} from '../proto/generated/zitadel/auth_pb';
|
||||
import { ChangeQuery } from '../proto/generated/zitadel/change_pb';
|
||||
import { ListQuery } from '../proto/generated/zitadel/object_pb';
|
||||
@@ -98,10 +98,8 @@ export class GrpcAuthService {
|
||||
public user!: Observable<User.AsObject | undefined>;
|
||||
public userSubject: BehaviorSubject<User.AsObject | undefined> = new BehaviorSubject<User.AsObject | undefined>(undefined);
|
||||
private zitadelPermissions: BehaviorSubject<string[]> = new BehaviorSubject(['user.resourceowner']);
|
||||
private zitadelFeatures: BehaviorSubject<string[]> = new BehaviorSubject(['']);
|
||||
|
||||
public readonly fetchedZitadelPermissions: BehaviorSubject<boolean> = new BehaviorSubject(false as boolean);
|
||||
public readonly fetchedZitadelFeatures: BehaviorSubject<boolean> = new BehaviorSubject(false as boolean);
|
||||
|
||||
private cachedOrgs: Org.AsObject[] = [];
|
||||
|
||||
@@ -134,7 +132,6 @@ export class GrpcAuthService {
|
||||
}),
|
||||
finalize(() => {
|
||||
this.loadPermissions();
|
||||
this.loadFeatures();
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -142,7 +139,6 @@ export class GrpcAuthService {
|
||||
|
||||
this.activeOrgChanged.subscribe(() => {
|
||||
this.loadPermissions();
|
||||
this.loadFeatures();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -217,22 +213,6 @@ export class GrpcAuthService {
|
||||
});
|
||||
}
|
||||
|
||||
private loadFeatures(): void {
|
||||
from(this.listMyZitadelFeatures())
|
||||
.pipe(
|
||||
map((featuresResp) => featuresResp.resultList),
|
||||
catchError((_) => {
|
||||
return of([]);
|
||||
}),
|
||||
finalize(() => {
|
||||
this.fetchedZitadelFeatures.next(true);
|
||||
}),
|
||||
)
|
||||
.subscribe((features) => {
|
||||
this.zitadelFeatures.next(features);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if user has one of the provided roles
|
||||
* @param roles roles of the user
|
||||
@@ -262,35 +242,6 @@ export class GrpcAuthService {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if user has one of the provided features
|
||||
* @param features regex of the user
|
||||
*/
|
||||
public canUseFeature(features: string[] | RegExp[]): Observable<boolean> {
|
||||
if (features && features.length > 0) {
|
||||
return this.zitadelFeatures.pipe(switchMap((zFeatures) => of(this.hasFeature(zFeatures, features))));
|
||||
} else {
|
||||
return of(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if user has one of the provided features
|
||||
* @param userFeature features of the user
|
||||
* @param requestedFeature required features for accessing the respective component
|
||||
*/
|
||||
public hasFeature(userFeatures: string[], requestedFeatures: string[] | RegExp[]): boolean {
|
||||
return (
|
||||
requestedFeatures.findIndex((regexp: any) => {
|
||||
return (
|
||||
userFeatures.findIndex((feature) => {
|
||||
return new RegExp(regexp).test(feature);
|
||||
}) > -1
|
||||
);
|
||||
}) > -1
|
||||
);
|
||||
}
|
||||
|
||||
public getMyProfile(): Promise<GetMyProfileResponse.AsObject> {
|
||||
return this.grpcService.auth.getMyProfile(new GetMyProfileRequest(), null).then((resp) => resp.toObject());
|
||||
}
|
||||
|
||||
@@ -6,16 +6,16 @@ import { BehaviorSubject, Observable, of, pairwise, Subject, takeUntil } from 'r
|
||||
import { KeyboardShortcutsComponent } from '../../modules/keyboard-shortcuts/keyboard-shortcuts.component';
|
||||
import { GrpcAuthService } from '../grpc-auth.service';
|
||||
import {
|
||||
ACTIONS,
|
||||
DOMAINS,
|
||||
HOME,
|
||||
KeyboardShortcut,
|
||||
ME,
|
||||
ORG,
|
||||
PROJECTS,
|
||||
SYSTEM,
|
||||
USERGRANTS,
|
||||
USERS,
|
||||
ACTIONS,
|
||||
DOMAINS,
|
||||
HOME,
|
||||
KeyboardShortcut,
|
||||
ME,
|
||||
ORG,
|
||||
PROJECTS,
|
||||
SYSTEM,
|
||||
USERGRANTS,
|
||||
USERS,
|
||||
} from './keyboard-shortcuts';
|
||||
|
||||
@Injectable({
|
||||
@@ -54,47 +54,47 @@ export class KeyboardShortcutsService implements OnDestroy {
|
||||
}
|
||||
|
||||
if (firstKey.code === 'KeyG' && secondKey.code === 'KeyH') {
|
||||
if (this.hasPermission(HOME) && this.hasFeature(HOME)) {
|
||||
if (this.hasPermission(HOME)) {
|
||||
this.router.navigate(HOME.link);
|
||||
}
|
||||
}
|
||||
if (firstKey.code === 'KeyG' && secondKey.code === 'KeyS') {
|
||||
if (this.hasPermission(SYSTEM) && this.hasFeature(SYSTEM)) {
|
||||
if (this.hasPermission(SYSTEM)) {
|
||||
this.router.navigate(SYSTEM.link);
|
||||
}
|
||||
}
|
||||
if (firstKey.code === 'KeyG' && secondKey.code === 'KeyO') {
|
||||
if (this.hasPermission(ORG) && this.hasFeature(ORG)) {
|
||||
if (this.hasPermission(ORG)) {
|
||||
this.router.navigate(ORG.link);
|
||||
}
|
||||
}
|
||||
if (firstKey.code === 'KeyM' && secondKey.code === 'KeyE') {
|
||||
if (this.hasPermission(ME) && this.hasFeature(ME)) {
|
||||
if (this.hasPermission(ME)) {
|
||||
this.router.navigate(ME.link);
|
||||
}
|
||||
}
|
||||
if (firstKey.code === 'KeyG' && secondKey.code === 'KeyP') {
|
||||
if (this.hasPermission(PROJECTS) && this.hasFeature(PROJECTS)) {
|
||||
if (this.hasPermission(PROJECTS)) {
|
||||
this.router.navigate(PROJECTS.link);
|
||||
}
|
||||
}
|
||||
if (firstKey.code === 'KeyG' && secondKey.code === 'KeyU') {
|
||||
if (this.hasPermission(USERS) && this.hasFeature(USERS)) {
|
||||
if (this.hasPermission(USERS)) {
|
||||
this.router.navigate(USERS.link);
|
||||
}
|
||||
}
|
||||
if (firstKey.code === 'KeyG' && secondKey.code === 'KeyA') {
|
||||
if (this.hasPermission(USERGRANTS) && this.hasFeature(USERGRANTS)) {
|
||||
if (this.hasPermission(USERGRANTS)) {
|
||||
this.router.navigate(USERGRANTS.link);
|
||||
}
|
||||
}
|
||||
if (firstKey.code === 'KeyG' && secondKey.code === 'KeyF') {
|
||||
if (this.hasPermission(ACTIONS) && this.hasFeature(ACTIONS)) {
|
||||
if (this.hasPermission(ACTIONS)) {
|
||||
this.router.navigate(ACTIONS.link);
|
||||
}
|
||||
}
|
||||
if (firstKey.code === 'KeyG' && secondKey.code === 'KeyD') {
|
||||
if (this.hasPermission(DOMAINS) && this.hasFeature(DOMAINS)) {
|
||||
if (this.hasPermission(DOMAINS)) {
|
||||
this.router.navigate(DOMAINS.link);
|
||||
}
|
||||
}
|
||||
@@ -136,12 +136,4 @@ export class KeyboardShortcutsService implements OnDestroy {
|
||||
return of(true);
|
||||
}
|
||||
}
|
||||
|
||||
private hasFeature(shortcut: KeyboardShortcut): Observable<boolean> {
|
||||
if (shortcut.features) {
|
||||
return this.authService.canUseFeature(shortcut.features);
|
||||
} else {
|
||||
return of(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ export interface CnslOverlay {
|
||||
requirements?: {
|
||||
media?: string;
|
||||
permission?: string[];
|
||||
feature?: string[];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -83,10 +82,9 @@ export class OverlayWorkflowService implements OnDestroy {
|
||||
return zip([
|
||||
this.meetsMediaRequirements(overlay),
|
||||
this.meetsPermissionRequirements(overlay),
|
||||
this.meetsFeatureRequirements(overlay),
|
||||
] as Observable<boolean>[]).pipe(
|
||||
switchMap(([media, permission, feature]) => {
|
||||
return of(media && permission && feature);
|
||||
switchMap(([media, permission]) => {
|
||||
return of(media && permission);
|
||||
}),
|
||||
);
|
||||
}
|
||||
@@ -114,15 +112,6 @@ export class OverlayWorkflowService implements OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
public meetsFeatureRequirements(overlay: CnslOverlay): Observable<boolean> {
|
||||
const regexArray = overlay.requirements?.feature;
|
||||
if (regexArray && regexArray.length) {
|
||||
return this.authService.canUseFeature(regexArray);
|
||||
} else {
|
||||
return of(true);
|
||||
}
|
||||
}
|
||||
|
||||
public reset(): void {
|
||||
this.currentWorkflow$.next(null);
|
||||
if (this.callback) {
|
||||
|
||||
@@ -21,7 +21,7 @@ export const IntroWorkflowOverlays: CnslOverlay[] = [
|
||||
content: {
|
||||
number: 2,
|
||||
count: 4,
|
||||
i18nText: 'OVERLAYS.SYSTEM.TEXT',
|
||||
i18nText: 'OVERLAYS.INSTANCE.TEXT',
|
||||
},
|
||||
requirements: {
|
||||
media: '(min-width: 600px)',
|
||||
|
||||
@@ -4,34 +4,36 @@ import { Observable, of } from 'rxjs';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
export abstract class StatehandlerProcessorService {
|
||||
public abstract createState(url: string): Observable<string | undefined>;
|
||||
public abstract restoreState(state?: string): void;
|
||||
public abstract createState(url: string): Observable<string | undefined>;
|
||||
public abstract restoreState(state?: string): void;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class StatehandlerProcessorServiceImpl
|
||||
implements StatehandlerProcessorService {
|
||||
constructor(private location: Location) { }
|
||||
export class StatehandlerProcessorServiceImpl implements StatehandlerProcessorService {
|
||||
constructor(private location: Location) {}
|
||||
|
||||
public createState(url: string): Observable<string> {
|
||||
const externalUrl = this.location.prepareExternalUrl(url);
|
||||
const urlId = uuidv4();
|
||||
public createState(url: string): Observable<string> {
|
||||
const externalUrl = this.location.prepareExternalUrl(url);
|
||||
const urlId = uuidv4();
|
||||
|
||||
sessionStorage.setItem(urlId, externalUrl);
|
||||
|
||||
return of(urlId);
|
||||
if (externalUrl.includes('login_hint=')) {
|
||||
sessionStorage.setItem(urlId, externalUrl);
|
||||
}
|
||||
|
||||
public restoreState(state?: string): void {
|
||||
if (state === undefined) {
|
||||
return;
|
||||
}
|
||||
return of(urlId);
|
||||
}
|
||||
|
||||
const url = sessionStorage.getItem(state);
|
||||
if (url === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.location.href = window.location.origin + url;
|
||||
public restoreState(state?: string): void {
|
||||
if (state === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const url = sessionStorage.getItem(state);
|
||||
if (url === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
sessionStorage.removeItem(state);
|
||||
window.location.href = window.location.origin + url;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,59 +1,79 @@
|
||||
import { Injectable, Injector, OnDestroy, Type } from '@angular/core';
|
||||
import { GuardsCheckStart, Router, RouterEvent } from '@angular/router';
|
||||
import { OAuthService } from 'angular-oauth2-oidc';
|
||||
import { Observable, Subject, throwError } from 'rxjs';
|
||||
import { Observable, of, Subject, throwError } from 'rxjs';
|
||||
import { filter, map, shareReplay, switchMap, take, takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { StatehandlerProcessorService } from './statehandler-processor.service';
|
||||
|
||||
export abstract class StatehandlerService {
|
||||
public abstract createState(): Observable<string | undefined>;
|
||||
public abstract initStateHandler(): void;
|
||||
public abstract createState(): Observable<string | undefined>;
|
||||
public abstract initStateHandler(): void;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class StatehandlerServiceImpl
|
||||
implements StatehandlerService, OnDestroy {
|
||||
private events?: Observable<string>;
|
||||
private unsubscribe$: Subject<void> = new Subject();
|
||||
export class StatehandlerServiceImpl implements StatehandlerService, OnDestroy {
|
||||
private events?: Observable<string>;
|
||||
private unsubscribe$: Subject<void> = new Subject();
|
||||
|
||||
constructor(
|
||||
oauthService: OAuthService,
|
||||
private injector: Injector,
|
||||
private processor: StatehandlerProcessorService,
|
||||
) {
|
||||
oauthService.events
|
||||
.pipe(
|
||||
filter(event => event.type === 'token_received'),
|
||||
map(() => oauthService.state),
|
||||
takeUntil(this.unsubscribe$),
|
||||
)
|
||||
.subscribe(state => processor.restoreState(state));
|
||||
constructor(oauthService: OAuthService, private injector: Injector, private processor: StatehandlerProcessorService) {
|
||||
oauthService.events
|
||||
.pipe(
|
||||
filter((event) => event.type === 'token_received'),
|
||||
map(() => oauthService.state),
|
||||
takeUntil(this.unsubscribe$),
|
||||
)
|
||||
.subscribe((state) => processor.restoreState(state));
|
||||
}
|
||||
|
||||
public initStateHandler(): void {
|
||||
const router = this.injector.get(Router as Type<Router>);
|
||||
this.events = (router.events as Observable<RouterEvent>).pipe(
|
||||
filter((event) => event instanceof GuardsCheckStart),
|
||||
map((event) => event.url),
|
||||
shareReplay(1),
|
||||
);
|
||||
|
||||
this.events.pipe(takeUntil(this.unsubscribe$)).subscribe();
|
||||
}
|
||||
|
||||
public createState(): Observable<string | undefined> {
|
||||
if (this.events === undefined) {
|
||||
return throwError(() => new Error('no router events'));
|
||||
}
|
||||
|
||||
public initStateHandler(): void {
|
||||
const router = this.injector.get(Router as Type<Router>);
|
||||
this.events = (router.events as Observable<RouterEvent>).pipe(
|
||||
filter(event => event instanceof GuardsCheckStart),
|
||||
map(event => event.url),
|
||||
shareReplay(1),
|
||||
);
|
||||
|
||||
this.events.pipe(takeUntil(this.unsubscribe$)).subscribe();
|
||||
}
|
||||
|
||||
public createState(): Observable<string | undefined> {
|
||||
if (this.events === undefined) {
|
||||
return throwError('no router events');
|
||||
return this.events.pipe(
|
||||
take(1),
|
||||
switchMap((url: string) => {
|
||||
if (url.includes('?login_hint=')) {
|
||||
const newUrl = this.removeParam('login_hint', url);
|
||||
return of(newUrl);
|
||||
} else {
|
||||
return this.processor.createState(url);
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
return this.events.pipe(
|
||||
take(1),
|
||||
switchMap(url => this.processor.createState(url)),
|
||||
);
|
||||
}
|
||||
public ngOnDestroy(): void {
|
||||
this.unsubscribe$.next();
|
||||
}
|
||||
|
||||
public ngOnDestroy(): void {
|
||||
this.unsubscribe$.next();
|
||||
removeParam(key: string, sourceURL: string) {
|
||||
var rtn = sourceURL.split('?')[0],
|
||||
param,
|
||||
params_arr = [],
|
||||
queryString = sourceURL.indexOf('?') !== -1 ? sourceURL.split('?')[1] : '';
|
||||
if (queryString !== '') {
|
||||
params_arr = queryString.split('&');
|
||||
for (var i = params_arr.length - 1; i >= 0; i -= 1) {
|
||||
param = params_arr[i].split('=')[0];
|
||||
if (param === key) {
|
||||
params_arr.splice(i, 1);
|
||||
}
|
||||
}
|
||||
if (params_arr.length) rtn = rtn + '?' + params_arr.join('&');
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { StorageService } from './storage.service';
|
||||
|
||||
const authorizationKey = 'Authorization';
|
||||
const bearerPrefix = 'Bearer';
|
||||
const accessTokenStorageKey = 'access_token';
|
||||
|
||||
export interface StripeCustomer {
|
||||
contact: string;
|
||||
company?: string;
|
||||
address: string;
|
||||
city: string;
|
||||
postal_code: string;
|
||||
country: string;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class SubscriptionService {
|
||||
constructor(private http: HttpClient, private storageService: StorageService) {}
|
||||
|
||||
public getLink(orgId: string, redirectURI: string): Promise<any> {
|
||||
return this.http
|
||||
.get('./assets/environment.json')
|
||||
.toPromise()
|
||||
.then((data: any) => {
|
||||
if (data && data.subscriptionServiceUrl) {
|
||||
const serviceUrl = data.subscriptionServiceUrl;
|
||||
const accessToken = this.storageService.getItem(accessTokenStorageKey);
|
||||
return this.http
|
||||
.get(`${serviceUrl}/redirect`, {
|
||||
headers: {
|
||||
[authorizationKey]: `${bearerPrefix} ${accessToken}`,
|
||||
},
|
||||
params: {
|
||||
org: orgId,
|
||||
return_url: encodeURI(redirectURI),
|
||||
country: 'ch',
|
||||
},
|
||||
})
|
||||
.toPromise();
|
||||
} else {
|
||||
return Promise.reject('Could not load environment');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public getCustomer(orgId: string): Promise<any> {
|
||||
return this.http
|
||||
.get('../../assets/environment.json')
|
||||
.toPromise()
|
||||
.then((data: any) => {
|
||||
if (data && data.subscriptionServiceUrl) {
|
||||
const serviceUrl = data.subscriptionServiceUrl;
|
||||
const accessToken = this.storageService.getItem(accessTokenStorageKey);
|
||||
return this.http
|
||||
.get(`${serviceUrl}/customer`, {
|
||||
headers: {
|
||||
[authorizationKey]: `${bearerPrefix} ${accessToken}`,
|
||||
},
|
||||
params: {
|
||||
org: orgId,
|
||||
},
|
||||
})
|
||||
.toPromise();
|
||||
} else {
|
||||
return Promise.reject('Could not load environment');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public setCustomer(orgId: string, body: StripeCustomer): Promise<any> {
|
||||
return this.http
|
||||
.get('./assets/environment.json')
|
||||
.toPromise()
|
||||
.then((data: any) => {
|
||||
if (data && data.subscriptionServiceUrl) {
|
||||
const serviceUrl = data.subscriptionServiceUrl;
|
||||
const accessToken = this.storageService.getItem(accessTokenStorageKey);
|
||||
return this.http
|
||||
.post(`${serviceUrl}/customer`, body, {
|
||||
headers: {
|
||||
[authorizationKey]: `${bearerPrefix} ${accessToken}`,
|
||||
},
|
||||
params: {
|
||||
org: orgId,
|
||||
},
|
||||
})
|
||||
.toPromise();
|
||||
} else {
|
||||
return Promise.reject('Could not load environment');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user