mirror of
https://github.com/unraid/api.git
synced 2026-01-01 22:20:05 -06:00
feat: fix missing import in ESM
This commit is contained in:
@@ -31,7 +31,7 @@ Options:
|
||||
--environment production/staging/development Set the working environment.
|
||||
--log-level ALL/TRACE/DEBUG/INFO/WARN/ERROR/FATAL/MARK/OFF Set the log level.
|
||||
|
||||
Copyright © 2022 Lime Technology, Inc.
|
||||
Copyright © 2024 Lime Technology, Inc.
|
||||
|
||||
```
|
||||
|
||||
@@ -55,4 +55,4 @@ unraid-api report -vv
|
||||
If you found this file you're likely a developer. If you'd like to know more about the API and when it's available please join [our discord](https://discord.unraid.net/).
|
||||
|
||||
## License
|
||||
Copyright 2019-2022 Lime Technology Inc. All rights reserved.
|
||||
Copyright Lime Technology Inc. All rights reserved.
|
||||
|
||||
18
api/src/core/utils/plugins/wrapper.php
Normal file
18
api/src/core/utils/plugins/wrapper.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
// Borrowed with love from https://b3z13r.wordpress.com/2011/05/16/passing-values-from-the-commandline-to-php-by-getpost-method/
|
||||
// e.g. `./wrapper.php GET /tmp/random_file.php?arg1=true&arg2=a-really-long-string` { "username": "root" }
|
||||
$method = $argv[1];
|
||||
$query_parts = explode('?', $argv[2], 2);
|
||||
$file = $query_parts[0];
|
||||
$query_params = $query_parts[1];
|
||||
$body = $argv[3];
|
||||
|
||||
// Load query_params or body into correct var
|
||||
if ($method === 'GET') {
|
||||
parse_str($query_params, $_GET);
|
||||
} else {
|
||||
parse_str($body, $_POST);
|
||||
}
|
||||
|
||||
include($file);
|
||||
?>
|
||||
12
api/src/graphql/resolvers/query/cloud/check-api.ts
Normal file
12
api/src/graphql/resolvers/query/cloud/check-api.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { logger } from '@app/core/log';
|
||||
import { getters } from '@app/store';
|
||||
import { type ApiKeyResponse } from '@app/graphql/generated/api/types';
|
||||
import { isApiKeyValid } from '@app/store/getters/index';
|
||||
|
||||
export const checkApi = async (): Promise<ApiKeyResponse> => {
|
||||
logger.trace('Cloud endpoint: Checking API');
|
||||
const valid = isApiKeyValid();
|
||||
const error = valid ? null : getters.apiKey().status;
|
||||
|
||||
return { valid, error };
|
||||
};
|
||||
100
api/src/graphql/resolvers/query/cloud/check-cloud.ts
Normal file
100
api/src/graphql/resolvers/query/cloud/check-cloud.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import { FIVE_DAYS_SECS, MOTHERSHIP_GRAPHQL_LINK, ONE_DAY_SECS } from '@app/consts';
|
||||
import { logger } from '@app/core/log';
|
||||
import { checkDNS } from '@app/graphql/resolvers/query/cloud/check-dns';
|
||||
import { checkMothershipAuthentication } from '@app/graphql/resolvers/query/cloud/check-mothership-authentication';
|
||||
import { getters, store } from '@app/store';
|
||||
import { getCloudCache, getDnsCache } from '@app/store/getters';
|
||||
import { setCloudCheck, setDNSCheck } from '@app/store/modules/cache';
|
||||
import { got } from 'got';
|
||||
import { type CloudResponse, MinigraphStatus } from '@app/graphql/generated/api/types';
|
||||
import { API_VERSION } from '@app/environment';
|
||||
|
||||
const mothershipBaseUrl = new URL(MOTHERSHIP_GRAPHQL_LINK).origin;
|
||||
|
||||
const createGotOptions = (apiVersion: string, apiKey: string) => ({
|
||||
timeout: {
|
||||
request: 5_000,
|
||||
},
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'application/json',
|
||||
'x-unraid-api-version': apiVersion,
|
||||
'x-api-key': apiKey,
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* This is mainly testing the user's network config
|
||||
* If they cannot resolve this they may have it blocked or have a routing issue
|
||||
*/
|
||||
const checkCanReachMothership = async (apiVersion: string, apiKey: string): Promise<void> => {
|
||||
const mothershipCanBeResolved = await got.head(mothershipBaseUrl, createGotOptions(apiVersion, apiKey)).then(() => true).catch(() => false);
|
||||
if (!mothershipCanBeResolved) throw new Error(`Unable to connect to ${mothershipBaseUrl}`);
|
||||
};
|
||||
|
||||
/**
|
||||
* Run a more performant cloud check with permanent DNS checking
|
||||
*/
|
||||
const fastCloudCheck = async (): Promise<CloudResponse> => {
|
||||
const result = { status: 'ok', error: null, ip: 'FAST_CHECK_NO_IP_FOUND' };
|
||||
|
||||
const cloudIp = getDnsCache()?.cloudIp ?? null;
|
||||
if (cloudIp) {
|
||||
result.ip = cloudIp;
|
||||
} else {
|
||||
try {
|
||||
result.ip = (await checkDNS()).cloudIp;
|
||||
logger.debug('DNS_CHECK_RESULT', await checkDNS());
|
||||
store.dispatch(setDNSCheck({ cloudIp: result.ip, ttl: FIVE_DAYS_SECS, error: null }));
|
||||
} catch (error: unknown) {
|
||||
logger.warn('Failed to fetch DNS, but Minigraph is connected - continuing');
|
||||
result.ip = `ERROR: ${error instanceof Error ? error.message : 'Unknown Error'}`;
|
||||
// Don't set an error since we're actually connected to the cloud
|
||||
store.dispatch(setDNSCheck({ cloudIp: result.ip, ttl: ONE_DAY_SECS, error: null }));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
export const checkCloud = async (): Promise<CloudResponse> => {
|
||||
logger.trace('Cloud endpoint: Checking mothership');
|
||||
|
||||
try {
|
||||
const config = getters.config();
|
||||
const apiVersion = API_VERSION;
|
||||
const apiKey = config.remote.apikey;
|
||||
const graphqlStatus = getters.minigraph().status;
|
||||
const result = { status: 'ok', error: null, ip: 'NO_IP_FOUND' };
|
||||
|
||||
// If minigraph is connected, skip the follow cloud checks
|
||||
if (graphqlStatus === MinigraphStatus.CONNECTED) {
|
||||
return await fastCloudCheck();
|
||||
}
|
||||
|
||||
// Check GraphQL Conneciton State, if it's broken, run these checks
|
||||
if (!apiKey) throw new Error('API key is missing');
|
||||
|
||||
const oldCheckResult = getCloudCache();
|
||||
if (oldCheckResult) {
|
||||
logger.trace('Using cached result for cloud check', oldCheckResult);
|
||||
return oldCheckResult;
|
||||
}
|
||||
|
||||
// Check DNS
|
||||
result.ip = (await checkDNS()).cloudIp;
|
||||
// Check if we can reach mothership
|
||||
await checkCanReachMothership(apiVersion, apiKey);
|
||||
|
||||
// Check auth, rate limiting, etc.
|
||||
await checkMothershipAuthentication(apiVersion, apiKey);
|
||||
|
||||
// Cache for 10 minutes
|
||||
store.dispatch(setCloudCheck(result));
|
||||
|
||||
return result;
|
||||
} catch (error: unknown) {
|
||||
if (!(error instanceof Error)) throw new Error(`Unknown Error "${error as string}"`);
|
||||
return { status: 'error', error: error.message };
|
||||
}
|
||||
};
|
||||
@@ -1,8 +1,3 @@
|
||||
/*!
|
||||
* Copyright 2022 Lime Technology Inc. All rights reserved.
|
||||
* Written by: Alexis Tyler
|
||||
*/
|
||||
|
||||
import { MOTHERSHIP_GRAPHQL_LINK } from '@app/consts';
|
||||
import { store } from '@app/store';
|
||||
import { getDnsCache } from '@app/store/getters';
|
||||
|
||||
14
api/src/graphql/resolvers/query/cloud/create-response.ts
Normal file
14
api/src/graphql/resolvers/query/cloud/create-response.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
export type Cloud = {
|
||||
error: string | null;
|
||||
apiKey: { valid: true; error: null } | { valid: false; error: string };
|
||||
minigraphql: {
|
||||
status: 'connected' | 'disconnected';
|
||||
};
|
||||
cloud: { status: 'ok'; error: null; ip: string } | { status: 'error'; error: string };
|
||||
allowedOrigins: string[];
|
||||
};
|
||||
|
||||
export const createResponse = (cloud: Omit<Cloud, 'error'>): Cloud => ({
|
||||
...cloud,
|
||||
error: cloud.apiKey.error ?? cloud.cloud.error,
|
||||
});
|
||||
@@ -22,7 +22,8 @@ import { fileExists } from '@app/core/utils/files/file-exists';
|
||||
import { encode as encodeIni } from 'ini';
|
||||
import { v7 as uuidv7 } from 'uuid';
|
||||
import { CHOKIDAR_USEPOLLING } from '@app/environment';
|
||||
import { emptyDir, statSync } from 'fs-extra';
|
||||
import { emptyDir } from 'fs-extra';
|
||||
import { statSync } from 'fs';
|
||||
import { execa } from 'execa';
|
||||
import { AppError } from '@app/core/errors/app-error';
|
||||
import { SortFn } from '@app/unraid-api/types/util';
|
||||
|
||||
Reference in New Issue
Block a user