diff --git a/src/app/d4sauth.service.ts b/src/app/d4sauth.service.ts index 31a46a5..64501f4 100644 --- a/src/app/d4sauth.service.ts +++ b/src/app/d4sauth.service.ts @@ -1,22 +1,23 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; +import { EventType } from '@angular/router'; import { resolve } from 'dns'; -import { KeycloakService } from 'keycloak-angular'; +import { KeycloakEventType, KeycloakService } from 'keycloak-angular'; @Injectable({ providedIn: 'root' }) export class D4sAuthService { - redirectUrl: string = 'd4sworkspace://org.gcube.workspace/'; //'http://localhost:8100/'; // + redirectUrl: string = 'http://localhost:8100/'; //'d4sworkspace://org.gcube.workspace/'; // - umaUrl : string = " https://accounts.dev.d4science.org/auth/realms/d4science/protocol/openid-connect/token"; + umaUrl: string = " https://accounts.dev.d4science.org/auth/realms/d4science/protocol/openid-connect/token"; audience: string = '%2Fgcube'; config: any = undefined; - uma : UmaToken | undefined ; + uma: UmaToken | undefined; constructor(private keycloak: KeycloakService, private httpClient: HttpClient) { } @@ -29,9 +30,7 @@ export class D4sAuthService { } if (!this.isAuthorized()) - throw("error authorizing"); - - await this.entitlement(this.audience).then( res => this.uma = res); + throw ("error authorizing"); } isAuthorized(): boolean { @@ -40,43 +39,65 @@ export class D4sAuthService { else return auth; } - - getSecureHeader(): string{ - return "Bearer "+this.uma?.access_token; + + parseJwt(token: string) { + var base64Url = token.split('.')[1] + var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/') + var jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) { + return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2) + }).join('')) + + return JSON.parse(jsonPayload); + } + + + async getSecureHeader(): Promise { + var mustUpdate = false; + if (this.keycloak.isTokenExpired(30)) { + await this.keycloak.updateToken(); + mustUpdate = true; + console.log("token refreshed"); + } + if (mustUpdate || !this.uma) + this.uma = await this.entitlement(this.audience); + + return "Bearer " + this.uma.access_token; } entitlement(resourceServerId: any): Promise { return new Promise((resolve, reject) => { const keycloak = this.keycloak.getKeycloakInstance(); - + var params = "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" - + const audience = encodeURIComponent(resourceServerId) params += "&audience=" + audience; - - console.log("params "+params); - this.httpClient.post(this.umaUrl, params , { headers: { - "Content-type": "application/x-www-form-urlencoded", - "Authorization": "Bearer " + this.keycloak.getKeycloakInstance().token - } }).subscribe( + console.log("params " + params); + + this.httpClient.post(this.umaUrl, params, { + headers: { + "Content-type": "application/x-www-form-urlencoded", + "Authorization": "Bearer " + this.keycloak.getKeycloakInstance().token + } + }).subscribe( { - error: (err) => reject("error getting uma token "+err), - next: (res:UmaToken) => resolve(res) - } + error: (err) => reject("error getting uma token " + err), + next: (res: UmaToken) => resolve(res) + } ); }); } } -class UmaToken{ +class UmaToken { - constructor(public upgraded :boolean, - public access_token:string, + constructor(public upgraded: boolean, + public access_token: string, public expires_in: number, public refresh_expires_in: number, public refresh_token: string, public token_type: string, - public not_before_policy:number){} + public not_before_policy: number) { } } \ No newline at end of file diff --git a/src/app/model/actions/action.ts b/src/app/model/actions/action.ts index e3229fc..5353b60 100644 --- a/src/app/model/actions/action.ts +++ b/src/app/model/actions/action.ts @@ -13,7 +13,7 @@ export abstract class Action { return undefined; } - abstract actionHandler(data: any, storagehub: StoragehubService): Observable; + abstract actionHandler(data: any, storagehub: StoragehubService): any; abstract getName(): string; diff --git a/src/app/model/actions/copy-item.ts b/src/app/model/actions/copy-item.ts index 5f53ed5..84f6289 100644 --- a/src/app/model/actions/copy-item.ts +++ b/src/app/model/actions/copy-item.ts @@ -17,19 +17,19 @@ export class CopyAction extends Action { notClickableIds: [item.item.id], notSelectableIds: [item.item.parentId], onSelected: (destinationItem: WSItem) => { - this.actionHandler({ item: item, destinationItem: destinationItem }, storagehub).subscribe( + this.actionHandler({ item: item, destinationItem: destinationItem }, storagehub).then( (obs) => obs.subscribe( () => { reload(); notify(`${item.getTitle()} copied`); } - ) + )) } } }; } - actionHandler(data: { item: WSItem, destinationItem: WSItem }, storagehub: StoragehubService): Observable { + actionHandler(data: { item: WSItem, destinationItem: WSItem }, storagehub: StoragehubService){ return storagehub.copyItem(data.destinationItem.item.id, data.item.item.id, data.item.item.name); } diff --git a/src/app/model/actions/create-folder.ts b/src/app/model/actions/create-folder.ts index 458cb4d..76bec39 100644 --- a/src/app/model/actions/create-folder.ts +++ b/src/app/model/actions/create-folder.ts @@ -6,46 +6,46 @@ import { Action } from "./action"; export class CreateFolderAction extends Action { - override getAlertOptions(item: WSItem, storagehub: StoragehubService, reload: Function): AlertOptions { - var title = item.getTitle(); - var options: AlertOptions = { - header: 'Create folder', - message: 'Please specify the name of the new folder', - inputs: [ - { - name: 'name', - type: 'text', - placeholder: 'new folder' - } - ], - buttons: [ - { - text: 'Cancel', - role: 'cancel' - }, - { - text: 'Create', - handler: (data) => { - this.actionHandler({wsitem: item, name: data.name}, storagehub).subscribe( - () => reload() - ); - - } - } - ] - }; - return options; + override getAlertOptions(item: WSItem, storagehub: StoragehubService, reload: Function): AlertOptions { + var title = item.getTitle(); + var options: AlertOptions = { + header: 'Create folder', + message: 'Please specify the name of the new folder', + inputs: [ + { + name: 'name', + type: 'text', + placeholder: 'new folder' + } + ], + buttons: [ + { + text: 'Cancel', + role: 'cancel' + }, + { + text: 'Create', + handler: (data) => { + this.actionHandler({ wsitem: item, name: data.name }, storagehub).then((obs) => obs.subscribe( + () => reload() + ) + ); + } + } + ] + }; + return options; - } - actionHandler(data: {wsitem: WSItem, name : string}, storagehub: StoragehubService): Observable { - return storagehub.createFolder(data.wsitem.item.id, data.name, ""); - } + } + actionHandler(data: { wsitem: WSItem, name: string }, storagehub: StoragehubService) { + return storagehub.createFolder(data.wsitem.item.id, data.name, ""); + } - getName(): string { - return "Create Folder"; - } - getActionType(): string | undefined { - return undefined; - } + getName(): string { + return "Create Folder"; + } + getActionType(): string | undefined { + return undefined; + } } diff --git a/src/app/model/actions/delete-item.ts b/src/app/model/actions/delete-item.ts index da8a4f8..e866044 100644 --- a/src/app/model/actions/delete-item.ts +++ b/src/app/model/actions/delete-item.ts @@ -17,16 +17,16 @@ export class DeleteAction extends Action { { text: 'Yes', handler: () => { - this.actionHandler(item, storagehub).subscribe( + this.actionHandler(item, storagehub).then((obs) => obs.subscribe( () => reload() - ); + )); } }] }; return options; } - actionHandler(data: WSItem, storagehub: StoragehubService): Observable { + actionHandler(data: WSItem, storagehub: StoragehubService) { return storagehub.deleteItem(data.item.id); } diff --git a/src/app/model/actions/move-item.ts b/src/app/model/actions/move-item.ts index 2866cb9..17d8c44 100644 --- a/src/app/model/actions/move-item.ts +++ b/src/app/model/actions/move-item.ts @@ -17,19 +17,19 @@ export class MoveAction extends Action { notClickableIds: [item.item.id], notSelectableIds: [item.item.parentId], onSelected: (destinationItem:WSItem) =>{ - this.actionHandler({item: item, destinationItem: destinationItem}, storagehub).subscribe( + this.actionHandler({item: item, destinationItem: destinationItem}, storagehub).then( (obs) => obs.subscribe( () => { reload(); notify(`${item.getTitle()} moved`); } - ) + )) } } }; } - actionHandler(data: {item: WSItem, destinationItem : WSItem}, storagehub: StoragehubService): Observable { + actionHandler(data: {item: WSItem, destinationItem : WSItem}, storagehub: StoragehubService) { return storagehub.moveItem(data.destinationItem.item.id, data.item.item.id); } diff --git a/src/app/model/actions/rename-item.ts b/src/app/model/actions/rename-item.ts index 2037e47..5487283 100644 --- a/src/app/model/actions/rename-item.ts +++ b/src/app/model/actions/rename-item.ts @@ -26,9 +26,9 @@ export class RenameAction extends Action { { text: 'Rename', handler: (data) => { - this.actionHandler({item: item, newName: data.name}, storagehub).subscribe( + this.actionHandler({item: item, newName: data.name}, storagehub).then( (obs) => obs.subscribe( () => reload() - ); + )); } } ] @@ -36,7 +36,7 @@ export class RenameAction extends Action { return options; } - actionHandler(data: {item: WSItem, newName : string}, storagehub: StoragehubService): Observable { + actionHandler(data: {item: WSItem, newName : string}, storagehub: StoragehubService) { return storagehub.renameItem(data.item.item.id, data.newName); } diff --git a/src/app/show-folder/show-folder.component.ts b/src/app/show-folder/show-folder.component.ts index 80477b5..af2a5d0 100644 --- a/src/app/show-folder/show-folder.component.ts +++ b/src/app/show-folder/show-folder.component.ts @@ -76,7 +76,7 @@ export class ShowFolderComponent implements OnInit { loadDocuments() { this.filteredItems = undefined; if (this.parentItem) { - this.storagehub.getChildren(this.parentItem.item.id).subscribe( + this.storagehub.getChildren(this.parentItem.item.id).then( (obs) => obs.subscribe( (res) => { const tmpItems$: WSItem[] = [] const tmpFiltered$: WSItem[] = [] @@ -90,6 +90,7 @@ export class ShowFolderComponent implements OnInit { this._items = tmpItems$.sort(Sorting.getSortFunction(this.currentSortName, this.currentSortType)); this.filteredItems = tmpFiltered$.sort(Sorting.getSortFunction(this.currentSortName, this.currentSortType)); }) + ) } } @@ -160,12 +161,13 @@ export class ShowFolderComponent implements OnInit { if (selected && this.parentItem) { this.underUploadItem = [selected.name]; const upload$ = this.storagehub.uploadFile(this.parentItem.item.id, selected.name, selected); - upload$.subscribe({ + upload$.then( (obs) => obs.subscribe({ next: () => this.loadDocuments(), error: () => this.underUploadItem = [], complete: () => this.underUploadItem = [] - }); + }) + ); } } diff --git a/src/app/storagehub.service.ts b/src/app/storagehub.service.ts index 85c611b..87bdd02 100644 --- a/src/app/storagehub.service.ts +++ b/src/app/storagehub.service.ts @@ -18,17 +18,17 @@ export class StoragehubService { } - getWsRoot() { + async getWsRoot() { const getWsURL = `${shURL}?exclude=hl:accounting`; - const bearer = this.auth.getSecureHeader(); + const bearer = await this.auth.getSecureHeader(); return this.http.get(getWsURL, {headers: {"Authorization": bearer }, observe: 'body', responseType: 'json'}).pipe( map(value => value.item), catchError(this.error) ); } - getTrashRoot(): Observable { - const bearer = this.auth.getSecureHeader(); + async getTrashRoot(): Promise> { + const bearer = await this.auth.getSecureHeader(); const getTrashURL = `${shURL}/trash/?exclude=hl:accounting`; return this.http.get(getTrashURL, {headers: {"Authorization": bearer }, observe: "body", responseType: "json"}).pipe( map(value => value.item), @@ -36,8 +36,8 @@ export class StoragehubService { ); } - getVres(): Observable { - const bearer = this.auth.getSecureHeader(); + async getVres(): Promise> { + const bearer = await this.auth.getSecureHeader(); const getVresURL = `${shURL}/vrefolders/?exclude=hl:accounting`; return this.http.get(getVresURL, {headers: {"Authorization": bearer }, observe: 'body', responseType: 'json'}).pipe( map(value => value.itemlist), @@ -45,8 +45,8 @@ export class StoragehubService { ); } - getItem(id: string): Observable { - const bearer = this.auth.getSecureHeader(); + async getItem(id: string): Promise> { + const bearer = await this.auth.getSecureHeader(); const getWsURL = `${shURL}/items/${id}?exclude=hl:accounting`; return this.http.get(getWsURL, {headers: {"Authorization": bearer }, observe: 'body', responseType: 'json'}).pipe( map(value => value.item), @@ -54,8 +54,8 @@ export class StoragehubService { ); } - getChildren(id:string, onlyFolder?:boolean): Observable{ - const bearer = this.auth.getSecureHeader(); + async getChildren(id:string, onlyFolder?:boolean): Promise>{ + const bearer = await this.auth.getSecureHeader(); let getWsURL = `${shURL}/items/${id}/children?exclude=hl:accounting`; if (onlyFolder) getWsURL += '&onlyType=nthl:workspaceItem'; @@ -65,8 +65,8 @@ export class StoragehubService { ); } - getAnchestor(id:string): Observable{ - const bearer = this.auth.getSecureHeader(); + async getAnchestor(id:string): Promise>{ + const bearer = await this.auth.getSecureHeader(); let getWsURL = `${shURL}/items/${id}/ancherstors?exclude=hl:accounting`; console.log("ws children "+getWsURL); return this.http.get(getWsURL, {headers: {"Authorization": bearer }, observe: 'body', responseType: 'json'}).pipe( @@ -75,8 +75,8 @@ export class StoragehubService { ); } - uploadFile(parentId: string, name: string, file: File){ - const bearer = this.auth.getSecureHeader(); + async uploadFile(parentId: string, name: string, file: File){ + const bearer = await this.auth.getSecureHeader(); let uploadURL = `${shURL}/items/${parentId}/create/FILE`; const formData = new FormData(); formData.append("name", name); @@ -87,8 +87,8 @@ export class StoragehubService { ); } - createFolder(parentId: string, name: string, description: string) : Observable { - const bearer = this.auth.getSecureHeader(); + async createFolder(parentId: string, name: string, description: string) { + const bearer = await this.auth.getSecureHeader(); let createFolderURL = `${shURL}/items/${parentId}/create/FOLDER`; const formData = new FormData(); let body = `name=${name}&description=${description}`; @@ -97,16 +97,16 @@ export class StoragehubService { ); } - deleteItem(itemId: string) : Observable { - const bearer = this.auth.getSecureHeader(); + async deleteItem(itemId: string) : Promise> { + const bearer = await this.auth.getSecureHeader(); let deleteItemUrl = `${shURL}/items/${itemId}`; return this.http.delete( deleteItemUrl).pipe( catchError(this.error) ); } - renameItem(itemId: string, newName: string) : Observable { - const bearer = this.auth.getSecureHeader(); + async renameItem(itemId: string, newName: string) { + const bearer = await this.auth.getSecureHeader(); let renameItemUrl = `${shURL}/items/${itemId}/rename`; let body = `newName=${newName}`; return this.http.put(renameItemUrl,body,{observe: 'body', responseType: 'text' ,headers: { 'Content-Type' : 'application/x-www-form-urlencoded', "Authorization": bearer }}).pipe( @@ -114,8 +114,8 @@ export class StoragehubService { ); } - copyItem(destinationId: string, itemId: string, name:string) : Observable { - const bearer = this.auth.getSecureHeader(); + async copyItem(destinationId: string, itemId: string, name:string) { + const bearer = await this.auth.getSecureHeader(); let copyItemUrl = `${shURL}/items/${itemId}/copy`; let body = `destinationId=${destinationId}&fileName=${name}`; return this.http.put(copyItemUrl,body,{observe: 'body', responseType: 'text' ,headers: { 'Content-Type' : 'application/x-www-form-urlencoded', "Authorization": bearer }}).pipe( @@ -123,8 +123,8 @@ export class StoragehubService { ); } - moveItem(destinationId: string, itemId: string) : Observable { - const bearer = this.auth.getSecureHeader(); + async moveItem(destinationId: string, itemId: string) { + const bearer = await this.auth.getSecureHeader(); let copyItemUrl = `${shURL}/items/${itemId}/move`; let body = `destinationId=${destinationId}`; return this.http.put(copyItemUrl,body,{observe: 'body', responseType: 'text' ,headers: { 'Content-Type' : 'application/x-www-form-urlencoded', "Authorization": bearer }}).pipe( diff --git a/src/app/trash/trash.page.ts b/src/app/trash/trash.page.ts index 5b834ce..77f68fa 100644 --- a/src/app/trash/trash.page.ts +++ b/src/app/trash/trash.page.ts @@ -20,19 +20,19 @@ export class TrashPage implements OnInit { ngOnInit() { - this.storagehub.getTrashRoot().subscribe( + this.storagehub.getTrashRoot().then((obs) => obs.subscribe( (res) => this.onSuccess(res) - ); + )); } private onSuccess(res: Item) { - this.storagehub.getChildren(res.id, false).subscribe( + this.storagehub.getChildren(res.id, false).then((obs) => obs.subscribe( (res) => { - const tmpItems$ : WSItem[] = [] + const tmpItems$: WSItem[] = [] res.forEach(i => tmpItems$.push(new WSItem(i))); this.values = tmpItems$; } - ) + )) } public getValues(): WSItem[] { diff --git a/src/app/vres/vres.page.ts b/src/app/vres/vres.page.ts index 291cf62..e5b109d 100644 --- a/src/app/vres/vres.page.ts +++ b/src/app/vres/vres.page.ts @@ -34,20 +34,20 @@ export class VresPage implements OnInit { this.root = !folderId; if (!tmpItem) { if (!folderId) - this.storagehub.getVres().subscribe( + this.storagehub.getVres().then( (obs) => obs.subscribe( (res) => { const tmpItems$: WSItem[] = [] res.forEach(i => tmpItems$.push(new WSItem(i))); this.values = tmpItems$; } - ); + )); else //folder is not cached - this.storagehub.getItem(folderId).subscribe( + this.storagehub.getItem(folderId).then( (obs) => obs.subscribe( (res) => { this.item = new WSItem(res); this.onSuccess(res) } - ); + )); } else { this.item = tmpItem; @@ -58,13 +58,13 @@ export class VresPage implements OnInit { private onSuccess(item: Item) { - this.storagehub.getChildren(item.id, false).subscribe( + this.storagehub.getChildren(item.id, false).then( (obs) => obs.subscribe( (res) => { const tmpItems$: WSItem[] = [] res.forEach(i => tmpItems$.push(new WSItem(i))); this.values = tmpItems$; } - ) + )) } public getValues(): WSItem[] | undefined { diff --git a/src/app/ws-viewer/ws-viewer.component.ts b/src/app/ws-viewer/ws-viewer.component.ts index 34d6530..4b4f72b 100644 --- a/src/app/ws-viewer/ws-viewer.component.ts +++ b/src/app/ws-viewer/ws-viewer.component.ts @@ -41,25 +41,26 @@ export class WsViewerComponent implements OnInit { loadDocuments() { if (this.currentItem) { - this.storagehub.getChildren(this.currentItem.item.id).subscribe( + this.storagehub.getChildren(this.currentItem.item.id).then( (obs) => obs.subscribe( (res) => { const tmpItems$: WSItem[] = [] res.forEach(i => tmpItems$.push(new WSItem(i))); this.items = tmpItems$.sort(Sorting.getSortFunction(SortName.FolderFirst, SortType.Asc)); }) + ); } else - this.storagehub.getWsRoot().subscribe( + this.storagehub.getWsRoot().then( (obs) => obs.subscribe( (res) => this.addVresToWs(new WSItem(res)) - ); + )); } addVresToWs(wsRoot: WSItem) { - this.storagehub.getVres().subscribe( + this.storagehub.getVres().then( (obs) => obs.subscribe( (res) => { const tmpItems$: WSItem[] = [wsRoot] res.forEach(i => tmpItems$.push(new WSItem(i))); this.items = tmpItems$; - }) + })); } isCurrentItemSelectable(){ diff --git a/src/app/ws/ws.page.ts b/src/app/ws/ws.page.ts index 9d5fa51..f79ea57 100644 --- a/src/app/ws/ws.page.ts +++ b/src/app/ws/ws.page.ts @@ -36,19 +36,19 @@ export class WsPage implements OnInit { this.root = !folderId; if (!tmpItem) { if (!folderId) - this.storagehub.getWsRoot().subscribe( + this.storagehub.getWsRoot().then( (obs) => obs.subscribe( (res) => { this.item = new WSItem(res); this.onSuccess(res) } - ); + )); else //folder is not cached - this.storagehub.getItem(folderId).subscribe( + this.storagehub.getItem(folderId).then( (obs) => obs.subscribe( (res) => { this.item = new WSItem(res); this.onSuccess(res) } - ); + )); } else { this.item = tmpItem; this.onSuccess(tmpItem.item); @@ -58,13 +58,13 @@ export class WsPage implements OnInit { private onSuccess(item: Item) { - this.storagehub.getChildren(item.id, false).subscribe( + this.storagehub.getChildren(item.id, false).then( (obs) => obs.subscribe( (res) => { const tmpItems$: WSItem[] = [] res.forEach(i => tmpItems$.push(new WSItem(i))); this.values = tmpItems$; } - ) + )) } public getValues(): WSItem[] | undefined {