Skip to content

Commit

Permalink
Add support for additional params in external auth url
Browse files Browse the repository at this point in the history
  • Loading branch information
mpgxvii committed Jan 16, 2025
1 parent acfa382 commit 3a0a21b
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 52 deletions.
21 changes: 20 additions & 1 deletion authorizer-app/src/app/admin/services/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,26 @@ export class UserService {
return this.http.delete(url);
}

storeAuthorizationToken(token: string) {
localStorage.setItem(StorageItem.AUTHORIZATION_TOKEN, token);
}

getAuthorizationToken() {
return localStorage.getItem(StorageItem.AUTHORIZATION_TOKEN);
}

storeReturnUrl(url: string) {
localStorage.setItem(StorageItem.EXTERNAL_RETURN_URL, url);
}

getReturnUrl() {
return localStorage.getItem(StorageItem.EXTERNAL_RETURN_URL);
}

clearReturnUrl() {
localStorage.removeItem(StorageItem.EXTERNAL_RETURN_URL);
}

storeUserAuthParams(url: string) {
const params = this.getJsonFromUrl(url);
localStorage.setItem(
Expand All @@ -87,7 +107,6 @@ export class UserService {
return params ? JSON.parse(params) : {};
}


getJsonFromUrl(url: string) {
const query = url.split('?')[1];
let result: any = {};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,59 +29,65 @@ export class AuthorizationCompletePageComponent implements OnInit {
this.isLoading = true;
const queryParams = this.activatedRoute.snapshot.queryParams;
const storedParams = this.service.getUserAuthParams();
const state = this.getOrDefault(queryParams.state, storedParams.state);
const oauth_token = this.getOrDefault(
queryParams.oauth_token,
storedParams.oauth_token
);
const oauth_verifier = this.getOrDefault(
queryParams.oauth_verifier,
storedParams.oauth_verifier
);
const oauth_token_secret = this.getOrDefault(
queryParams.oauth_token_secret,
storedParams.oauth_token_secret
);
const code = this.getOrDefault(queryParams.code, storedParams.code);
const stateOrToken = this.getStateOrToken(queryParams, storedParams);

let stateOrToken = state;
if (!state) {
stateOrToken = localStorage.getItem(SharedStorageItem.AUTHORIZATION_TOKEN);
}
if(!stateOrToken){
this.error = 'SHARED.AUTHORIZATION_COMPLETE_PAGE.ERROR.badUrl';
this.isLoading = false;
if (!stateOrToken) {
this.handleError('SHARED.AUTHORIZATION_COMPLETE_PAGE.ERROR.badUrl');
return;
}
const authorizeRequest = {
code,
oauth_token,
oauth_verifier,
oauth_token_secret
};

const authorizeRequest = this.buildAuthorizeRequest(queryParams, storedParams);
this.service.authorizeUser(authorizeRequest, stateOrToken).subscribe({
next: (resp) => {
this.sourceType = resp.sourceType;
this.project = resp.project.id;
if (resp.persistent) {
this.isLoading = false;
} else {
const lastLocation = JSON.parse(localStorage.getItem(StorageItem.LAST_LOCATION) || '{}');
this.router.navigate(
[lastLocation.url || '/'],
{queryParams: lastLocation.params}
).finally(() => this.service.clearUserAuthParams());
}
},
error: (error) => {
this.isLoading = false;
// TODO translate errors
this.error = error.error?.error_description || error.message || error;
}
next: (resp) => this.handleSuccessResponse(resp),
error: (error) => this.handleError(error.error?.error_description || error.message || error)
});
}

getOrDefault(value: any, defaultValue: any) {
return value ? value : defaultValue;
private getStateOrToken(queryParams: any, storedParams: any): string | null {
return (
this.getOrDefault(queryParams.state, storedParams.state) ||
localStorage.getItem(SharedStorageItem.AUTHORIZATION_TOKEN)
);
}

private buildAuthorizeRequest(queryParams: any, storedParams: any): any {
return {
code: this.getOrDefault(queryParams.code, storedParams.code),
oauth_token: this.getOrDefault(queryParams.oauth_token, storedParams.oauth_token),
oauth_verifier: this.getOrDefault(queryParams.oauth_verifier, storedParams.oauth_verifier),
oauth_token_secret: this.getOrDefault(queryParams.oauth_token_secret, storedParams.oauth_token_secret)
};
}

private handleSuccessResponse(resp: any): void {
this.sourceType = resp.sourceType;
this.project = resp.project.id;

this.redirectToExternalUrl();

if (resp.persistent) {
this.isLoading = false;
return;
}
const lastLocation = JSON.parse(localStorage.getItem(StorageItem.LAST_LOCATION) || '{}');
this.router.navigate([lastLocation.url || '/'], { queryParams: lastLocation.params })
.finally(() => this.service.clearUserAuthParams());
}

private redirectToExternalUrl(): void {
const externalUrl = this.service.getReturnUrl();
if (externalUrl) {
this.service.clearReturnUrl();
window.location.href = externalUrl;
}
}

private handleError(message: string): void {
this.error = message;
this.isLoading = false;
}

private getOrDefault(value: any, defaultValue: any): any {
return value ?? defaultValue;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,25 @@ export class AuthorizationPageComponent implements OnInit {
) {}

ngOnInit(): void {
const {token, secret} = this.activatedRoute.snapshot.queryParams;
const {token, secret, redirect, return_to} = this.activatedRoute.snapshot.queryParams;
if(!token || !secret){
this.error = 'SHARED.AUTHORIZATION_PAGE.ERROR.badUrl';
this.isLoading = false;
return;
}
localStorage.setItem(StorageItem.AUTHORIZATION_TOKEN, token);
this.userService.storeAuthorizationToken(token);
this.userService.storeReturnUrl(return_to);
this.userService.getAuthEndpointUrl({secret}, token).subscribe({
next: (resp) => {
if (resp.authEndpointUrl) {
this.sourceType = resp.sourceType;
this.project = resp.project.id;
this.authEndpointUrl = resp.authEndpointUrl;
this.isLoading = false;
this.userService.storeUserAuthParams(resp.authEndpointUrl);
if (redirect) {
this.authorize();
}
this.isLoading = false;
}
},
error: (error) => {
Expand Down
3 changes: 2 additions & 1 deletion authorizer-app/src/app/shared/enums/storage-item.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export enum StorageItem {
AUTHORIZATION_TOKEN = 'authorizationToken',
LOCALE = 'locale',
AUTH_ENDPOINT_PARAMS_STORAGE_KEY = 'auth_endpoint_params'
AUTH_ENDPOINT_PARAMS_STORAGE_KEY = 'auth_endpoint_params',
EXTERNAL_RETURN_URL = 'externalReturnUrl',
}

0 comments on commit 3a0a21b

Please sign in to comment.