Swagger update + moved API user/gpg -> gpgkey/
This commit is contained in:
1 parent
8036edec5a
commit
d6c6572989
13 files changed
+336
-286
No files matched your search
@@ -0,0 +1,295 @@
|
||||
<?php
|
||||
|
||||
namespace Core\API {
|
||||
|
||||
use Core\Objects\Context;
|
||||
|
||||
abstract class GpgKeyAPI extends \Core\API\Request {
|
||||
public function __construct(Context $context, bool $externalCall = false, array $params = array()) {
|
||||
parent::__construct($context, $externalCall, $params);
|
||||
$this->loginRequired = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace Core\API\GpgKey {
|
||||
|
||||
|
||||
use Core\API\GpgKeyAPI;
|
||||
use Core\API\Parameter\Parameter;
|
||||
use Core\API\Parameter\StringType;
|
||||
use Core\API\Template\Render;
|
||||
use Core\Driver\SQL\Condition\Compare;
|
||||
use Core\Driver\SQL\Query\Insert;
|
||||
use Core\Objects\Context;
|
||||
use Core\Objects\DatabaseEntity\GpgKey;
|
||||
use Core\Objects\DatabaseEntity\User;
|
||||
use Core\Objects\DatabaseEntity\UserToken;
|
||||
|
||||
class Import extends GpgKeyAPI {
|
||||
|
||||
public function __construct(Context $context, bool $externalCall = false) {
|
||||
parent::__construct($context, $externalCall, [
|
||||
"pubkey" => new StringType("pubkey")
|
||||
]);
|
||||
$this->loginRequired = true;
|
||||
$this->forbidMethod("GET");
|
||||
}
|
||||
|
||||
private function testKey(string $keyString) {
|
||||
$res = GpgKey::getKeyInfo($keyString);
|
||||
if (!$res["success"]) {
|
||||
return $this->createError($res["error"] ?? $res["msg"]);
|
||||
}
|
||||
|
||||
$keyData = $res["data"];
|
||||
$keyType = $keyData["type"];
|
||||
$expires = $keyData["expires"];
|
||||
|
||||
if ($keyType === "sec#") {
|
||||
return self::createError("ATTENTION! It seems like you've imported a PGP PRIVATE KEY instead of a public key.
|
||||
It is recommended to immediately revoke your private key and create a new key pair.");
|
||||
} else if ($keyType !== "pub") {
|
||||
return self::createError("Unknown key type: $keyType");
|
||||
} else if (isInPast($expires)) {
|
||||
return self::createError("It seems like the gpg key is already expired.");
|
||||
} else {
|
||||
return $keyData;
|
||||
}
|
||||
}
|
||||
|
||||
public function _execute(): bool {
|
||||
|
||||
$currentUser = $this->context->getUser();
|
||||
$gpgKey = $currentUser->getGPG();
|
||||
if ($gpgKey) {
|
||||
return $this->createError("You already added a GPG key to your account.");
|
||||
} else if (!$currentUser->getEmail()) {
|
||||
return $this->createError("You do not have an e-mail address");
|
||||
}
|
||||
|
||||
// fix key first, enforce a newline after
|
||||
$keyString = $this->getParam("pubkey");
|
||||
$keyString = preg_replace("/(-{2,})\n([^\n])/", "$1\n\n$2", $keyString);
|
||||
$keyData = $this->testKey($keyString);
|
||||
if ($keyData === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$res = GpgKey::importKey($keyString);
|
||||
if (!$res["success"]) {
|
||||
return $this->createError($res["error"]);
|
||||
}
|
||||
|
||||
$sql = $this->context->getSQL();
|
||||
$gpgKey = new GpgKey($keyData["fingerprint"], $keyData["algorithm"], $keyData["expires"]);
|
||||
if (!$gpgKey->save($sql)) {
|
||||
return $this->createError("Error creating gpg key: " . $sql->getLastError());
|
||||
}
|
||||
|
||||
$token = generateRandomString(36);
|
||||
$userToken = new UserToken($currentUser, $token, UserToken::TYPE_GPG_CONFIRM, 1);
|
||||
if (!$userToken->save($sql)) {
|
||||
return $this->createError("Error saving user token: " . $sql->getLastError());
|
||||
}
|
||||
|
||||
$validHours = 1;
|
||||
$settings = $this->context->getSettings();
|
||||
$baseUrl = $settings->getBaseUrl();
|
||||
$siteName = $settings->getSiteName();
|
||||
$req = new Render($this->context);
|
||||
$this->success = $req->execute([
|
||||
"file" => "mail/gpg_import.twig",
|
||||
"parameters" => [
|
||||
"link" => "$baseUrl/resetPassword?token=$token",
|
||||
"site_name" => $siteName,
|
||||
"base_url" => $baseUrl,
|
||||
"username" => $currentUser->getDisplayName(),
|
||||
"valid_time" => $this->formatDuration($validHours, "hour")
|
||||
]
|
||||
]);
|
||||
|
||||
$this->lastError = $req->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
$messageBody = $req->getResult()["html"];
|
||||
$sendMail = new \Core\API\Mail\Send($this->context);
|
||||
$this->success = $sendMail->execute(array(
|
||||
"to" => $currentUser->getEmail(),
|
||||
"subject" => "[$siteName] Confirm GPG-Key",
|
||||
"body" => $messageBody,
|
||||
"gpgFingerprint" => $gpgKey->getFingerprint()
|
||||
));
|
||||
|
||||
$this->lastError = $sendMail->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
$currentUser->gpgKey = $gpgKey;
|
||||
if ($currentUser->save($sql, ["gpgKey"])) {
|
||||
$this->result["gpgKey"] = $gpgKey->jsonSerialize();
|
||||
} else {
|
||||
return $this->createError("Error updating user details: " . $sql->getLastError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
public static function getDefaultACL(Insert $insert): void {
|
||||
$insert->addRow(self::getEndpoint(), [], "Allows users to import gpg keys for a secure e-mail communication", true);
|
||||
}
|
||||
}
|
||||
|
||||
class Remove extends GpgKeyAPI {
|
||||
public function __construct(Context $context, bool $externalCall = false) {
|
||||
parent::__construct($context, $externalCall, array(
|
||||
"password" => new StringType("password")
|
||||
));
|
||||
$this->loginRequired = true;
|
||||
$this->forbidMethod("GET");
|
||||
}
|
||||
|
||||
public function _execute(): bool {
|
||||
|
||||
$currentUser = $this->context->getUser();
|
||||
$gpgKey = $currentUser->getGPG();
|
||||
if (!$gpgKey) {
|
||||
return $this->createError("You have not added a GPG public key to your account yet.");
|
||||
}
|
||||
|
||||
$sql = $this->context->getSQL();
|
||||
$password = $this->getParam("password");
|
||||
if (!password_verify($password, $currentUser->password)) {
|
||||
return $this->createError("Incorrect password.");
|
||||
} else if (!$gpgKey->delete($sql)) {
|
||||
return $this->createError("Error deleting gpg key: " . $sql->getLastError());
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
public static function getDefaultACL(Insert $insert): void {
|
||||
$insert->addRow(self::getEndpoint(), [], "Allows users to unlink gpg keys from their profile", true);
|
||||
}
|
||||
}
|
||||
|
||||
class Confirm extends GpgKeyAPI {
|
||||
|
||||
public function __construct(Context $context, bool $externalCall = false) {
|
||||
parent::__construct($context, $externalCall, [
|
||||
"token" => new StringType("token", 36)
|
||||
]);
|
||||
$this->loginRequired = true;
|
||||
}
|
||||
|
||||
public function _execute(): bool {
|
||||
|
||||
$currentUser = $this->context->getUser();
|
||||
$gpgKey = $currentUser->getGPG();
|
||||
if (!$gpgKey) {
|
||||
return $this->createError("You have not added a GPG key yet.");
|
||||
} else if ($gpgKey->isConfirmed()) {
|
||||
return $this->createError("Your GPG key is already confirmed");
|
||||
}
|
||||
|
||||
$token = $this->getParam("token");
|
||||
$sql = $this->context->getSQL();
|
||||
|
||||
$userToken = UserToken::findBy(UserToken::createBuilder($sql, true)
|
||||
->whereEq("token", $token)
|
||||
->where(new Compare("valid_until", $sql->now(), ">="))
|
||||
->whereEq("user_id", $currentUser->getId())
|
||||
->whereEq("token_type", UserToken::TYPE_GPG_CONFIRM));
|
||||
|
||||
if ($userToken !== false) {
|
||||
if ($userToken === null) {
|
||||
return $this->createError("Invalid token");
|
||||
} else {
|
||||
if (!$gpgKey->confirm($sql)) {
|
||||
return $this->createError("Error updating gpg key: " . $sql->getLastError());
|
||||
}
|
||||
|
||||
$userToken->invalidate($sql);
|
||||
}
|
||||
} else {
|
||||
return $this->createError("Error validating token: " . $sql->getLastError());
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
||||
|
||||
class Download extends GpgKeyAPI {
|
||||
public function __construct(Context $context, bool $externalCall = false) {
|
||||
parent::__construct($context, $externalCall, array(
|
||||
"id" => new Parameter("id", Parameter::TYPE_INT, true, null),
|
||||
"format" => new StringType("format", 16, true, "ascii")
|
||||
));
|
||||
$this->loginRequired = true;
|
||||
$this->csrfTokenRequired = false;
|
||||
}
|
||||
|
||||
public function _execute(): bool {
|
||||
|
||||
$allowedFormats = ["json", "ascii", "gpg"];
|
||||
$format = $this->getParam("format");
|
||||
if (!in_array($format, $allowedFormats)) {
|
||||
return $this->getParam("Invalid requested format. Allowed formats: " . implode(",", $allowedFormats));
|
||||
}
|
||||
|
||||
$currentUser = $this->context->getUser();
|
||||
$userId = $this->getParam("id");
|
||||
if ($userId === null || $userId == $currentUser->getId()) {
|
||||
$gpgKey = $currentUser->getGPG();
|
||||
if (!$gpgKey) {
|
||||
return $this->createError("You did not add a gpg key yet.");
|
||||
}
|
||||
|
||||
$email = $currentUser->getEmail();
|
||||
} else {
|
||||
$sql = $this->context->getSQL();
|
||||
$user = User::find($sql, $userId, true);
|
||||
if ($user === false) {
|
||||
return $this->createError("Error fetching user details: " . $sql->getLastError());
|
||||
} else if ($user === null) {
|
||||
return $this->createError("User not found");
|
||||
}
|
||||
|
||||
$email = $user->getEmail();
|
||||
$gpgKey = $user->getGPG();
|
||||
if (!$gpgKey || !$gpgKey->isConfirmed()) {
|
||||
return $this->createError("This user has not added a gpg key yet or has not confirmed it yet.");
|
||||
}
|
||||
}
|
||||
|
||||
$res = GpgKey::export($gpgKey->getFingerprint(), $format !== "gpg");
|
||||
if (!$res["success"]) {
|
||||
return $this->createError($res["error"]);
|
||||
}
|
||||
|
||||
$key = $res["data"];
|
||||
if ($format === "json") {
|
||||
$this->result["key"] = $key;
|
||||
return true;
|
||||
} else if ($format === "ascii") {
|
||||
$contentType = "application/pgp-keys";
|
||||
$ext = "asc";
|
||||
} else if ($format === "gpg") {
|
||||
$contentType = "application/octet-stream";
|
||||
$ext = "gpg";
|
||||
} else {
|
||||
die("Invalid format");
|
||||
}
|
||||
|
||||
$fileName = "$email.$ext";
|
||||
header("Content-Type: $contentType");
|
||||
header("Content-Length: " . strlen($key));
|
||||
header("Content-Disposition: attachment; filename=\"$fileName\"");
|
||||
die($key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -604,4 +604,12 @@ abstract class Request {
|
||||
$currentUser = $this->context->getUser();
|
||||
return $currentUser ? "userId='" . $currentUser->getId() . "'" : "SYSTEM";
|
||||
}
|
||||
|
||||
protected function formatDuration(int $count, string $string): string {
|
||||
if ($count === 1) {
|
||||
return $string;
|
||||
} else {
|
||||
return "the next $count {$string}s";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,6 +63,9 @@ class Swagger extends Request {
|
||||
|
||||
$definitions = [];
|
||||
$paths = [];
|
||||
$tags = [];
|
||||
|
||||
// TODO: consumes and produces is not always the same, but it's okay for now
|
||||
foreach (self::getApiEndpoints() as $endpoint => $apiClass) {
|
||||
$body = null;
|
||||
$requiredProperties = [];
|
||||
@@ -72,6 +75,17 @@ class Swagger extends Request {
|
||||
continue;
|
||||
}
|
||||
|
||||
$tag = null;
|
||||
if ($apiClass->getParentClass()->getName() !== Request::class) {
|
||||
$parentClass = $apiClass->getParentClass()->getShortName();
|
||||
if (endsWith($parentClass, "API")) {
|
||||
$tag = substr($parentClass, 0, strlen($parentClass) - 3);
|
||||
if (!in_array($tag, $tags)) {
|
||||
$tags[] = $tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$parameters = $apiObject->getDefaultParams();
|
||||
if (!empty($parameters)) {
|
||||
$body = [];
|
||||
@@ -107,6 +121,7 @@ class Swagger extends Request {
|
||||
|
||||
$endPointDefinition = [
|
||||
"post" => [
|
||||
"tags" => [$tag ?? "Global"],
|
||||
"produces" => ["application/json"],
|
||||
"responses" => [
|
||||
"200" => ["description" => "OK!"],
|
||||
@@ -123,7 +138,7 @@ class Swagger extends Request {
|
||||
}
|
||||
|
||||
if ($body) {
|
||||
$endPointDefinition["post"]["consumes"] = ["application/json"];
|
||||
$endPointDefinition["post"]["consumes"] = ["application/json", "application/x-www-form-urlencoded"];
|
||||
$endPointDefinition["post"]["parameters"] = [[
|
||||
"in" => "body",
|
||||
"name" => "body",
|
||||
@@ -149,6 +164,7 @@ class Swagger extends Request {
|
||||
"host" => $domain,
|
||||
"basePath" => "/api",
|
||||
"schemes" => ["$protocol"],
|
||||
"tags" => $tags,
|
||||
"paths" => $paths,
|
||||
"definitions" => $definitions
|
||||
];
|
||||
|
||||
@@ -98,14 +98,6 @@ namespace Core\API {
|
||||
return password_hash($password, PASSWORD_BCRYPT);
|
||||
}
|
||||
|
||||
protected function formatDuration(int $count, string $string): string {
|
||||
if ($count === 1) {
|
||||
return $string;
|
||||
} else {
|
||||
return "the next $count {$string}s";
|
||||
}
|
||||
}
|
||||
|
||||
protected function checkToken(string $token) : UserToken|bool {
|
||||
$sql = $this->context->getSQL();
|
||||
$userToken = UserToken::findBy(UserToken::createBuilder($sql, true)
|
||||
@@ -1244,270 +1236,6 @@ namespace Core\API\User {
|
||||
}
|
||||
}
|
||||
|
||||
class ImportGPG extends UserAPI {
|
||||
|
||||
public function __construct(Context $context, bool $externalCall = false) {
|
||||
parent::__construct($context, $externalCall, [
|
||||
"pubkey" => new StringType("pubkey")
|
||||
]);
|
||||
$this->loginRequired = true;
|
||||
$this->forbidMethod("GET");
|
||||
}
|
||||
|
||||
private function testKey(string $keyString) {
|
||||
$res = GpgKey::getKeyInfo($keyString);
|
||||
if (!$res["success"]) {
|
||||
return $this->createError($res["error"] ?? $res["msg"]);
|
||||
}
|
||||
|
||||
$keyData = $res["data"];
|
||||
$keyType = $keyData["type"];
|
||||
$expires = $keyData["expires"];
|
||||
|
||||
if ($keyType === "sec#") {
|
||||
return self::createError("ATTENTION! It seems like you've imported a PGP PRIVATE KEY instead of a public key.
|
||||
It is recommended to immediately revoke your private key and create a new key pair.");
|
||||
} else if ($keyType !== "pub") {
|
||||
return self::createError("Unknown key type: $keyType");
|
||||
} else if (isInPast($expires)) {
|
||||
return self::createError("It seems like the gpg key is already expired.");
|
||||
} else {
|
||||
return $keyData;
|
||||
}
|
||||
}
|
||||
|
||||
public function _execute(): bool {
|
||||
|
||||
$currentUser = $this->context->getUser();
|
||||
$gpgKey = $currentUser->getGPG();
|
||||
if ($gpgKey) {
|
||||
return $this->createError("You already added a GPG key to your account.");
|
||||
} else if (!$currentUser->getEmail()) {
|
||||
return $this->createError("You do not have an e-mail address");
|
||||
}
|
||||
|
||||
// fix key first, enforce a newline after
|
||||
$keyString = $this->getParam("pubkey");
|
||||
$keyString = preg_replace("/(-{2,})\n([^\n])/", "$1\n\n$2", $keyString);
|
||||
$keyData = $this->testKey($keyString);
|
||||
if ($keyData === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$res = GpgKey::importKey($keyString);
|
||||
if (!$res["success"]) {
|
||||
return $this->createError($res["error"]);
|
||||
}
|
||||
|
||||
$sql = $this->context->getSQL();
|
||||
$gpgKey = new GpgKey($keyData["fingerprint"], $keyData["algorithm"], $keyData["expires"]);
|
||||
if (!$gpgKey->save($sql)) {
|
||||
return $this->createError("Error creating gpg key: " . $sql->getLastError());
|
||||
}
|
||||
|
||||
$token = generateRandomString(36);
|
||||
$userToken = new UserToken($currentUser, $token, UserToken::TYPE_GPG_CONFIRM, 1);
|
||||
if (!$userToken->save($sql)) {
|
||||
return $this->createError("Error saving user token: " . $sql->getLastError());
|
||||
}
|
||||
|
||||
$validHours = 1;
|
||||
$settings = $this->context->getSettings();
|
||||
$baseUrl = $settings->getBaseUrl();
|
||||
$siteName = $settings->getSiteName();
|
||||
$req = new Render($this->context);
|
||||
$this->success = $req->execute([
|
||||
"file" => "mail/gpg_import.twig",
|
||||
"parameters" => [
|
||||
"link" => "$baseUrl/resetPassword?token=$token",
|
||||
"site_name" => $siteName,
|
||||
"base_url" => $baseUrl,
|
||||
"username" => $currentUser->getDisplayName(),
|
||||
"valid_time" => $this->formatDuration($validHours, "hour")
|
||||
]
|
||||
]);
|
||||
|
||||
$this->lastError = $req->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
$messageBody = $req->getResult()["html"];
|
||||
$sendMail = new \Core\API\Mail\Send($this->context);
|
||||
$this->success = $sendMail->execute(array(
|
||||
"to" => $currentUser->getEmail(),
|
||||
"subject" => "[$siteName] Confirm GPG-Key",
|
||||
"body" => $messageBody,
|
||||
"gpgFingerprint" => $gpgKey->getFingerprint()
|
||||
));
|
||||
|
||||
$this->lastError = $sendMail->getLastError();
|
||||
|
||||
if ($this->success) {
|
||||
$currentUser->gpgKey = $gpgKey;
|
||||
if ($currentUser->save($sql, ["gpgKey"])) {
|
||||
$this->result["gpgKey"] = $gpgKey->jsonSerialize();
|
||||
} else {
|
||||
return $this->createError("Error updating user details: " . $sql->getLastError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
public static function getDefaultACL(Insert $insert): void {
|
||||
$insert->addRow(self::getEndpoint(), [], "Allows users to import gpg keys for a secure e-mail communication", true);
|
||||
}
|
||||
}
|
||||
|
||||
class RemoveGPG extends UserAPI {
|
||||
public function __construct(Context $context, bool $externalCall = false) {
|
||||
parent::__construct($context, $externalCall, array(
|
||||
"password" => new StringType("password")
|
||||
));
|
||||
$this->loginRequired = true;
|
||||
$this->forbidMethod("GET");
|
||||
}
|
||||
|
||||
public function _execute(): bool {
|
||||
|
||||
$currentUser = $this->context->getUser();
|
||||
$gpgKey = $currentUser->getGPG();
|
||||
if (!$gpgKey) {
|
||||
return $this->createError("You have not added a GPG public key to your account yet.");
|
||||
}
|
||||
|
||||
$sql = $this->context->getSQL();
|
||||
$password = $this->getParam("password");
|
||||
if (!password_verify($password, $currentUser->password)) {
|
||||
return $this->createError("Incorrect password.");
|
||||
} else if (!$gpgKey->delete($sql)) {
|
||||
return $this->createError("Error deleting gpg key: " . $sql->getLastError());
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
public static function getDefaultACL(Insert $insert): void {
|
||||
$insert->addRow(self::getEndpoint(), [], "Allows users to unlink gpg keys from their profile", true);
|
||||
}
|
||||
}
|
||||
|
||||
class ConfirmGPG extends UserAPI {
|
||||
|
||||
public function __construct(Context $context, bool $externalCall = false) {
|
||||
parent::__construct($context, $externalCall, [
|
||||
"token" => new StringType("token", 36)
|
||||
]);
|
||||
$this->loginRequired = true;
|
||||
}
|
||||
|
||||
public function _execute(): bool {
|
||||
|
||||
$currentUser = $this->context->getUser();
|
||||
$gpgKey = $currentUser->getGPG();
|
||||
if (!$gpgKey) {
|
||||
return $this->createError("You have not added a GPG key yet.");
|
||||
} else if ($gpgKey->isConfirmed()) {
|
||||
return $this->createError("Your GPG key is already confirmed");
|
||||
}
|
||||
|
||||
$token = $this->getParam("token");
|
||||
$sql = $this->context->getSQL();
|
||||
|
||||
$userToken = UserToken::findBy(UserToken::createBuilder($sql, true)
|
||||
->whereEq("token", $token)
|
||||
->where(new Compare("valid_until", $sql->now(), ">="))
|
||||
->whereEq("user_id", $currentUser->getId())
|
||||
->whereEq("token_type", UserToken::TYPE_GPG_CONFIRM));
|
||||
|
||||
if ($userToken !== false) {
|
||||
if ($userToken === null) {
|
||||
return $this->createError("Invalid token");
|
||||
} else {
|
||||
if (!$gpgKey->confirm($sql)) {
|
||||
return $this->createError("Error updating gpg key: " . $sql->getLastError());
|
||||
}
|
||||
|
||||
$userToken->invalidate($sql);
|
||||
}
|
||||
} else {
|
||||
return $this->createError("Error validating token: " . $sql->getLastError());
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
}
|
||||
|
||||
class DownloadGPG extends UserAPI {
|
||||
public function __construct(Context $context, bool $externalCall = false) {
|
||||
parent::__construct($context, $externalCall, array(
|
||||
"id" => new Parameter("id", Parameter::TYPE_INT, true, null),
|
||||
"format" => new StringType("format", 16, true, "ascii")
|
||||
));
|
||||
$this->loginRequired = true;
|
||||
$this->csrfTokenRequired = false;
|
||||
}
|
||||
|
||||
public function _execute(): bool {
|
||||
|
||||
$allowedFormats = ["json", "ascii", "gpg"];
|
||||
$format = $this->getParam("format");
|
||||
if (!in_array($format, $allowedFormats)) {
|
||||
return $this->getParam("Invalid requested format. Allowed formats: " . implode(",", $allowedFormats));
|
||||
}
|
||||
|
||||
$currentUser = $this->context->getUser();
|
||||
$userId = $this->getParam("id");
|
||||
if ($userId === null || $userId == $currentUser->getId()) {
|
||||
$gpgKey = $currentUser->getGPG();
|
||||
if (!$gpgKey) {
|
||||
return $this->createError("You did not add a gpg key yet.");
|
||||
}
|
||||
|
||||
$email = $currentUser->getEmail();
|
||||
} else {
|
||||
$sql = $this->context->getSQL();
|
||||
$user = User::find($sql, $userId, true);
|
||||
if ($user === false) {
|
||||
return $this->createError("Error fetching user details: " . $sql->getLastError());
|
||||
} else if ($user === null) {
|
||||
return $this->createError("User not found");
|
||||
}
|
||||
|
||||
$email = $user->getEmail();
|
||||
$gpgKey = $user->getGPG();
|
||||
if (!$gpgKey || !$gpgKey->isConfirmed()) {
|
||||
return $this->createError("This user has not added a gpg key yet or has not confirmed it yet.");
|
||||
}
|
||||
}
|
||||
|
||||
$res = GpgKey::export($gpgKey->getFingerprint(), $format !== "gpg");
|
||||
if (!$res["success"]) {
|
||||
return $this->createError($res["error"]);
|
||||
}
|
||||
|
||||
$key = $res["data"];
|
||||
if ($format === "json") {
|
||||
$this->result["key"] = $key;
|
||||
return true;
|
||||
} else if ($format === "ascii") {
|
||||
$contentType = "application/pgp-keys";
|
||||
$ext = "asc";
|
||||
} else if ($format === "gpg") {
|
||||
$contentType = "application/octet-stream";
|
||||
$ext = "gpg";
|
||||
} else {
|
||||
die("Invalid format");
|
||||
}
|
||||
|
||||
$fileName = "$email.$ext";
|
||||
header("Content-Type: $contentType");
|
||||
header("Content-Length: " . strlen($key));
|
||||
header("Content-Disposition: attachment; filename=\"$fileName\"");
|
||||
die($key);
|
||||
}
|
||||
}
|
||||
|
||||
class UploadPicture extends UserAPI {
|
||||
public function __construct(Context $context, bool $externalCall = false) {
|
||||
// TODO: we should optimize the process here, we need an offset and size parameter to get a quadratic crop of the uploaded image
|
||||
|
||||
@@ -45,6 +45,7 @@ class Security extends Document {
|
||||
"# This project is based on the open-source framework hosted on https://github.com/rhergenreder/web-base",
|
||||
"# Any non site-specific issues can be reported via the github security reporting feature:",
|
||||
"# https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability",
|
||||
"# or by contacting me directly: mail(at)romanh(dot)de",
|
||||
"",
|
||||
"Canonical: $baseUrl/.well-known/security.txt",
|
||||
"Preferred-Languages: $languageCodes",
|
||||
|
||||
@@ -62,7 +62,7 @@ class ApiRoute extends Route {
|
||||
http_response_code(400);
|
||||
$response = createError("Invalid Method");
|
||||
} else {
|
||||
$request = $apiClass->newInstanceArgs(array($router->getContext(), true));
|
||||
$request = $apiClass->newInstanceArgs([$router->getContext(), true]);
|
||||
$success = $request->execute();
|
||||
$response = $request->getResult();
|
||||
$response["success"] = $success;
|
||||
@@ -74,6 +74,7 @@ class ApiRoute extends Route {
|
||||
}
|
||||
} catch (ReflectionException $e) {
|
||||
http_response_code(500);
|
||||
$router->getLogger()->error("Error instantiating class: $e");
|
||||
$response = createError("Error instantiating class: $e");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,6 +83,7 @@ class DocumentRoute extends Route {
|
||||
|
||||
try {
|
||||
if (!$this->loadClass()) {
|
||||
$router->getLogger()->warning("Error loading class: $className");
|
||||
return $router->returnStatusCode(500, [ "message" => "Error loading class: $className"]);
|
||||
}
|
||||
|
||||
@@ -90,6 +91,7 @@ class DocumentRoute extends Route {
|
||||
$document = $this->reflectionClass->newInstanceArgs($args);
|
||||
return $document->load($params);
|
||||
} catch (\ReflectionException $e) {
|
||||
$router->getLogger()->error("Error loading class: $className: " . $e->getMessage());
|
||||
return $router->returnStatusCode(500, [ "message" => "Error loading class $className: " . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
let token = jsCore.getParameter("token");
|
||||
let confirmStatus = $("#confirm-status");
|
||||
if (token) {
|
||||
jsCore.apiCall("/user/confirmGPG", { token: token, csrfToken: '{{ user.session.csrfToken }}' }, (res) => {
|
||||
jsCore.apiCall("/gpgKey/confirm", { token: token, csrfToken: '{{ user.session.csrfToken }}' }, (res) => {
|
||||
confirmStatus.removeClass("alert-info");
|
||||
if (!res.success) {
|
||||
confirmStatus.addClass("alert-danger");
|
||||
|
||||
+1
-2
@@ -1,4 +1,3 @@
|
||||
.swagger-ui{color:#3b4151;
|
||||
/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */font-family:sans-serif}.swagger-ui html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;line-height:1.15}.swagger-ui body{margin:0}.swagger-ui article,.swagger-ui aside,.swagger-ui footer,.swagger-ui header,.swagger-ui nav,.swagger-ui section{display:block}.swagger-ui h1{font-size:2em;margin:.67em 0}.swagger-ui figcaption,.swagger-ui figure,.swagger-ui main{display:block}.swagger-ui figure{margin:1em 40px}.swagger-ui hr{box-sizing:content-box;height:0;overflow:visible}.swagger-ui pre{font-family:monospace,monospace;font-size:1em}.swagger-ui a{-webkit-text-decoration-skip:objects;background-color:transparent}.swagger-ui abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.swagger-ui b,.swagger-ui strong{font-weight:inherit;font-weight:bolder}.swagger-ui code,.swagger-ui kbd,.swagger-ui samp{font-family:monospace,monospace;font-size:1em}.swagger-ui dfn{font-style:italic}.swagger-ui mark{background-color:#ff0;color:#000}.swagger-ui small{font-size:80%}.swagger-ui sub,.swagger-ui sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}.swagger-ui sub{bottom:-.25em}.swagger-ui sup{top:-.5em}.swagger-ui audio,.swagger-ui video{display:inline-block}.swagger-ui audio:not([controls]){display:none;height:0}.swagger-ui img{border-style:none}.swagger-ui svg:not(:root){overflow:hidden}.swagger-ui button,.swagger-ui input,.swagger-ui optgroup,.swagger-ui select,.swagger-ui textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}.swagger-ui button,.swagger-ui input{overflow:visible}.swagger-ui button,.swagger-ui select{text-transform:none}.swagger-ui [type=reset],.swagger-ui [type=submit],.swagger-ui button,.swagger-ui html [type=button]{-webkit-appearance:button}.swagger-ui [type=button]::-moz-focus-inner,.swagger-ui [type=reset]::-moz-focus-inner,.swagger-ui [type=submit]::-moz-focus-inner,.swagger-ui button::-moz-focus-inner{border-style:none;padding:0}.swagger-ui [type=button]:-moz-focusring,.swagger-ui [type=reset]:-moz-focusring,.swagger-ui [type=submit]:-moz-focusring,.swagger-ui button:-moz-focusring{outline:1px dotted ButtonText}.swagger-ui fieldset{padding:.35em .75em .625em}.swagger-ui legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}.swagger-ui progress{display:inline-block;vertical-align:baseline}.swagger-ui textarea{overflow:auto}.swagger-ui [type=checkbox],.swagger-ui [type=radio]{box-sizing:border-box;padding:0}.swagger-ui [type=number]::-webkit-inner-spin-button,.swagger-ui [type=number]::-webkit-outer-spin-button{height:auto}.swagger-ui [type=search]{-webkit-appearance:textfield;outline-offset:-2px}.swagger-ui [type=search]::-webkit-search-cancel-button,.swagger-ui [type=search]::-webkit-search-decoration{-webkit-appearance:none}.swagger-ui ::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}.swagger-ui details,.swagger-ui menu{display:block}.swagger-ui summary{display:list-item}.swagger-ui canvas{display:inline-block}.swagger-ui [hidden],.swagger-ui template{display:none}.swagger-ui .debug *{outline:1px solid gold}.swagger-ui .debug-white *{outline:1px solid #fff}.swagger-ui .debug-black *{outline:1px solid #000}.swagger-ui .debug-grid{background:transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTRDOTY4N0U2N0VFMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTRDOTY4N0Q2N0VFMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3NjY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3NzY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PsBS+GMAAAAjSURBVHjaYvz//z8DLsD4gcGXiYEAGBIKGBne//fFpwAgwAB98AaF2pjlUQAAAABJRU5ErkJggg==) repeat 0 0}.swagger-ui .debug-grid-16{background:transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eLine truncated
|
||||
.swagger-ui{color:#3b4151;font-family:sans-serif/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */}.swagger-ui html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}.swagger-ui body{margin:0}.swagger-ui article,.swagger-ui aside,.swagger-ui footer,.swagger-ui header,.swagger-ui nav,.swagger-ui section{display:block}.swagger-ui h1{font-size:2em;margin:.67em 0}.swagger-ui figcaption,.swagger-ui figure,.swagger-ui main{display:block}.swagger-ui figure{margin:1em 40px}.swagger-ui hr{box-sizing:content-box;height:0;overflow:visible}.swagger-ui pre{font-family:monospace,monospace;font-size:1em}.swagger-ui a{background-color:transparent;-webkit-text-decoration-skip:objects}.swagger-ui abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.swagger-ui b,.swagger-ui strong{font-weight:inherit;font-weight:bolder}.swagger-ui code,.swagger-ui kbd,.swagger-ui samp{font-family:monospace,monospace;font-size:1em}.swagger-ui dfn{font-style:italic}.swagger-ui mark{background-color:#ff0;color:#000}.swagger-ui small{font-size:80%}.swagger-ui sub,.swagger-ui sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}.swagger-ui sub{bottom:-.25em}.swagger-ui sup{top:-.5em}.swagger-ui audio,.swagger-ui video{display:inline-block}.swagger-ui audio:not([controls]){display:none;height:0}.swagger-ui img{border-style:none}.swagger-ui svg:not(:root){overflow:hidden}.swagger-ui button,.swagger-ui input,.swagger-ui optgroup,.swagger-ui select,.swagger-ui textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}.swagger-ui button,.swagger-ui input{overflow:visible}.swagger-ui button,.swagger-ui select{text-transform:none}.swagger-ui [type=reset],.swagger-ui [type=submit],.swagger-ui button,.swagger-ui html [type=button]{-webkit-appearance:button}.swagger-ui [type=button]::-moz-focus-inner,.swagger-ui [type=reset]::-moz-focus-inner,.swagger-ui [type=submit]::-moz-focus-inner,.swagger-ui button::-moz-focus-inner{border-style:none;padding:0}.swagger-ui [type=button]:-moz-focusring,.swagger-ui [type=reset]:-moz-focusring,.swagger-ui [type=submit]:-moz-focusring,.swagger-ui button:-moz-focusring{outline:1px dotted ButtonText}.swagger-ui fieldset{padding:.35em .75em .625em}.swagger-ui legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}.swagger-ui progress{display:inline-block;vertical-align:baseline}.swagger-ui textarea{overflow:auto}.swagger-ui [type=checkbox],.swagger-ui [type=radio]{box-sizing:border-box;padding:0}.swagger-ui [type=number]::-webkit-inner-spin-button,.swagger-ui [type=number]::-webkit-outer-spin-button{height:auto}.swagger-ui [type=search]{-webkit-appearance:textfield;outline-offset:-2px}.swagger-ui [type=search]::-webkit-search-cancel-button,.swagger-ui [type=search]::-webkit-search-decoration{-webkit-appearance:none}.swagger-ui ::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}.swagger-ui details,.swagger-ui menu{display:block}.swagger-ui summary{display:list-item}.swagger-ui canvas{display:inline-block}.swagger-ui [hidden],.swagger-ui template{display:none}.swagger-ui .debug *{outline:1px solid gold}.swagger-ui .debug-white *{outline:1px solid #fff}.swagger-ui .debug-black *{outline:1px solid #000}.swagger-ui .debug-grid{background:transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTRDOTY4N0U2N0VFMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTRDOTY4N0Q2N0VFMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3NjY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3NzY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PsBS+GMAAAAjSURBVHjaYvz//z8DLsD4gcGXiYEAGBIKGBne//fFpwAgwAB98AaF2pjlUQAAAABJRU5ErkJggg==) repeat 0 0}.swagger-ui .debug-grid-16{background:transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+ILine truncated
|
||||
|
||||
/*# sourceMappingURL=swagger-ui.css.map*/
|
||||
@@ -1,3 +1,3 @@
|
||||
/*! For license information please see swagger-ui-bundle.js.LICENSE.txt */
|
||||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.SwaggerUIBundle=t():e.SwaggerUIBundle=t()}(this,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist",n(n.s=481)}([function(e,t,n){"use strict";e.exports=n(555)},function(e,t,n){e.exports=function(){"use strict";var e=Array.prototype.slice;function t(e,t){t&&(e.prototype=Object.create(t.prototype)),e.prototype.constructor=e}function n(e){return i(e)?e:J(e)}function r(e){return u(e)?e:K(e)}function o(e){return s(e)?e:Y(e)}function a(e){return i(e)&&!c(e)?e:G(e)}function i(e){return!(!e||!e[f])}function u(e){return!(!e||!e[p])}function s(e){return!(!e||!e[h])}function c(e){return u(e)||s(e)}function l(e){return!(!e||!e[d])}t(r,n),t(o,n),t(a,n),n.isIterable=i,n.isKeyed=u,n.isIndexed=s,n.isAssociative=c,n.isOrdered=l,n.Keyed=r,n.Indexed=o,n.Set=a;var f="@@__IMMUTABLE_ITERABLE__@@",p="@@__IMMUTABLE_KEYED__@@",h="@@__IMMUTABLE_INDEXED__@@",d="@@__IMMUTABLE_ORDERED__@@",m="delete",v=5,g=1<<v,y=g-1,b={},w={value:!1},x={value:!1};function _(e){return e.value=!1,e}function E(e){e&&(e.value=!0)}function S(){}function k(e,t){t=t||0;for(var n=Math.max(0,e.length-t),r=new Array(n),o=0;o<n;o++)r[o]=e[o+t];return r}function A(e){return void 0===e.size&&(e.size=e.__iterate(C)),e.size}function O(e,t){if("number"!=typeof t){var n=t>>>0;if(""+n!==t||4294967295===n)return NaN;t=n}return t<0?A(e)+t:t}function C(){return!0}function j(e,t,n){return(0===e||void 0!==n&&e<=-n)&&(void 0===t||void 0!==n&&t>=n)}function T(e,t){return N(e,t,0)}function I(e,t){return N(e,t,t)}function N(e,t,n){return void 0===e?n:e<0?Math.max(0,t+e):void 0===t?e:Math.min(t,e)}var P=0,M=1,R=2,D="function"==typeof Symbol&&Symbol.iterator,L="@@iterator",B=D||L;function F(e){this.next=e}function z(e,t,n,r){var o=0===e?t:1===e?n:[t,n];return r?r.value=o:r={value:o,done:!1},r}function q(){return{value:void 0,done:!0}}function U(e){return!!H(e)}function V(e){return e&&"function"==typeof e.next}function W(e){var t=H(e);return t&&t.call(e)}function H(e){var t=e&&(D&&e[D]||e[L]);if("function"==typeof t)return t}function $(e){return e&&"number"==typeof e.length}function J(e){return null==e?ie():i(e)?e.toSeq():ce(e)}function K(e){return null==e?ie().toKeyedSeq():i(e)?u(e)?e.toSeq():e.fromEntrySeq():ue(e)}function Y(e){return null==e?ie():i(e)?u(e)?e.entrySeq():e.toIndexedSeq():se(e)}function G(e){return(null==e?ie():i(e)?u(e)?e.entrySeq():e:se(e)).toSetSeq()}F.prototype.toString=function(){return"[Iterator]"},F.KEYS=P,F.VALUES=M,F.ENTRIES=R,F.prototype.inspect=F.prototype.toSource=function(){return this.toString()},F.prototype[B]=function(){return this},t(J,n),J.of=function(){return J(arguments)},J.prototype.toSeq=function(){return this},J.prototype.toString=function(){return this.__toString("Seq {","}")},J.prototype.cacheResult=function(){return!this._cache&&this.__iterateUncached&&(this._cache=this.entrySeq().toArray(),this.size=this._cache.length),this},J.prototype.__iterate=function(e,t){return fe(this,e,t,!0)},J.prototype.__iterator=function(e,t){return pe(this,e,t,!0)},t(K,J),K.prototype.toKeyedSeq=function(){return this},t(Y,J),Y.of=function(){return Y(arguments)},Y.prototype.toIndexedSeq=function(){return this},Y.prototype.toString=function(){return this.__toString("Seq [","]")},Y.prototype.__iterate=function(e,t){return fe(this,e,t,!1)},Y.prototype.__iterator=function(e,t){return pe(this,e,t,!1)},t(G,J),G.of=function(){return G(arguments)},G.prototype.toSetSeq=function(){return this},J.isSeq=ae,J.Keyed=K,J.Set=G,J.Indexed=Y;var Q,Z,X,ee="@@__IMMUTABLE_SEQ__@@";function te(e){this._array=e,this.size=e.length}function ne(e){var t=Object.keys(e);this._object=e,this._keys=t,this.size=t.length}function re(e){this._iterable=e,this.size=e.length||e.size}function oe(e){this._iterator=e,this._iteratorCache=[]}function ae(e){return!(!e||!e[ee])}function ie(){return Q||(Q=new te([]))}function ue(e){var t=Array.isArray(e)?new te(e).fromEntrySeq():V(e)?new oe(e).fromEntrySeq():U(e)?new re(e).fromEntrySeq():"object"==typeof e?new ne(e):void 0;if(Line truncated
|
||||
!function webpackUniversalModuleDefinition(s,i){"object"==typeof exports&&"object"==typeof module?module.exports=i():"function"==typeof define&&define.amd?define([],i):"object"==typeof exports?exports.SwaggerUIBundle=i():s.SwaggerUIBundle=i()}(this,(()=>(()=>{var s,i,u={69119:(s,i)=>{"use strict";Object.defineProperty(i,"__esModule",{value:!0}),i.BLANK_URL=i.relativeFirstCharacters=i.urlSchemeRegex=i.ctrlCharactersRegex=i.htmlCtrlEntityRegex=i.htmlEntitiesRegex=i.invalidProtocolRegex=void 0,i.invalidProtocolRegex=/^([^\w]*)(javascript|data|vbscript)/im,i.htmlEntitiesRegex=/&#(\w+)(^\w|;)?/g,i.htmlCtrlEntityRegex=/&(newline|tab);/gi,i.ctrlCharactersRegex=/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim,i.urlSchemeRegex=/^.+(:|:)/gim,i.relativeFirstCharacters=[".","/"],i.BLANK_URL="about:blank"},16750:(s,i,u)=>{"use strict";i.J=void 0;var _=u(69119);i.J=function sanitizeUrl(s){if(!s)return _.BLANK_URL;var i,u,w=s;do{i=(w=(u=w,u.replace(_.ctrlCharactersRegex,"").replace(_.htmlEntitiesRegex,(function(s,i){return String.fromCharCode(i)}))).replace(_.htmlCtrlEntityRegex,"").replace(_.ctrlCharactersRegex,"").trim()).match(_.ctrlCharactersRegex)||w.match(_.htmlEntitiesRegex)||w.match(_.htmlCtrlEntityRegex)}while(i&&i.length>0);var x=w;if(!x)return _.BLANK_URL;if(function isRelativeUrlWithoutProtocol(s){return _.relativeFirstCharacters.indexOf(s[0])>-1}(x))return x;var j=x.match(_.urlSchemeRegex);if(!j)return x;var P=j[0];return _.invalidProtocolRegex.test(P)?_.BLANK_URL:x}},67526:(s,i)=>{"use strict";i.byteLength=function byteLength(s){var i=getLens(s),u=i[0],_=i[1];return 3*(u+_)/4-_},i.toByteArray=function toByteArray(s){var i,u,x=getLens(s),j=x[0],P=x[1],B=new w(function _byteLength(s,i,u){return 3*(i+u)/4-u}(0,j,P)),$=0,U=P>0?j-4:j;for(u=0;u<U;u+=4)i=_[s.charCodeAt(u)]<<18|_[s.charCodeAt(u+1)]<<12|_[s.charCodeAt(u+2)]<<6|_[s.charCodeAt(u+3)],B[$++]=i>>16&255,B[$++]=i>>8&255,B[$++]=255&i;2===P&&(i=_[s.charCodeAt(u)]<<2|_[s.charCodeAt(u+1)]>>4,B[$++]=255&i);1===P&&(i=_[s.charCodeAt(u)]<<10|_[s.charCodeAt(u+1)]<<4|_[s.charCodeAt(u+2)]>>2,B[$++]=i>>8&255,B[$++]=255&i);return B},i.fromByteArray=function fromByteArray(s){for(var i,_=s.length,w=_%3,x=[],j=16383,P=0,B=_-w;P<B;P+=j)x.push(encodeChunk(s,P,P+j>B?B:P+j));1===w?(i=s[_-1],x.push(u[i>>2]+u[i<<4&63]+"==")):2===w&&(i=(s[_-2]<<8)+s[_-1],x.push(u[i>>10]+u[i>>4&63]+u[i<<2&63]+"="));return x.join("")};for(var u=[],_=[],w="undefined"!=typeof Uint8Array?Uint8Array:Array,x="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",j=0;j<64;++j)u[j]=x[j],_[x.charCodeAt(j)]=j;function getLens(s){var i=s.length;if(i%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var u=s.indexOf("=");return-1===u&&(u=i),[u,u===i?0:4-u%4]}function encodeChunk(s,i,_){for(var w,x,j=[],P=i;P<_;P+=3)w=(s[P]<<16&16711680)+(s[P+1]<<8&65280)+(255&s[P+2]),j.push(u[(x=w)>>18&63]+u[x>>12&63]+u[x>>6&63]+u[63&x]);return j.join("")}_["-".charCodeAt(0)]=62,_["_".charCodeAt(0)]=63},48287:(s,i,u)=>{"use strict";const _=u(67526),w=u(251),x="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):null;i.Buffer=Buffer,i.SlowBuffer=function SlowBuffer(s){+s!=s&&(s=0);return Buffer.alloc(+s)},i.INSPECT_MAX_BYTES=50;const j=2147483647;function createBuffer(s){if(s>j)throw new RangeError('The value "'+s+'" is invalid for option "size"');const i=new Uint8Array(s);return Object.setPrototypeOf(i,Buffer.prototype),i}function Buffer(s,i,u){if("number"==typeof s){if("string"==typeof i)throw new TypeError('The "string" argument must be of type string. Received type number');return allocUnsafe(s)}return from(s,i,u)}function from(s,i,u){if("string"==typeof s)return function fromString(s,i){"string"==typeof i&&""!==i||(i="utf8");if(!Buffer.isEncoding(i))throw new TypeError("Unknown encoding: "+i);const u=0|byteLength(s,i);let _=createBuffer(u);const w=_.write(s,i);w!==u&&(_=_.slice(0,w));return _}(s,i);if(ArrayBuffer.isView(s))return function fromArrayView(s){if(isInstance(s,Uint8Array)){const i=new Uint8Array(s);return fromArrayBuffer(i.buffer,i.byteOffset,i.byteLength)}return fromArrayLike(s)}(s);if(null==s)throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof s);if(isInstance(s,ArrayBuffer)||s&&isInstance(s.buffer,ArrayBuffer))return fromArrayBuffer(s,i,u);if("undefined"!=typeof SharedArrayBuffer&&(isInstance(s,SharedArrayBuffer)||s&&isInstance(s.buffer,SharedArrayBuffer)))return fromArrayBuffer(s,i,u);if("number"==typeof s)throw new TypeError('The "value" argument must not be of type number. Received type number');const _=s.valueOf&&s.valueOf();if(null!=_&&_!==s)return Buffer.from(_,i,u);const w=function fromObject(s){if(Buffer.isBuffer(s)){const i=0|checked(s.length),u=createBuffer(i);return 0===u.length||s.copy(u,0,0,i),u}if(void 0!==s.length)return"number"!=typeof s.length||numberIsNaN(s.length)?createBuffer(0):fromArrayLike(s);if("Buffer"===s.typeLine truncated
|
||||
//# sourceMappingURL=swagger-ui-bundle.js.map
|
||||
@@ -1,3 +1,3 @@
|
||||
/*! For license information please see swagger-ui-standalone-preset.js.LICENSE.txt */
|
||||
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.SwaggerUIStandalonePreset=e():t.SwaggerUIStandalonePreset=e()}(this,(function(){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(r,i,function(e){return t[e]}.bind(null,i));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="/dist",n(n.s=236)}([function(t,e,n){(function(e){var n=function(t){return t&&t.Math==Math&&t};t.exports=n("object"==typeof globalThis&&globalThis)||n("object"==typeof window&&window)||n("object"==typeof self&&self)||n("object"==typeof e&&e)||function(){return this}()||Function("return this")()}).call(this,n(24))},function(t,e,n){t.exports=function(){"use strict";var t=Array.prototype.slice;function e(t,e){e&&(t.prototype=Object.create(e.prototype)),t.prototype.constructor=t}function n(t){return u(t)?t:J(t)}function r(t){return s(t)?t:Z(t)}function i(t){return a(t)?t:X(t)}function o(t){return u(t)&&!c(t)?t:V(t)}function u(t){return!(!t||!t[l])}function s(t){return!(!t||!t[p])}function a(t){return!(!t||!t[h])}function c(t){return s(t)||a(t)}function f(t){return!(!t||!t[d])}e(r,n),e(i,n),e(o,n),n.isIterable=u,n.isKeyed=s,n.isIndexed=a,n.isAssociative=c,n.isOrdered=f,n.Keyed=r,n.Indexed=i,n.Set=o;var l="@@__IMMUTABLE_ITERABLE__@@",p="@@__IMMUTABLE_KEYED__@@",h="@@__IMMUTABLE_INDEXED__@@",d="@@__IMMUTABLE_ORDERED__@@",y="delete",v=5,g=1<<v,w=g-1,M={},_={value:!1},L={value:!1};function m(t){return t.value=!1,t}function x(t){t&&(t.value=!0)}function j(){}function b(t,e){e=e||0;for(var n=Math.max(0,t.length-e),r=new Array(n),i=0;i<n;i++)r[i]=t[i+e];return r}function N(t){return void 0===t.size&&(t.size=t.__iterate(D)),t.size}function S(t,e){if("number"!=typeof e){var n=e>>>0;if(""+n!==e||4294967295===n)return NaN;e=n}return e<0?N(t)+e:e}function D(){return!0}function I(t,e,n){return(0===t||void 0!==n&&t<=-n)&&(void 0===e||void 0!==n&&e>=n)}function O(t,e){return T(t,e,0)}function A(t,e){return T(t,e,e)}function T(t,e,n){return void 0===t?n:t<0?Math.max(0,e+t):void 0===e?t:Math.min(e,t)}var C=0,E=1,z=2,k="function"==typeof Symbol&&Symbol.iterator,U="@@iterator",Y=k||U;function P(t){this.next=t}function R(t,e,n,r){var i=0===t?e:1===t?n:[e,n];return r?r.value=i:r={value:i,done:!1},r}function Q(){return{value:void 0,done:!0}}function B(t){return!!W(t)}function F(t){return t&&"function"==typeof t.next}function G(t){var e=W(t);return e&&e.call(t)}function W(t){var e=t&&(k&&t[k]||t[U]);if("function"==typeof e)return e}function q(t){return t&&"number"==typeof t.length}function J(t){return null==t?ut():u(t)?t.toSeq():ct(t)}function Z(t){return null==t?ut().toKeyedSeq():u(t)?s(t)?t.toSeq():t.fromEntrySeq():st(t)}function X(t){return null==t?ut():u(t)?s(t)?t.entrySeq():t.toIndexedSeq():at(t)}function V(t){return(null==t?ut():u(t)?s(t)?t.entrySeq():t:at(t)).toSetSeq()}P.prototype.toString=function(){return"[Iterator]"},P.KEYS=C,P.VALUES=E,P.ENTRIES=z,P.prototype.inspect=P.prototype.toSource=function(){return this.toString()},P.prototype[Y]=function(){return this},e(J,n),J.of=function(){return J(arguments)},J.prototype.toSeq=function(){return this},J.prototype.toString=function(){return this.__toString("Seq {","}")},J.prototype.cacheResult=function(){return!this._cache&&this.__iterateUncached&&(this._cache=this.entrySeq().toArray(),this.size=this._cache.length),this},J.prototype.__iterate=function(t,e){return lt(this,t,e,!0)},J.prototype.__iterator=function(t,e){return pt(this,t,e,!0)},e(Z,J),Z.prototype.toKeyedSeq=function(){return this},e(X,J),X.of=function(){return X(arguments)},X.prototype.toIndexedSeq=function(){return this},X.prototype.toString=function(){return this.__toString("Seq [","]")},X.prototype.__iterate=function(t,e){return lt(this,t,e,!1)},X.prototype.__iterator=function(t,e){return pt(this,t,e,!1)},e(V,J),V.of=function(){return V(arguments)},V.prototype.toSetSeq=function(){return this},J.isSeq=ot,J.Keyed=Z,J.Set=V,J.Indexed=X;var H,K,$,tt="@@__IMMUTABLE_SEQ__@@";function et(t){this._array=t,this.size=t.length}function nt(t){var e=Object.keys(t);this._object=t,this._keys=e,this.size=e.length}function rt(t){this._iterable=t,this.size=t.length||t.size}function it(t){this._itLine truncated
|
||||
!function webpackUniversalModuleDefinition(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.SwaggerUIStandalonePreset=t():e.SwaggerUIStandalonePreset=t()}(this,(()=>(()=>{var e={9119:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.BLANK_URL=t.relativeFirstCharacters=t.urlSchemeRegex=t.ctrlCharactersRegex=t.htmlCtrlEntityRegex=t.htmlEntitiesRegex=t.invalidProtocolRegex=void 0,t.invalidProtocolRegex=/^([^\w]*)(javascript|data|vbscript)/im,t.htmlEntitiesRegex=/&#(\w+)(^\w|;)?/g,t.htmlCtrlEntityRegex=/&(newline|tab);/gi,t.ctrlCharactersRegex=/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim,t.urlSchemeRegex=/^.+(:|:)/gim,t.relativeFirstCharacters=[".","/"],t.BLANK_URL="about:blank"},6750:(e,t,r)=>{"use strict";var n=r(9119)},7526:(e,t)=>{"use strict";t.byteLength=function byteLength(e){var t=getLens(e),r=t[0],n=t[1];return 3*(r+n)/4-n},t.toByteArray=function toByteArray(e){var t,r,o=getLens(e),a=o[0],s=o[1],u=new i(function _byteLength(e,t,r){return 3*(t+r)/4-r}(0,a,s)),c=0,f=s>0?a-4:a;for(r=0;r<f;r+=4)t=n[e.charCodeAt(r)]<<18|n[e.charCodeAt(r+1)]<<12|n[e.charCodeAt(r+2)]<<6|n[e.charCodeAt(r+3)],u[c++]=t>>16&255,u[c++]=t>>8&255,u[c++]=255&t;2===s&&(t=n[e.charCodeAt(r)]<<2|n[e.charCodeAt(r+1)]>>4,u[c++]=255&t);1===s&&(t=n[e.charCodeAt(r)]<<10|n[e.charCodeAt(r+1)]<<4|n[e.charCodeAt(r+2)]>>2,u[c++]=t>>8&255,u[c++]=255&t);return u},t.fromByteArray=function fromByteArray(e){for(var t,n=e.length,i=n%3,o=[],a=16383,s=0,u=n-i;s<u;s+=a)o.push(encodeChunk(e,s,s+a>u?u:s+a));1===i?(t=e[n-1],o.push(r[t>>2]+r[t<<4&63]+"==")):2===i&&(t=(e[n-2]<<8)+e[n-1],o.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+"="));return o.join("")};for(var r=[],n=[],i="undefined"!=typeof Uint8Array?Uint8Array:Array,o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",a=0;a<64;++a)r[a]=o[a],n[o.charCodeAt(a)]=a;function getLens(e){var t=e.length;if(t%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var r=e.indexOf("=");return-1===r&&(r=t),[r,r===t?0:4-r%4]}function encodeChunk(e,t,n){for(var i,o,a=[],s=t;s<n;s+=3)i=(e[s]<<16&16711680)+(e[s+1]<<8&65280)+(255&e[s+2]),a.push(r[(o=i)>>18&63]+r[o>>12&63]+r[o>>6&63]+r[63&o]);return a.join("")}n["-".charCodeAt(0)]=62,n["_".charCodeAt(0)]=63},8287:(e,t,r)=>{"use strict";const n=r(7526),i=r(251),o="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):null;t.Buffer=Buffer,t.SlowBuffer=function SlowBuffer(e){+e!=e&&(e=0);return Buffer.alloc(+e)},t.INSPECT_MAX_BYTES=50;const a=2147483647;function createBuffer(e){if(e>a)throw new RangeError('The value "'+e+'" is invalid for option "size"');const t=new Uint8Array(e);return Object.setPrototypeOf(t,Buffer.prototype),t}function Buffer(e,t,r){if("number"==typeof e){if("string"==typeof t)throw new TypeError('The "string" argument must be of type string. Received type number');return allocUnsafe(e)}return from(e,t,r)}function from(e,t,r){if("string"==typeof e)return function fromString(e,t){"string"==typeof t&&""!==t||(t="utf8");if(!Buffer.isEncoding(t))throw new TypeError("Unknown encoding: "+t);const r=0|byteLength(e,t);let n=createBuffer(r);const i=n.write(e,t);i!==r&&(n=n.slice(0,i));return n}(e,t);if(ArrayBuffer.isView(e))return function fromArrayView(e){if(isInstance(e,Uint8Array)){const t=new Uint8Array(e);return fromArrayBuffer(t.buffer,t.byteOffset,t.byteLength)}return fromArrayLike(e)}(e);if(null==e)throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e);if(isInstance(e,ArrayBuffer)||e&&isInstance(e.buffer,ArrayBuffer))return fromArrayBuffer(e,t,r);if("undefined"!=typeof SharedArrayBuffer&&(isInstance(e,SharedArrayBuffer)||e&&isInstance(e.buffer,SharedArrayBuffer)))return fromArrayBuffer(e,t,r);if("number"==typeof e)throw new TypeError('The "value" argument must not be of type number. Received type number');const n=e.valueOf&&e.valueOf();if(null!=n&&n!==e)return Buffer.from(n,t,r);const i=function fromObject(e){if(Buffer.isBuffer(e)){const t=0|checked(e.length),r=createBuffer(t);return 0===r.length||e.copy(r,0,0,t),r}if(void 0!==e.length)return"number"!=typeof e.length||numberIsNaN(e.length)?createBuffer(0):fromArrayLike(e);if("Buffer"===e.type&&Array.isArray(e.data))return fromArrayLike(e.data)}(e);if(i)return i;if("undefined"!=typeof Symbol&&null!=Symbol.toPrimitive&&"function"==typeof e[Symbol.toPrimitive])return Buffer.from(e[Symbol.toPrimitive]("string"),t,r);throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e)}function assertSize(e){if("number"!=typeof e)throw new TypeError('"size" argument must be of type number');if(e<0)throw new RangeError('The value "'+e+'" is invalid for option "size"')}function allocUnsafe(e){return assertSize(e),createBuffer(e<0?0:0|checked(e))Line truncated
|
||||
//# sourceMappingURL=swagger-ui-standalone-preset.js.map
|
||||
@@ -126,7 +126,7 @@ export default function GpgBox(props) {
|
||||
<Button startIcon={isGpgKeyRemoving ? <CircularProgress size={12} /> : <Remove />}
|
||||
color="secondary" onClick={onRemoveGpgKey}
|
||||
variant="outlined" size="small"
|
||||
disabled={isGpgKeyRemoving || !api.hasPermission("user/removeGPG")}>
|
||||
disabled={isGpgKeyRemoving || !api.hasPermission("gpgKey/remove")}>
|
||||
{isGpgKeyRemoving ? L("general.removing") + "…" : L("general.remove")}
|
||||
</Button>
|
||||
</Box> :
|
||||
@@ -134,7 +134,7 @@ export default function GpgBox(props) {
|
||||
<SpacedFormGroup>
|
||||
<FormLabel>{L("account.gpg_key")}</FormLabel>
|
||||
<GpgKeyField value={gpgKey} multiline={true} rows={8}
|
||||
disabled={isGpgKeyUploading || !api.hasPermission("user/importGPG")}
|
||||
disabled={isGpgKeyUploading || !api.hasPermission("gpgKey/import")}
|
||||
placeholder={L("account.gpg_key_placeholder_text")}
|
||||
onChange={e => setGpgKey(e.target.value)}
|
||||
onDrop={e => {
|
||||
@@ -162,7 +162,7 @@ export default function GpgBox(props) {
|
||||
<Button startIcon={isGpgKeyUploading ? <CircularProgress size={12} /> : <Upload />}
|
||||
color="primary" onClick={onUploadGPG}
|
||||
variant="outlined" size="small"
|
||||
disabled={isGpgKeyUploading || !api.hasPermission("user/importGPG")}>
|
||||
disabled={isGpgKeyUploading || !api.hasPermission("gpgKey/import")}>
|
||||
{isGpgKeyUploading ? L("general.uploading") + "…" : L("general.upload")}
|
||||
</Button>
|
||||
</ButtonBar>
|
||||
|
||||
+4
-4
@@ -387,7 +387,7 @@ export default class API {
|
||||
|
||||
/** GPG API **/
|
||||
async uploadGPG(pubkey) {
|
||||
let res = await this.apiCall("user/importGPG", { pubkey: pubkey });
|
||||
let res = await this.apiCall("gpgKey/import", { pubkey: pubkey });
|
||||
if (res.success) {
|
||||
this.user.gpgKey = res.gpgKey;
|
||||
}
|
||||
@@ -396,7 +396,7 @@ export default class API {
|
||||
}
|
||||
|
||||
async confirmGpgToken(token) {
|
||||
let res = await this.apiCall("user/confirmGPG", { token: token });
|
||||
let res = await this.apiCall("gpgKey/confirm", { token: token });
|
||||
if (res.success) {
|
||||
this.user.gpgKey.confirmed = true;
|
||||
}
|
||||
@@ -405,7 +405,7 @@ export default class API {
|
||||
}
|
||||
|
||||
async removeGPG(password) {
|
||||
let res = await this.apiCall("user/removeGPG", { password: password });
|
||||
let res = await this.apiCall("gpgKey/remove", { password: password });
|
||||
if (res.success) {
|
||||
this.user.gpgKey = null;
|
||||
}
|
||||
@@ -414,7 +414,7 @@ export default class API {
|
||||
}
|
||||
|
||||
async downloadGPG(userId) {
|
||||
return this.apiCall("user/downloadGPG", { id: userId }, true);
|
||||
return this.apiCall("gpgKey/download", { id: userId }, true);
|
||||
}
|
||||
|
||||
/** Log API **/
|
||||
|
||||
Reference in new issue
Block a user