From 91b2bd49626fc9de04da96480d520a50c853e3c2 Mon Sep 17 00:00:00 2001 From: rubikscraft Date: Mon, 18 Apr 2022 17:46:17 +0200 Subject: [PATCH] Add authorization to image worker --- .../picsur-img/picsur-img.component.ts | 24 +++++++++++-------- frontend/src/app/services/api/api.service.ts | 14 +++++++++++ frontend/src/app/workers/qoi-worker.dto.ts | 3 ++- .../src/app/workers/qoi-worker.service.ts | 9 ++++--- frontend/src/app/workers/qoi.job.ts | 11 +++++++-- frontend/src/app/workers/qoi.worker.ts | 7 +++--- 6 files changed, 49 insertions(+), 19 deletions(-) diff --git a/frontend/src/app/components/picsur-img/picsur-img.component.ts b/frontend/src/app/components/picsur-img/picsur-img.component.ts index 9879da6..8100076 100644 --- a/frontend/src/app/components/picsur-img/picsur-img.component.ts +++ b/frontend/src/app/components/picsur-img/picsur-img.component.ts @@ -6,12 +6,11 @@ import { SimpleChanges, ViewChild } from '@angular/core'; -import { - SupportedMime -} from 'picsur-shared/dist/dto/mimes.dto'; -import { HasFailed } from 'picsur-shared/dist/types'; +import { FullMime, SupportedMime } from 'picsur-shared/dist/dto/mimes.dto'; +import { AsyncFailable, HasFailed } from 'picsur-shared/dist/types'; import { URLRegex } from 'picsur-shared/dist/util/common-regex'; import { ParseMime } from 'picsur-shared/dist/util/parse-mime'; +import { ApiService } from 'src/app/services/api/api.service'; import { Logger } from 'src/app/services/logger/logger.service'; import { QoiWorkerService } from 'src/app/workers/qoi-worker.service'; @@ -35,7 +34,10 @@ export class PicsurImgComponent implements OnChanges { public state: PicsurImgState = PicsurImgState.Loading; - constructor(private qoiWorker: QoiWorkerService) {} + constructor( + private qoiWorker: QoiWorkerService, + private apiService: ApiService + ) {} ngOnChanges(changes: SimpleChanges): void { let url = this.imageURL ?? ''; @@ -67,11 +69,13 @@ export class PicsurImgComponent implements OnChanges { } } - private async getMime(url: string) { - const response = await fetch(url, { - method: 'HEAD', - }); - const mimeHeader = response.headers.get('content-type') ?? ''; + private async getMime(url: string): AsyncFailable { + const response = await this.apiService.head(url); + if (HasFailed(response)) { + return response; + } + + const mimeHeader = response.get('content-type') ?? ''; const mime = mimeHeader.split(';')[0]; const fullMime = ParseMime(mime); diff --git a/frontend/src/app/services/api/api.service.ts b/frontend/src/app/services/api/api.service.ts index f977d70..2a49533 100644 --- a/frontend/src/app/services/api/api.service.ts +++ b/frontend/src/app/services/api/api.service.ts @@ -34,6 +34,10 @@ export class ApiService { return this.fetchSafeJson(type, url, { method: 'GET' }); } + public async head(url: string): AsyncFailable { + return this.fetchHead(url, { method: 'HEAD' }); + } + public async post( sendType: ZodDtoStatic, receiveType: ZodDtoStatic, @@ -118,6 +122,16 @@ export class ApiService { } } + private async fetchHead( + url: RequestInfo, + options: RequestInit + ): AsyncFailable { + const response = await this.fetch(url, options); + if (HasFailed(response)) return response; + + return response.headers; + } + private async fetch( url: RequestInfo, options: RequestInit diff --git a/frontend/src/app/workers/qoi-worker.dto.ts b/frontend/src/app/workers/qoi-worker.dto.ts index 46db302..31eeb6b 100644 --- a/frontend/src/app/workers/qoi-worker.dto.ts +++ b/frontend/src/app/workers/qoi-worker.dto.ts @@ -7,10 +7,11 @@ export interface QOIImage { export interface QOIWorkerIn { id: number; url: string; + authorization: string; } export interface QOIWorkerOut extends QOIImage { id: number; } -export type QOIJob = (url: string) => Promise; +export type QOIJob = (url: string, authorization: string) => Promise; diff --git a/frontend/src/app/workers/qoi-worker.service.ts b/frontend/src/app/workers/qoi-worker.service.ts index 4a031f2..4a034c0 100644 --- a/frontend/src/app/workers/qoi-worker.service.ts +++ b/frontend/src/app/workers/qoi-worker.service.ts @@ -1,4 +1,5 @@ import { Injectable } from '@angular/core'; +import { KeyService } from '../services/storage/key.service'; import { QOIImage, QOIJob, QOIWorkerOut } from './qoi-worker.dto'; @Injectable({ @@ -8,7 +9,7 @@ export class QoiWorkerService { private worker: Worker | null = null; private job: Promise | null = null; - constructor() { + constructor(private keyService: KeyService) { if (typeof Worker !== 'undefined') { this.worker = new Worker(new URL('./qoi.worker', import.meta.url)); } else { @@ -17,6 +18,8 @@ export class QoiWorkerService { } public async decode(url: string): Promise { + const authorization = 'Bearer ' + (this.keyService.get() ?? ''); + if (this.worker && !this.job) { return new Promise((resolve, reject) => { const id = Date.now(); @@ -31,11 +34,11 @@ export class QoiWorkerService { }); }; this.worker!.addEventListener('message', listener); - this.worker!.postMessage({ id, url }); + this.worker!.postMessage({ id, url, authorization }); }); } else if (!this.worker && this.job) { const job = await this.job; - return job(url); + return job(url, authorization); } else { throw new Error('No worker available'); } diff --git a/frontend/src/app/workers/qoi.job.ts b/frontend/src/app/workers/qoi.job.ts index 2fea00d..bd24871 100644 --- a/frontend/src/app/workers/qoi.job.ts +++ b/frontend/src/app/workers/qoi.job.ts @@ -1,8 +1,15 @@ import { QOIdecodeJS } from '../util/qoi/qoi-decode'; import { QOIImage } from './qoi-worker.dto'; -export default async function qoiDecodeJob(url: string): Promise { - const response = await fetch(url); +export default async function qoiDecodeJob( + url: string, + authorization: string +): Promise { + const response = await fetch(url, { + headers: { + Authorization: authorization, + }, + }); if (!response.ok) { throw new Error(`Failed to fetch image: ${url}`); } diff --git a/frontend/src/app/workers/qoi.worker.ts b/frontend/src/app/workers/qoi.worker.ts index a962e0d..b631f13 100644 --- a/frontend/src/app/workers/qoi.worker.ts +++ b/frontend/src/app/workers/qoi.worker.ts @@ -4,12 +4,13 @@ import { QOIWorkerIn, QOIWorkerOut } from './qoi-worker.dto'; import qoiDecodeJob from './qoi.job'; addEventListener('message', async (msg) => { - const { id, url } = msg.data as QOIWorkerIn; - if (!id || !url) { + const { id, url, authorization } = msg.data as QOIWorkerIn; + + if (!id || !url || !authorization) { throw new Error('Invalid message'); } - const result = await qoiDecodeJob(url); + const result = await qoiDecodeJob(url, authorization); const returned: QOIWorkerOut = { id,