Skip to content

Commit

Permalink
cherrypick (#984)
Browse files Browse the repository at this point in the history
  • Loading branch information
mbritense authored May 8, 2024
1 parent 7e2fe1d commit 054573f
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,25 @@ import {
Formio,
FormioComponent as FormIoSourceComponent,
FormioOptions,
FormioRefreshValue,
FormioSubmission,
FormioUtils,
} from '@formio/angular';
import {FormioRefreshValue} from '@formio/angular/formio.common';
import {jwtDecode} from 'jwt-decode';
import {NGXLogger} from 'ngx-logger';
import {BehaviorSubject, combineLatest, Observable, Subject, Subscription, timer} from 'rxjs';
import {distinctUntilChanged, map, switchMap, take, tap} from 'rxjs/operators';
import {FormIoStateService} from './services/form-io-state.service';
import {ActivatedRoute} from '@angular/router';
import {TranslateService} from '@ngx-translate/core';
import {FormIoLocalStorageService} from './services/form-io-local-storage.service';
import {deepmerge} from 'deepmerge-ts';
import {ConfigService, ValtimoConfig} from '@valtimo/config';

@Component({
selector: 'valtimo-form-io',
templateUrl: './form-io.component.html',
styleUrls: ['./form-io.component.css'],
providers: [FormIoLocalStorageService],
})
export class FormioComponent implements OnInit, OnChanges, OnDestroy {
@Input() set options(optionsValue: ValtimoFormioOptions) {
Expand All @@ -73,7 +74,7 @@ export class FormioComponent implements OnInit, OnChanges, OnDestroy {

@HostListener('window:beforeunload', ['$event'])
private handleBeforeUnload() {
this.clearTokenFromLocalStorage();
this.localStorageService.clearTokenFromLocalStorage();
}

public refreshForm = new EventEmitter<FormioRefreshValue>();
Expand All @@ -83,7 +84,6 @@ export class FormioComponent implements OnInit, OnChanges, OnDestroy {
public readonly options$ = new BehaviorSubject<ValtimoFormioOptions>(undefined);
public readonly readOnly$ = new BehaviorSubject<boolean>(false);
public readonly errors$ = new BehaviorSubject<Array<string>>([]);
public readonly tokenSetInLocalStorage$ = new BehaviorSubject<boolean>(false);

public readonly currentLanguage$ = this.translateService.stream('key').pipe(
map(() => this.translateService.currentLang),
Expand Down Expand Up @@ -115,19 +115,20 @@ export class FormioComponent implements OnInit, OnChanges, OnDestroy {
tap(options => this.logger.debug('Form.IO options used', options))
);

public readonly tokenSetInLocalStorage$ = this.localStorageService.tokenSetInLocalStorage$;

private _tokenRefreshTimerSubscription!: Subscription;
private _formRefreshSubscription!: Subscription;
private readonly _subscriptions = new Subscription();
private readonly _tokenTimerSubscription = new Subscription();

private readonly _FORMIO_TOKEN_LOCAL_STORAGE_KEY = 'formioToken';

constructor(
private readonly userProviderService: UserProviderService,
private readonly logger: NGXLogger,
private readonly stateService: FormIoStateService,
private readonly route: ActivatedRoute,
private readonly translateService: TranslateService,
private readonly localStorageService: FormIoLocalStorageService,
private readonly modalService: ValtimoModalService,
private readonly configService: ConfigService
) {
Expand Down Expand Up @@ -157,7 +158,7 @@ export class FormioComponent implements OnInit, OnChanges, OnDestroy {
this.unsubscribeFormRefresh();
this._tokenRefreshTimerSubscription?.unsubscribe();
this._subscriptions.unsubscribe();
this.clearTokenFromLocalStorage();
this.localStorageService.clearTokenFromLocalStorage();
}

public showErrors(errors: string[]): void {
Expand Down Expand Up @@ -218,9 +219,8 @@ export class FormioComponent implements OnInit, OnChanges, OnDestroy {
private setToken(token: string): void {
Formio.setUser(jwtDecode(token));
Formio.setToken(token);
localStorage.setItem(this._FORMIO_TOKEN_LOCAL_STORAGE_KEY, token);
this.setTimerForTokenRefresh(token);
this.tokenSetInLocalStorage$.next(true);
this.localStorageService.setTokenInLocalStorage(token);

this.logger.debug('New token set for form.io.');
}
Expand Down Expand Up @@ -277,10 +277,6 @@ export class FormioComponent implements OnInit, OnChanges, OnDestroy {
);
}

private clearTokenFromLocalStorage(): void {
localStorage.removeItem(this._FORMIO_TOKEN_LOCAL_STORAGE_KEY);
}

private setOverrideOptions(config: ValtimoConfig): void {
if (!config.formioOptions) return;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright 2015-2024 Ritense BV, the Netherlands.
*
* Licensed under EUPL, Version 1.2 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import {Injectable} from '@angular/core';
import {BehaviorSubject, Observable} from 'rxjs';

@Injectable()
export class FormIoLocalStorageService {
private readonly _FORMIO_TOKEN_LOCAL_STORAGE_KEY = 'formioToken';
private readonly _tokenSetInLocalStorage$ = new BehaviorSubject<boolean>(false);

public get tokenSetInLocalStorage$(): Observable<boolean> {
return this._tokenSetInLocalStorage$.asObservable();
}

public setTokenInLocalStorage(token: string): void {
setTimeout(() => {
localStorage.setItem(this._FORMIO_TOKEN_LOCAL_STORAGE_KEY, token);
this.checkIfTokenExistsInLocalStorage();
});
}

public clearTokenFromLocalStorage(): void {
localStorage.removeItem(this._FORMIO_TOKEN_LOCAL_STORAGE_KEY);
this.checkIfTokenIsRemovedFromLocalStorage();
}

private getTokenFromLocalStorage(): string | null {
return localStorage.getItem(this._FORMIO_TOKEN_LOCAL_STORAGE_KEY);
}

private checkIfTokenExistsInLocalStorage(): void {
const maxChecks = 100;
let checks = 0;

if (this.getTokenFromLocalStorage()) {
this._tokenSetInLocalStorage$.next(true);
} else if (checks <= maxChecks) {
checks++;
this.checkIfTokenExistsInLocalStorage();
}
}

private checkIfTokenIsRemovedFromLocalStorage(): void {
const maxChecks = 100;
let checks = 0;

if (this.getTokenFromLocalStorage() && checks <= maxChecks) {
checks++;
this.checkIfTokenIsRemovedFromLocalStorage();
} else {
this._tokenSetInLocalStorage$.next(false);
}
}
}

0 comments on commit 054573f

Please sign in to comment.