Add console oauth endpoint

This commit is contained in:
Matej Bačo
2026-04-28 09:47:27 +02:00
parent ad4178aa42
commit d25707346f
50 changed files with 1307 additions and 1 deletions
+6
View File
@@ -56,6 +56,9 @@ use Appwrite\Utopia\Response\Model\ColumnString;
use Appwrite\Utopia\Response\Model\ColumnText;
use Appwrite\Utopia\Response\Model\ColumnURL;
use Appwrite\Utopia\Response\Model\ColumnVarchar;
use Appwrite\Utopia\Response\Model\ConsoleOAuth2Provider;
use Appwrite\Utopia\Response\Model\ConsoleOAuth2ProviderList;
use Appwrite\Utopia\Response\Model\ConsoleOAuth2ProviderParameter;
use Appwrite\Utopia\Response\Model\ConsoleVariables;
use Appwrite\Utopia\Response\Model\Continent;
use Appwrite\Utopia\Response\Model\Country;
@@ -476,6 +479,9 @@ Response::setModel(new Rule());
Response::setModel(new Schedule());
Response::setModel(new TemplateEmail());
Response::setModel(new ConsoleVariables());
Response::setModel(new ConsoleOAuth2ProviderParameter());
Response::setModel(new ConsoleOAuth2Provider());
Response::setModel(new ConsoleOAuth2ProviderList());
Response::setModel(new MFAChallenge());
Response::setModel(new MFARecoveryCodes());
Response::setModel(new MFAType());
@@ -0,0 +1 @@
List all OAuth2 providers supported by the Appwrite server, along with the parameters required to configure each provider. The response excludes mock providers but includes sandbox providers.
@@ -0,0 +1,80 @@
<?php
namespace Appwrite\Platform\Modules\Console\Http\OAuth2Providers;
use Appwrite\Platform\Modules\Project\Http\Project\OAuth2\Base as OAuth2Base;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\ContentType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response;
use Utopia\Config\Config;
use Utopia\Database\Document;
use Utopia\Platform\Action;
use Utopia\Platform\Scope\HTTP;
class XList extends Action
{
use HTTP;
public static function getName(): string
{
return 'listOAuth2Providers';
}
public function __construct()
{
$this
->setHttpMethod(Action::HTTP_REQUEST_METHOD_GET)
->setHttpPath('/v1/console/oauth2-providers')
->desc('List OAuth2 providers')
->groups(['api'])
->label('scope', 'public')
->label('sdk', new Method(
namespace: 'console',
group: 'console',
name: 'listOAuth2Providers',
description: '/docs/references/console/list-oauth2-providers.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_CONSOLE_OAUTH2_PROVIDER_LIST,
)
],
contentType: ContentType::JSON
))
->inject('response')
->callback($this->action(...));
}
public function action(Response $response): void
{
$providersConfig = Config::getParam('oAuthProviders', []);
$actions = OAuth2Base::getProviderActions();
$providers = [];
foreach ($actions as $providerId => $updateClass) {
$config = $providersConfig[$providerId] ?? null;
if ($config === null) {
continue;
}
if (!($config['enabled'] ?? false)) {
continue;
}
if ($config['mock'] ?? false) {
continue;
}
$providers[] = new Document([
'$id' => $providerId,
'parameters' => $updateClass::getParameters(),
]);
}
$response->dynamic(new Document([
'total' => \count($providers),
'oAuth2Providers' => $providers,
]), Response::MODEL_CONSOLE_OAUTH2_PROVIDER_LIST);
}
}
@@ -5,6 +5,7 @@ namespace Appwrite\Platform\Modules\Console\Services;
use Appwrite\Platform\Modules\Console\Http\Assistant\Create as CreateAssistantQuery;
use Appwrite\Platform\Modules\Console\Http\Init\API;
use Appwrite\Platform\Modules\Console\Http\Init\Web;
use Appwrite\Platform\Modules\Console\Http\OAuth2Providers\XList as ListOAuth2Providers;
use Appwrite\Platform\Modules\Console\Http\Redirects\Auth\Get as RedirectAuth;
use Appwrite\Platform\Modules\Console\Http\Redirects\Card\Get as RedirectCard;
use Appwrite\Platform\Modules\Console\Http\Redirects\Invite\Get as RedirectInvite;
@@ -28,6 +29,7 @@ class Http extends Service
$this->addAction(Web::getName(), new Web());
$this->addAction(GetVariables::getName(), new GetVariables());
$this->addAction(ListOAuth2Providers::getName(), new ListOAuth2Providers());
$this->addAction(CreateAssistantQuery::getName(), new CreateAssistantQuery());
$this->addAction(GetResourceAvailability::getName(), new GetResourceAvailability());
@@ -42,4 +42,24 @@ class Update extends Base
{
return '\'Client Secret\' of Amazon OAuth2 app. For example: 79ffe4000000000000000000000000000000000000000000000000000002de55';
}
public static function getClientIdName(): string
{
return 'Client ID';
}
public static function getClientIdExample(): string
{
return 'amzn1.application-oa2-client.87400c00000000000000000000063d5b2';
}
public static function getClientSecretName(): string
{
return 'Client Secret';
}
public static function getClientSecretExample(): string
{
return '79ffe4000000000000000000000000000000000000000000000000000002de55';
}
}
@@ -61,6 +61,59 @@ class Update extends Base
return '';
}
public static function getClientIdName(): string
{
return 'Service ID';
}
public static function getClientIdExample(): string
{
return 'ip.appwrite.app.web';
}
public static function getClientSecretName(): string
{
// Apple does not use a single clientSecret param. Returning an empty
// string causes the default getParameters() to skip it; the override
// below adds the three real fields (keyId, teamId, p8File).
return '';
}
public static function getClientSecretExample(): string
{
return '';
}
public static function getParameters(): array
{
return [
[
'$id' => static::getClientIdParamName(),
'name' => static::getClientIdName(),
'example' => static::getClientIdExample(),
'hint' => '',
],
[
'$id' => 'keyId',
'name' => 'Key ID',
'example' => 'P4000000N8',
'hint' => '',
],
[
'$id' => 'teamId',
'name' => 'Team ID',
'example' => 'D4000000R6',
'hint' => '',
],
[
'$id' => 'p8File',
'name' => 'P8 File',
'example' => '-----BEGIN PRIVATE KEY-----MIGTAg...jy2Xbna-----END PRIVATE KEY-----',
'hint' => '',
],
];
}
public function __construct()
{
$providerId = static::getProviderId();
@@ -54,6 +54,38 @@ class Update extends Base
return '\'Client Secret\' of Auth0 OAuth2 app. For example: zXz0000-00000000000000000000000000000-00000000000000000000PJafnF';
}
public static function getClientIdName(): string
{
return 'Client ID';
}
public static function getClientIdExample(): string
{
return 'OaOkIA000000000000000000005KLSYq';
}
public static function getClientSecretName(): string
{
return 'Client Secret';
}
public static function getClientSecretExample(): string
{
return 'zXz0000-00000000000000000000000000000-00000000000000000000PJafnF';
}
public static function getParameters(): array
{
return \array_merge(parent::getParameters(), [
[
'$id' => 'endpoint',
'name' => 'Domain',
'example' => 'example.us.auth0.com',
'hint' => '',
],
]);
}
public function __construct()
{
$providerId = static::getProviderId();
@@ -54,6 +54,38 @@ class Update extends Base
return '\'Client Secret\' of Authentik OAuth2 app. For example: ntQadq000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Hp5WK';
}
public static function getClientIdName(): string
{
return 'Client ID';
}
public static function getClientIdExample(): string
{
return 'dTKOPa0000000000000000000000000000e7G8hv';
}
public static function getClientSecretName(): string
{
return 'Client Secret';
}
public static function getClientSecretExample(): string
{
return 'ntQadq000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Hp5WK';
}
public static function getParameters(): array
{
return \array_merge(parent::getParameters(), [
[
'$id' => 'endpoint',
'name' => 'Domain',
'example' => 'example.authentik.com',
'hint' => '',
],
]);
}
public function __construct()
{
$providerId = static::getProviderId();
@@ -42,4 +42,24 @@ class Update extends Base
{
return '\'client secret\' of Autodesk OAuth2 app. For example: 7I000000000000MW';
}
public static function getClientIdName(): string
{
return 'Client ID';
}
public static function getClientIdExample(): string
{
return '5zw90v00000000000000000000kVYXN7';
}
public static function getClientSecretName(): string
{
return 'Client Secret';
}
public static function getClientSecretExample(): string
{
return '7I000000000000MW';
}
}
@@ -64,6 +64,97 @@ abstract class Base extends Action
*/
abstract public static function getClientSecretDescription(): string;
/**
* Verbose, user-facing name of the clientId param. Includes alternate
* names when the provider exposes more than one (e.g. "Client ID or App
* ID", "Application ID (also known as Client ID)").
*
* @return string
*/
abstract public static function getClientIdName(): string;
/**
* Example value of the clientId param. Used to build the public OAuth2
* providers metadata response.
*
* @return string
*/
abstract public static function getClientIdExample(): string;
/**
* Optional hint for the clientId param. Typically used to call out a
* common wrong value (e.g. "Example of wrong value: 370006"). Defaults
* to an empty string.
*/
public static function getClientIdHint(): string
{
return '';
}
/**
* Verbose, user-facing name of the clientSecret param. Returns an empty
* string for providers that don't have a single clientSecret param
* (e.g. Apple uses keyId/teamId/p8File instead).
*
* @return string
*/
abstract public static function getClientSecretName(): string;
/**
* Example value of the clientSecret param. Returns an empty string for
* providers without a clientSecret param.
*
* @return string
*/
abstract public static function getClientSecretExample(): string;
/**
* Optional hint for the clientSecret param. Defaults to an empty string.
*/
public static function getClientSecretHint(): string
{
return '';
}
/**
* Public-facing parameter metadata for this provider. Used by the public
* console OAuth2 providers endpoint to describe the form fields a project
* owner must fill in to configure the provider.
*
* Default shape: clientId + clientSecret. Providers that take additional
* fields (Apple, Auth0, Authentik, Gitlab, Microsoft, Oidc, Okta)
* override this method to add or replace entries. Each parameter is an
* associative array with keys `$id`, `name`, `example`, `hint`.
*
* @return array<int, array<string, string>>
*/
public static function getParameters(): array
{
$parameters = [];
$clientIdName = static::getClientIdName();
if ($clientIdName !== '') {
$parameters[] = [
'$id' => static::getClientIdParamName(),
'name' => $clientIdName,
'example' => static::getClientIdExample(),
'hint' => static::getClientIdHint(),
];
}
$clientSecretName = static::getClientSecretName();
if ($clientSecretName !== '') {
$parameters[] = [
'$id' => static::getClientSecretParamName(),
'name' => $clientSecretName,
'example' => static::getClientSecretExample(),
'hint' => static::getClientSecretHint(),
];
}
return $parameters;
}
/**
* Public-facing name of the clientId param. Some providers use a different
* terminology (e.g. Dropbox calls it "App key"), so the param name and the
@@ -52,4 +52,24 @@ class Update extends Base
{
return '\'Secret\' of Bitbucket OAuth2 app. For example: NMfLZJ00000000000000000000TLQdDx';
}
public static function getClientIdName(): string
{
return 'Key';
}
public static function getClientIdExample(): string
{
return 'Knt70000000000ByRc';
}
public static function getClientSecretName(): string
{
return 'Secret';
}
public static function getClientSecretExample(): string
{
return 'NMfLZJ00000000000000000000TLQdDx';
}
}
@@ -42,4 +42,24 @@ class Update extends Base
{
return '\'Client Secret\' of Bitly OAuth2 app. For example: a13e250000000000000000000000000000d73095';
}
public static function getClientIdName(): string
{
return 'Client ID';
}
public static function getClientIdExample(): string
{
return 'd95151000000000000000000000000000067af9b';
}
public static function getClientSecretName(): string
{
return 'Client Secret';
}
public static function getClientSecretExample(): string
{
return 'a13e250000000000000000000000000000d73095';
}
}
@@ -42,4 +42,24 @@ class Update extends Base
{
return '\'Client Secret\' of Box OAuth2 app. For example: OKM1f100000000000000000000eshEif';
}
public static function getClientIdName(): string
{
return 'Client ID';
}
public static function getClientIdExample(): string
{
return 'deglcs00000000000000000000x2og6y';
}
public static function getClientSecretName(): string
{
return 'Client Secret';
}
public static function getClientSecretExample(): string
{
return 'OKM1f100000000000000000000eshEif';
}
}
@@ -52,4 +52,24 @@ class Update extends Base
{
return '\'API secret\' of Dailymotion OAuth2 app. For example: a399a90000000000000000000000000000d90639';
}
public static function getClientIdName(): string
{
return 'API Key';
}
public static function getClientIdExample(): string
{
return '07a9000000000000067f';
}
public static function getClientSecretName(): string
{
return 'API Secret';
}
public static function getClientSecretExample(): string
{
return 'a399a90000000000000000000000000000d90639';
}
}
@@ -42,4 +42,24 @@ class Update extends Base
{
return '\'Client Secret\' of Discord OAuth2 app. For example: YmPXnM000000000000000000002zFg5D';
}
public static function getClientIdName(): string
{
return 'Client ID';
}
public static function getClientIdExample(): string
{
return '950722000000343754';
}
public static function getClientSecretName(): string
{
return 'Client Secret';
}
public static function getClientSecretExample(): string
{
return 'YmPXnM000000000000000000002zFg5D';
}
}
@@ -52,4 +52,24 @@ class Update extends Base
{
return '\'Secret Key\', also known as \'API Secret\', of Disqus OAuth2 app. For example: W7Bykj00000000000000000000000000000000000000000000000000003o43w9';
}
public static function getClientIdName(): string
{
return 'Public Key, also known as API Key';
}
public static function getClientIdExample(): string
{
return 'cgegH70000000000000000000000000000000000000000000000000000Hr1nYX';
}
public static function getClientSecretName(): string
{
return 'Secret Key, also known as API Secret';
}
public static function getClientSecretExample(): string
{
return 'W7Bykj00000000000000000000000000000000000000000000000000003o43w9';
}
}
@@ -52,4 +52,24 @@ class Update extends Base
{
return '\'App secret\' of Dropbox OAuth2 app. For example: g200000000000vw';
}
public static function getClientIdName(): string
{
return 'App Key';
}
public static function getClientIdExample(): string
{
return 'jl000000000009t';
}
public static function getClientSecretName(): string
{
return 'App Secret';
}
public static function getClientSecretExample(): string
{
return 'g200000000000vw';
}
}
@@ -52,4 +52,24 @@ class Update extends Base
{
return '\'Shared Secret\' of Etsy OAuth2 app. For example: tp000000ru';
}
public static function getClientIdName(): string
{
return 'Keystring';
}
public static function getClientIdExample(): string
{
return 'nsgzxh0000000000008j85a2';
}
public static function getClientSecretName(): string
{
return 'Shared Secret';
}
public static function getClientSecretExample(): string
{
return 'tp000000ru';
}
}
@@ -52,4 +52,24 @@ class Update extends Base
{
return '\'App secret\' of Facebook OAuth2 app. For example: 2d0b2800000000000000000000d38af4';
}
public static function getClientIdName(): string
{
return 'App ID';
}
public static function getClientIdExample(): string
{
return '260600000007694';
}
public static function getClientSecretName(): string
{
return 'App Secret';
}
public static function getClientSecretExample(): string
{
return '2d0b2800000000000000000000d38af4';
}
}
@@ -42,4 +42,24 @@ class Update extends Base
{
return '\'Client Secret\' of Figma OAuth2 app. For example: yEpOYn0000000000000000004iIsU5';
}
public static function getClientIdName(): string
{
return 'Client ID';
}
public static function getClientIdExample(): string
{
return 'byay5H0000000000VtiI40';
}
public static function getClientSecretName(): string
{
return 'Client Secret';
}
public static function getClientSecretExample(): string
{
return 'yEpOYn0000000000000000004iIsU5';
}
}
@@ -42,4 +42,29 @@ class Update extends Base
{
return '\'Client secret\' of GitHub OAuth2 app, or GitHub generic app. For example: 5e07c00000000000000000000000000000198bcc';
}
public static function getClientIdName(): string
{
return 'Client ID or App ID';
}
public static function getClientIdExample(): string
{
return 'e4d87900000000540733';
}
public static function getClientIdHint(): string
{
return 'Example of wrong value: 370006';
}
public static function getClientSecretName(): string
{
return 'Client Secret';
}
public static function getClientSecretExample(): string
{
return '5e07c00000000000000000000000000000198bcc';
}
}
@@ -65,6 +65,38 @@ class Update extends Base
return '\'Secret\' of GitLab OAuth2 app. For example: gloas-838cfa0000000000000000000000000000000000000000000000000000ecbb38';
}
public static function getClientIdName(): string
{
return 'Application ID';
}
public static function getClientIdExample(): string
{
return 'd41ffe0000000000000000000000000000000000000000000000000000d5e252';
}
public static function getClientSecretName(): string
{
return 'Secret';
}
public static function getClientSecretExample(): string
{
return 'gloas-838cfa0000000000000000000000000000000000000000000000000000ecbb38';
}
public static function getParameters(): array
{
return \array_merge(parent::getParameters(), [
[
'$id' => 'endpoint',
'name' => 'Endpoint',
'example' => 'https://gitlab.com',
'hint' => '',
],
]);
}
public function __construct()
{
$providerId = static::getProviderId();
@@ -42,4 +42,24 @@ class Update extends Base
{
return '\'Client secret\' of Google OAuth2 app. For example: GOCSPX-2k8gsR0000000000000000VNahJj';
}
public static function getClientIdName(): string
{
return 'Client ID';
}
public static function getClientIdExample(): string
{
return '120000000095-92ifjb00000000000000000000g7ijfb.apps.googleusercontent.com';
}
public static function getClientSecretName(): string
{
return 'Client Secret';
}
public static function getClientSecretExample(): string
{
return 'GOCSPX-2k8gsR0000000000000000VNahJj';
}
}
@@ -42,4 +42,24 @@ class Update extends Base
{
return '\'Client Secret\' of Kick OAuth2 app. For example: 34ac5600000000000000000000000000000000000000000000000000e830c8b';
}
public static function getClientIdName(): string
{
return 'Client ID';
}
public static function getClientIdExample(): string
{
return '01KQ7C00000000000001MFHS32';
}
public static function getClientSecretName(): string
{
return 'Client Secret';
}
public static function getClientSecretExample(): string
{
return '34ac5600000000000000000000000000000000000000000000000000e830c8b';
}
}
@@ -47,4 +47,24 @@ class Update extends Base
{
return '\'Primary Client Secret\' or \'Secondary Client Secret\', of LinkedIn OAuth2 app. For example: WPL_AP1.2Bf0000000000000./HtlYw==';
}
public static function getClientIdName(): string
{
return 'Client ID';
}
public static function getClientIdExample(): string
{
return '770000000000dv';
}
public static function getClientSecretName(): string
{
return 'Primary Client Secret or Secondary Client Secret';
}
public static function getClientSecretExample(): string
{
return 'WPL_AP1.2Bf0000000000000./HtlYw==';
}
}
@@ -64,6 +64,38 @@ class Update extends Base
return '\'Application Secret\' (also known as Client Secret) of Microsoft Entra ID app. For example: A1bC2dE3fH4iJ5kL6mN7oP8qR9sT0u';
}
public static function getClientIdName(): string
{
return 'Application ID (also known as Client ID)';
}
public static function getClientIdExample(): string
{
return '00001111-aaaa-2222-bbbb-3333cccc4444';
}
public static function getClientSecretName(): string
{
return 'Application Secret (also known as Client Secret)';
}
public static function getClientSecretExample(): string
{
return 'A1bC2dE3fH4iJ5kL6mN7oP8qR9sT0u';
}
public static function getParameters(): array
{
return \array_merge(parent::getParameters(), [
[
'$id' => 'tenant',
'name' => 'Tenant',
'example' => 'common',
'hint' => '',
],
]);
}
public function __construct()
{
$providerId = static::getProviderId();
@@ -52,4 +52,24 @@ class Update extends Base
{
return '\'OAuth Client Secret\' of Notion OAuth2 app. For example: secret_dLUr4b000000000000000000000000000000lFHAa9';
}
public static function getClientIdName(): string
{
return 'OAuth Client ID';
}
public static function getClientIdExample(): string
{
return '341d8700-0000-0000-0000-000000446ee3';
}
public static function getClientSecretName(): string
{
return 'OAuth Client Secret';
}
public static function getClientSecretExample(): string
{
return 'secret_dLUr4b000000000000000000000000000000lFHAa9';
}
}
@@ -56,6 +56,56 @@ class Update extends Base
return '\'Client Secret\' of OpenID Connect OAuth2 app. For example: Ah68ed000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003qpcHV';
}
public static function getClientIdName(): string
{
return 'Client ID';
}
public static function getClientIdExample(): string
{
return 'qibI2x0000000000000000000000000006L2YFoG';
}
public static function getClientSecretName(): string
{
return 'Client Secret';
}
public static function getClientSecretExample(): string
{
return 'Ah68ed000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003qpcHV';
}
public static function getParameters(): array
{
return \array_merge(parent::getParameters(), [
[
'$id' => 'wellKnownURL',
'name' => 'Well-known URL',
'example' => 'https://myoauth.com/.well-known/openid-configuration',
'hint' => '',
],
[
'$id' => 'authorizationURL',
'name' => 'Authorization URL',
'example' => 'https://myoauth.com/oauth2/authorize',
'hint' => '',
],
[
'$id' => 'tokenUrl',
'name' => 'Token URL',
'example' => 'https://myoauth.com/oauth2/token',
'hint' => '',
],
[
'$id' => 'userInfoUrl',
'name' => 'User Info URL',
'example' => 'https://myoauth.com/oauth2/userinfo',
'hint' => '',
],
]);
}
public function __construct()
{
$providerId = static::getProviderId();
@@ -56,6 +56,44 @@ class Update extends Base
return '\'Client Secret\' of Okta OAuth2 app. For example: Kiq0000000000000000000000000000000000000-00000000000H2L5-3SJ-vRV';
}
public static function getClientIdName(): string
{
return 'Client ID';
}
public static function getClientIdExample(): string
{
return '0oa00000000000000698';
}
public static function getClientSecretName(): string
{
return 'Client Secret';
}
public static function getClientSecretExample(): string
{
return 'Kiq0000000000000000000000000000000000000-00000000000H2L5-3SJ-vRV';
}
public static function getParameters(): array
{
return \array_merge(parent::getParameters(), [
[
'$id' => 'domain',
'name' => 'Domain',
'example' => 'trial-6400025.okta.com',
'hint' => 'Example of wrong value: trial-6400025-admin.okta.com, or https://trial-6400025.okta.com/',
],
[
'$id' => 'authorizationServerId',
'name' => 'Authorization Server ID',
'example' => 'aus000000000000000h7z',
'hint' => '',
],
]);
}
public function __construct()
{
$providerId = static::getProviderId();
@@ -47,4 +47,24 @@ class Update extends Base
{
return '\'Secret key 1\', or \'Secret key 2\', of ' . static::getProviderLabel() . ' OAuth2 app. For example: EH8KCXtew--000000000000000000000000000000000000000_C-1_5UP_000000000000000CB7KDp';
}
public static function getClientIdName(): string
{
return 'Client ID';
}
public static function getClientIdExample(): string
{
return 'AdhIEG7-000000000000-0000000000000000000000000000000-0000000000000000000000-2pyB';
}
public static function getClientSecretName(): string
{
return 'Secret Key 1 or Secret Key 2';
}
public static function getClientSecretExample(): string
{
return 'EH8KCXtew--000000000000000000000000000000000000000_C-1_5UP_000000000000000CB7KDp';
}
}
@@ -42,4 +42,24 @@ class Update extends Base
{
return '\'Client Secret\' of Podio OAuth2 app. For example: Rn247T0000000000000000000000000000000000000000000000000000W2zWTN';
}
public static function getClientIdName(): string
{
return 'Client ID';
}
public static function getClientIdExample(): string
{
return 'appwrite-o0000000st-app';
}
public static function getClientSecretName(): string
{
return 'Client Secret';
}
public static function getClientSecretExample(): string
{
return 'Rn247T0000000000000000000000000000000000000000000000000000W2zWTN';
}
}
@@ -52,4 +52,24 @@ class Update extends Base
{
return '\'Consumer secret\' of Salesforce OAuth2 app. For example: 3w000000000000e2';
}
public static function getClientIdName(): string
{
return 'Consumer Key';
}
public static function getClientIdExample(): string
{
return '3MVG9I0000000000000000000000000000000000000000000000000000000000000000000000000C5Aejq';
}
public static function getClientSecretName(): string
{
return 'Consumer Secret';
}
public static function getClientSecretExample(): string
{
return '3w000000000000e2';
}
}
@@ -42,4 +42,24 @@ class Update extends Base
{
return '\'Client Secret\' of Slack OAuth2 app. For example: 81656000000000000000000000f3d2fd';
}
public static function getClientIdName(): string
{
return 'Client ID';
}
public static function getClientIdExample(): string
{
return '23000000089.15000000000023';
}
public static function getClientSecretName(): string
{
return 'Client Secret';
}
public static function getClientSecretExample(): string
{
return '81656000000000000000000000f3d2fd';
}
}
@@ -42,4 +42,24 @@ class Update extends Base
{
return '\'Client secret\' of Spotify OAuth2 app. For example: db068a000000000000000000008b5b9f';
}
public static function getClientIdName(): string
{
return 'Client ID';
}
public static function getClientIdExample(): string
{
return '6ec271000000000000000000009beace';
}
public static function getClientSecretName(): string
{
return 'Client Secret';
}
public static function getClientSecretExample(): string
{
return 'db068a000000000000000000008b5b9f';
}
}
@@ -47,4 +47,24 @@ class Update extends Base
{
return '\'API Secret key\' of Stripe OAuth2 app. For example: sk_51SfOd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000QGWYfp';
}
public static function getClientIdName(): string
{
return 'Client ID';
}
public static function getClientIdExample(): string
{
return 'ca_UKibXX0000000000000000000006byvR';
}
public static function getClientSecretName(): string
{
return 'API Secret Key';
}
public static function getClientSecretExample(): string
{
return 'sk_51SfOd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000QGWYfp';
}
}
@@ -52,4 +52,24 @@ class Update extends Base
{
return '\'Oauth2 Client secret\' of ' . static::getProviderLabel() . ' OAuth2 app. For example: 7cb52700-0000-0000-0000-000000ca5b83';
}
public static function getClientIdName(): string
{
return 'OAuth2 Client ID';
}
public static function getClientIdExample(): string
{
return 'appwrite-tes00000.0000000000est-app';
}
public static function getClientSecretName(): string
{
return 'OAuth2 Client Secret';
}
public static function getClientSecretExample(): string
{
return '7cb52700-0000-0000-0000-000000ca5b83';
}
}
@@ -42,4 +42,24 @@ class Update extends Base
{
return '\'Client Secret\' of Twitch OAuth2 app. For example: pmapue000000000000000000zylw3v';
}
public static function getClientIdName(): string
{
return 'Client ID';
}
public static function getClientIdExample(): string
{
return 'vvi0in000000000000000000ikmt9p';
}
public static function getClientSecretName(): string
{
return 'Client Secret';
}
public static function getClientSecretExample(): string
{
return 'pmapue000000000000000000zylw3v';
}
}
@@ -42,4 +42,24 @@ class Update extends Base
{
return '\'Client Secret\' of WordPress OAuth2 app. For example: PlBfJS0000000000000000000000000000000000000000000000000000EdUZJk';
}
public static function getClientIdName(): string
{
return 'Client ID';
}
public static function getClientIdExample(): string
{
return '130005';
}
public static function getClientSecretName(): string
{
return 'Client Secret';
}
public static function getClientSecretExample(): string
{
return 'PlBfJS0000000000000000000000000000000000000000000000000000EdUZJk';
}
}
@@ -52,4 +52,24 @@ class Update extends Base
{
return '\'Secret Key\' of X OAuth2 app. For example: tkEPkp00000000000000000000000000000000000000FTxbI9';
}
public static function getClientIdName(): string
{
return 'Customer Key';
}
public static function getClientIdExample(): string
{
return 'slzZV0000000000000NFLaWT';
}
public static function getClientSecretName(): string
{
return 'Secret Key';
}
public static function getClientSecretExample(): string
{
return 'tkEPkp00000000000000000000000000000000000000FTxbI9';
}
}
@@ -42,4 +42,24 @@ class Update extends Base
{
return '\'Client Secret\', also known as \'Customer Secret\', of Yahoo OAuth2 app. For example: cf978f0000000000000000000000000000c5e2e9';
}
public static function getClientIdName(): string
{
return 'Client ID, also known as Customer Key';
}
public static function getClientIdExample(): string
{
return 'dj0yJm000000000000000000000000000000000000000000000000000000000000000000000000000000000000Z4PWRm';
}
public static function getClientSecretName(): string
{
return 'Client Secret, also known as Customer Secret';
}
public static function getClientSecretExample(): string
{
return 'cf978f0000000000000000000000000000c5e2e9';
}
}
@@ -42,4 +42,24 @@ class Update extends Base
{
return '\'Client secret\' of Yandex OAuth2 app. For example: bbf98500000000000000000000c75a63';
}
public static function getClientIdName(): string
{
return 'Client ID';
}
public static function getClientIdExample(): string
{
return '6a8a6a0000000000000000000091483c';
}
public static function getClientSecretName(): string
{
return 'Client Secret';
}
public static function getClientSecretExample(): string
{
return 'bbf98500000000000000000000c75a63';
}
}
@@ -42,4 +42,24 @@ class Update extends Base
{
return '\'Client Secret\' of Zoho OAuth2 app. For example: fb5cac000000000000000000000000000000a68f6e';
}
public static function getClientIdName(): string
{
return 'Client ID';
}
public static function getClientIdExample(): string
{
return '1000.83C178000000000000000000RPNX0B';
}
public static function getClientSecretName(): string
{
return 'Client Secret';
}
public static function getClientSecretExample(): string
{
return 'fb5cac000000000000000000000000000000a68f6e';
}
}
@@ -42,4 +42,24 @@ class Update extends Base
{
return '\'Client Secret\' of Zoom OAuth2 app. For example: GAWsG4000000000000000000007U01ON';
}
public static function getClientIdName(): string
{
return 'Client ID';
}
public static function getClientIdExample(): string
{
return 'QMAC00000000000000w0AQ';
}
public static function getClientSecretName(): string
{
return 'Client Secret';
}
public static function getClientSecretExample(): string
{
return 'GAWsG4000000000000000000007U01ON';
}
}
+3
View File
@@ -329,6 +329,9 @@ class Response extends SwooleResponse
// Console
public const MODEL_CONSOLE_VARIABLES = 'consoleVariables';
public const MODEL_CONSOLE_OAUTH2_PROVIDER_PARAMETER = 'consoleOAuth2ProviderParameter';
public const MODEL_CONSOLE_OAUTH2_PROVIDER = 'consoleOAuth2Provider';
public const MODEL_CONSOLE_OAUTH2_PROVIDER_LIST = 'consoleOAuth2ProviderList';
// Deprecated
public const MODEL_PERMISSIONS = 'permissions';
@@ -0,0 +1,37 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
class ConsoleOAuth2Provider extends Model
{
public function __construct()
{
$this
->addRule('$id', [
'type' => self::TYPE_STRING,
'description' => 'OAuth2 provider ID.',
'default' => '',
'example' => 'github',
])
->addRule('parameters', [
'type' => Response::MODEL_CONSOLE_OAUTH2_PROVIDER_PARAMETER,
'description' => 'List of parameters required to configure this OAuth2 provider.',
'default' => [],
'array' => true,
])
;
}
public function getName(): string
{
return 'Console OAuth2 Provider';
}
public function getType(): string
{
return Response::MODEL_CONSOLE_OAUTH2_PROVIDER;
}
}
@@ -0,0 +1,37 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
class ConsoleOAuth2ProviderList extends Model
{
public function __construct()
{
$this
->addRule('total', [
'type' => self::TYPE_INTEGER,
'description' => 'Total number of OAuth2 providers exposed by the server.',
'default' => 0,
'example' => 5,
])
->addRule('oAuth2Providers', [
'type' => Response::MODEL_CONSOLE_OAUTH2_PROVIDER,
'description' => 'List of OAuth2 providers, each with the parameters required to configure it.',
'default' => [],
'array' => true,
])
;
}
public function getName(): string
{
return 'Console OAuth2 Providers List';
}
public function getType(): string
{
return Response::MODEL_CONSOLE_OAUTH2_PROVIDER_LIST;
}
}
@@ -0,0 +1,49 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
class ConsoleOAuth2ProviderParameter extends Model
{
public function __construct()
{
$this
->addRule('$id', [
'type' => self::TYPE_STRING,
'description' => 'Parameter ID. Maps to the request body field used by the project OAuth2 update endpoint (e.g. `clientId`, `appKey`, `tenant`).',
'default' => '',
'example' => 'clientId',
])
->addRule('name', [
'type' => self::TYPE_STRING,
'description' => 'Verbose, user-facing parameter name as shown in the provider\'s own dashboard. Includes alternate names when the provider exposes more than one.',
'default' => '',
'example' => 'Client ID or App ID',
])
->addRule('example', [
'type' => self::TYPE_STRING,
'description' => 'Example value for this parameter.',
'default' => '',
'example' => 'e4d87900000000540733',
])
->addRule('hint', [
'type' => self::TYPE_STRING,
'description' => 'Optional hint for this parameter, typically calling out a common wrong value. Empty string when no hint is set.',
'default' => '',
'example' => 'Example of wrong value: 370006',
])
;
}
public function getName(): string
{
return 'Console OAuth2 Provider Parameter';
}
public function getType(): string
{
return Response::MODEL_CONSOLE_OAUTH2_PROVIDER_PARAMETER;
}
}
@@ -22,7 +22,7 @@ class OAuth2Linkedin extends OAuth2Base
public function getClientSecretExample(): string
{
return 'WPL_AP1.2Bf0000000000000';
return 'WPL_AP1.2Bf0000000000000./HtlYw==';
}
public function getClientSecretFieldName(): string
@@ -41,4 +41,91 @@ class ConsoleConsoleClientTest extends Scope
$this->assertIsString($response['body']['_APP_DB_ADAPTER']);
// When adding new keys, dont forget to update count a few lines above
}
public function testListOAuth2Providers(): void
{
$response = $this->client->call(Client::METHOD_GET, '/console/oauth2-providers', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertIsInt($response['body']['total']);
$this->assertIsArray($response['body']['oAuth2Providers']);
$this->assertGreaterThan(0, $response['body']['total']);
$this->assertEquals($response['body']['total'], \count($response['body']['oAuth2Providers']));
$providerIds = \array_column($response['body']['oAuth2Providers'], '$id');
// Well-known providers must be present
$this->assertContains('github', $providerIds);
$this->assertContains('google', $providerIds);
// Mock providers must be excluded
$this->assertNotContains('mock', $providerIds);
$this->assertNotContains('mock-unverified', $providerIds);
// Every provider has the expected shape
foreach ($response['body']['oAuth2Providers'] as $provider) {
$this->assertArrayHasKey('$id', $provider);
$this->assertIsString($provider['$id']);
$this->assertArrayHasKey('parameters', $provider);
$this->assertIsArray($provider['parameters']);
$this->assertGreaterThan(0, \count($provider['parameters']));
foreach ($provider['parameters'] as $parameter) {
$this->assertArrayHasKey('$id', $parameter);
$this->assertIsString($parameter['$id']);
$this->assertNotEmpty($parameter['$id']);
$this->assertArrayHasKey('name', $parameter);
$this->assertIsString($parameter['name']);
$this->assertNotEmpty($parameter['name']);
$this->assertArrayHasKey('example', $parameter);
$this->assertIsString($parameter['example']);
$this->assertArrayHasKey('hint', $parameter);
$this->assertIsString($parameter['hint']);
}
}
// GitHub provider has the expected metadata for clientId, including the hint
$github = null;
foreach ($response['body']['oAuth2Providers'] as $provider) {
if ($provider['$id'] === 'github') {
$github = $provider;
break;
}
}
$this->assertNotNull($github);
$this->assertCount(2, $github['parameters']);
$clientId = $github['parameters'][0];
$this->assertEquals('clientId', $clientId['$id']);
$this->assertEquals('Client ID or App ID', $clientId['name']);
$this->assertEquals('e4d87900000000540733', $clientId['example']);
$this->assertEquals('Example of wrong value: 370006', $clientId['hint']);
$clientSecret = $github['parameters'][1];
$this->assertEquals('clientSecret', $clientSecret['$id']);
$this->assertEquals('Client Secret', $clientSecret['name']);
$this->assertNotEmpty($clientSecret['example']);
$this->assertEquals('', $clientSecret['hint']);
// Multi-parameter provider (Apple) exposes its non-clientSecret fields
$apple = null;
foreach ($response['body']['oAuth2Providers'] as $provider) {
if ($provider['$id'] === 'apple') {
$apple = $provider;
break;
}
}
$this->assertNotNull($apple);
$appleParamIds = \array_column($apple['parameters'], '$id');
$this->assertContains('serviceId', $appleParamIds);
$this->assertContains('keyId', $appleParamIds);
$this->assertContains('teamId', $appleParamIds);
$this->assertContains('p8File', $appleParamIds);
// Apple does not expose a single clientSecret param
$this->assertNotContains('clientSecret', $appleParamIds);
// Sandbox providers (e.g. paypalSandbox) are included
$this->assertContains('paypalSandbox', $providerIds);
}
}
@@ -24,4 +24,23 @@ class ConsoleCustomServerTest extends Scope
$this->assertEquals(401, $response['headers']['status-code']);
}
public function testListOAuth2Providers(): void
{
// Public endpoint: must succeed without admin authentication. Drop the
// headers from getHeaders() and only pass project + content-type.
$response = $this->client->call(Client::METHOD_GET, '/console/oauth2-providers', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertIsInt($response['body']['total']);
$this->assertIsArray($response['body']['oAuth2Providers']);
$this->assertGreaterThan(0, $response['body']['total']);
$providerIds = \array_column($response['body']['oAuth2Providers'], '$id');
$this->assertContains('github', $providerIds);
$this->assertNotContains('mock', $providerIds);
}
}