mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-10-15 22:11:57 +00:00
109 lines
2.9 KiB
TypeScript
109 lines
2.9 KiB
TypeScript
/*
|
|
* Copyright (C) 2022 StApps
|
|
* This program is free software: you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the Free
|
|
* Software Foundation, version 3.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with
|
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
import {
|
|
AppAuthError,
|
|
Requestor,
|
|
} from '@openid/appauth';
|
|
import {
|
|
CapacitorHttp,
|
|
HttpHeaders,
|
|
HttpOptions,
|
|
} from '@capacitor/core';
|
|
|
|
type XhrSettings = Parameters<Requestor['xhr']>[0];
|
|
|
|
export class CapacitorRequestor implements Requestor {
|
|
public async xhr<T>(settings: XhrSettings): Promise<T> {
|
|
if (!settings.url) {
|
|
throw new AppAuthError('A URL must be provided.');
|
|
}
|
|
|
|
const method = (settings.method ?? 'GET').toUpperCase();
|
|
const url = new URL(settings.url);
|
|
|
|
let data: unknown;
|
|
|
|
if (settings.data) {
|
|
if (method === 'POST') {
|
|
data = settings.data;
|
|
} else {
|
|
const searchParams = new URLSearchParams(settings.data);
|
|
|
|
searchParams.forEach((value, key) => {
|
|
url.searchParams.append(key, value);
|
|
});
|
|
}
|
|
}
|
|
|
|
const options: HttpOptions = {
|
|
url: url.toString(),
|
|
method,
|
|
headers: this.getHeaders(settings.headers),
|
|
data,
|
|
};
|
|
|
|
if (settings.dataType?.toLowerCase() === 'json') {
|
|
options.responseType = 'json';
|
|
}
|
|
|
|
const response = await CapacitorHttp.request(options);
|
|
|
|
if (response.status < 200 || response.status >= 300) {
|
|
const body = this.parseBody(response.data);
|
|
|
|
/*
|
|
* Use the OAuth error code (e.g. 'invalid_grant') as message when the
|
|
* server sent one (RFC 6749, 5.2), so callers can tell a rejected
|
|
* refresh token apart from temporary failures.
|
|
*/
|
|
throw new AppAuthError(
|
|
typeof body?.error === 'string' ? body.error : `HTTP ${response.status}`,
|
|
body ?? response.data,
|
|
);
|
|
}
|
|
|
|
return response.data as T;
|
|
}
|
|
|
|
private parseBody(data: unknown): Record<string, unknown> | undefined {
|
|
if (typeof data === 'string') {
|
|
try {
|
|
data = JSON.parse(data);
|
|
} catch {
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
return data !== null && typeof data === 'object' ? (data as Record<string, unknown>) : undefined;
|
|
}
|
|
|
|
private getHeaders(headers: XhrSettings['headers']): HttpHeaders {
|
|
const result: HttpHeaders = {};
|
|
|
|
if (!headers) {
|
|
return result;
|
|
}
|
|
|
|
for (const [key, value] of Object.entries(headers)) {
|
|
if (value !== undefined && value !== null) {
|
|
result[key] = String(value);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|