Add authorization to image worker

This commit is contained in:
rubikscraft 2022-04-18 17:46:17 +02:00
parent 3759b8b23f
commit 91b2bd4962
No known key found for this signature in database
GPG key ID: 1463EBE9200A5CD4
6 changed files with 49 additions and 19 deletions

View file

@ -6,12 +6,11 @@ import {
SimpleChanges, SimpleChanges,
ViewChild ViewChild
} from '@angular/core'; } from '@angular/core';
import { import { FullMime, SupportedMime } from 'picsur-shared/dist/dto/mimes.dto';
SupportedMime import { AsyncFailable, HasFailed } from 'picsur-shared/dist/types';
} from 'picsur-shared/dist/dto/mimes.dto';
import { HasFailed } from 'picsur-shared/dist/types';
import { URLRegex } from 'picsur-shared/dist/util/common-regex'; import { URLRegex } from 'picsur-shared/dist/util/common-regex';
import { ParseMime } from 'picsur-shared/dist/util/parse-mime'; 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 { Logger } from 'src/app/services/logger/logger.service';
import { QoiWorkerService } from 'src/app/workers/qoi-worker.service'; import { QoiWorkerService } from 'src/app/workers/qoi-worker.service';
@ -35,7 +34,10 @@ export class PicsurImgComponent implements OnChanges {
public state: PicsurImgState = PicsurImgState.Loading; public state: PicsurImgState = PicsurImgState.Loading;
constructor(private qoiWorker: QoiWorkerService) {} constructor(
private qoiWorker: QoiWorkerService,
private apiService: ApiService
) {}
ngOnChanges(changes: SimpleChanges): void { ngOnChanges(changes: SimpleChanges): void {
let url = this.imageURL ?? ''; let url = this.imageURL ?? '';
@ -67,11 +69,13 @@ export class PicsurImgComponent implements OnChanges {
} }
} }
private async getMime(url: string) { private async getMime(url: string): AsyncFailable<FullMime> {
const response = await fetch(url, { const response = await this.apiService.head(url);
method: 'HEAD', if (HasFailed(response)) {
}); return response;
const mimeHeader = response.headers.get('content-type') ?? ''; }
const mimeHeader = response.get('content-type') ?? '';
const mime = mimeHeader.split(';')[0]; const mime = mimeHeader.split(';')[0];
const fullMime = ParseMime(mime); const fullMime = ParseMime(mime);

View file

@ -34,6 +34,10 @@ export class ApiService {
return this.fetchSafeJson(type, url, { method: 'GET' }); return this.fetchSafeJson(type, url, { method: 'GET' });
} }
public async head(url: string): AsyncFailable<Headers> {
return this.fetchHead(url, { method: 'HEAD' });
}
public async post<T extends z.AnyZodObject, W extends z.AnyZodObject>( public async post<T extends z.AnyZodObject, W extends z.AnyZodObject>(
sendType: ZodDtoStatic<T>, sendType: ZodDtoStatic<T>,
receiveType: ZodDtoStatic<W>, receiveType: ZodDtoStatic<W>,
@ -118,6 +122,16 @@ export class ApiService {
} }
} }
private async fetchHead(
url: RequestInfo,
options: RequestInit
): AsyncFailable<Headers> {
const response = await this.fetch(url, options);
if (HasFailed(response)) return response;
return response.headers;
}
private async fetch( private async fetch(
url: RequestInfo, url: RequestInfo,
options: RequestInit options: RequestInit

View file

@ -7,10 +7,11 @@ export interface QOIImage {
export interface QOIWorkerIn { export interface QOIWorkerIn {
id: number; id: number;
url: string; url: string;
authorization: string;
} }
export interface QOIWorkerOut extends QOIImage { export interface QOIWorkerOut extends QOIImage {
id: number; id: number;
} }
export type QOIJob = (url: string) => Promise<QOIImage>; export type QOIJob = (url: string, authorization: string) => Promise<QOIImage>;

View file

@ -1,4 +1,5 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { KeyService } from '../services/storage/key.service';
import { QOIImage, QOIJob, QOIWorkerOut } from './qoi-worker.dto'; import { QOIImage, QOIJob, QOIWorkerOut } from './qoi-worker.dto';
@Injectable({ @Injectable({
@ -8,7 +9,7 @@ export class QoiWorkerService {
private worker: Worker | null = null; private worker: Worker | null = null;
private job: Promise<QOIJob> | null = null; private job: Promise<QOIJob> | null = null;
constructor() { constructor(private keyService: KeyService) {
if (typeof Worker !== 'undefined') { if (typeof Worker !== 'undefined') {
this.worker = new Worker(new URL('./qoi.worker', import.meta.url)); this.worker = new Worker(new URL('./qoi.worker', import.meta.url));
} else { } else {
@ -17,6 +18,8 @@ export class QoiWorkerService {
} }
public async decode(url: string): Promise<QOIImage> { public async decode(url: string): Promise<QOIImage> {
const authorization = 'Bearer ' + (this.keyService.get() ?? '');
if (this.worker && !this.job) { if (this.worker && !this.job) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const id = Date.now(); const id = Date.now();
@ -31,11 +34,11 @@ export class QoiWorkerService {
}); });
}; };
this.worker!.addEventListener('message', listener); this.worker!.addEventListener('message', listener);
this.worker!.postMessage({ id, url }); this.worker!.postMessage({ id, url, authorization });
}); });
} else if (!this.worker && this.job) { } else if (!this.worker && this.job) {
const job = await this.job; const job = await this.job;
return job(url); return job(url, authorization);
} else { } else {
throw new Error('No worker available'); throw new Error('No worker available');
} }

View file

@ -1,8 +1,15 @@
import { QOIdecodeJS } from '../util/qoi/qoi-decode'; import { QOIdecodeJS } from '../util/qoi/qoi-decode';
import { QOIImage } from './qoi-worker.dto'; import { QOIImage } from './qoi-worker.dto';
export default async function qoiDecodeJob(url: string): Promise<QOIImage> { export default async function qoiDecodeJob(
const response = await fetch(url); url: string,
authorization: string
): Promise<QOIImage> {
const response = await fetch(url, {
headers: {
Authorization: authorization,
},
});
if (!response.ok) { if (!response.ok) {
throw new Error(`Failed to fetch image: ${url}`); throw new Error(`Failed to fetch image: ${url}`);
} }

View file

@ -4,12 +4,13 @@ import { QOIWorkerIn, QOIWorkerOut } from './qoi-worker.dto';
import qoiDecodeJob from './qoi.job'; import qoiDecodeJob from './qoi.job';
addEventListener('message', async (msg) => { addEventListener('message', async (msg) => {
const { id, url } = msg.data as QOIWorkerIn; const { id, url, authorization } = msg.data as QOIWorkerIn;
if (!id || !url) {
if (!id || !url || !authorization) {
throw new Error('Invalid message'); throw new Error('Invalid message');
} }
const result = await qoiDecodeJob(url); const result = await qoiDecodeJob(url, authorization);
const returned: QOIWorkerOut = { const returned: QOIWorkerOut = {
id, id,