friendship ended with social-app. php is my new best friend
1<?php
2/**
3 * Class Discord
4 *
5 * @created 22.10.2017
6 * @author Smiley <smiley@chillerlan.net>
7 * @copyright 2017 Smiley
8 * @license MIT
9 *
10 * @noinspection PhpUnused
11 */
12declare(strict_types=1);
13
14namespace chillerlan\OAuth\Providers;
15
16use chillerlan\OAuth\Core\{
17 AccessToken, AuthenticatedUser, ClientCredentials, ClientCredentialsTrait, CSRFToken,
18 OAuth2Provider, TokenInvalidate, TokenInvalidateTrait, TokenRefresh, UserInfo,
19};
20use function sprintf;
21
22/**
23 * Discord OAuth2
24 *
25 * @link https://discord.com/developers/docs/topics/oauth2
26 */
27class Discord extends OAuth2Provider implements ClientCredentials, CSRFToken, TokenInvalidate, TokenRefresh, UserInfo{
28 use ClientCredentialsTrait, TokenInvalidateTrait;
29
30 public const IDENTIFIER = 'DISCORD';
31
32 public const SCOPE_APPLICATIONS_COMMANDS = 'applications.commands';
33 public const SCOPE_APPLICATIONS_COMMANDS_UPDATE = 'applications.commands.update';
34 public const SCOPE_APPLICATIONS_COMMANDS_PERMISSIONS_UPDATE = 'applications.commands.permissions.update';
35 public const SCOPE_APPLICATIONS_ENTITLEMENTS = 'applications.entitlements';
36 public const SCOPE_BOT = 'bot';
37 public const SCOPE_CONNECTIONS = 'connections';
38 public const SCOPE_EMAIL = 'email';
39 public const SCOPE_GDM_JOIN = 'gdm.join';
40 public const SCOPE_GUILDS = 'guilds';
41 public const SCOPE_GUILDS_JOIN = 'guilds.join';
42 public const SCOPE_GUILDS_MEMBERS_READ = 'guilds.members.read';
43 public const SCOPE_IDENTIFY = 'identify';
44 public const SCOPE_MESSAGES_READ = 'messages.read';
45 public const SCOPE_RELATIONSHIPS_READ = 'relationships.read';
46 public const SCOPE_ROLE_CONNECTIONS_WRITE = 'role_connections.write';
47 public const SCOPE_RPC = 'rpc';
48 public const SCOPE_RPC_ACTIVITIES_WRITE = 'rpc.activities.write';
49 public const SCOPE_RPC_NOTIFICATIONS_READ = 'rpc.notifications.read';
50 public const SCOPE_WEBHOOK_INCOMING = 'webhook.incoming';
51
52 public const DEFAULT_SCOPES = [
53 self::SCOPE_CONNECTIONS,
54 self::SCOPE_EMAIL,
55 self::SCOPE_IDENTIFY,
56 self::SCOPE_GUILDS,
57 self::SCOPE_GUILDS_JOIN,
58 self::SCOPE_GDM_JOIN,
59 self::SCOPE_MESSAGES_READ,
60 ];
61
62 protected string $authorizationURL = 'https://discordapp.com/api/oauth2/authorize';
63 protected string $accessTokenURL = 'https://discordapp.com/api/oauth2/token';
64 protected string $revokeURL = 'https://discordapp.com/api/oauth2/token/revoke';
65 protected string $apiURL = 'https://discordapp.com/api';
66 protected string|null $apiDocs = 'https://discord.com/developers/';
67 protected string|null $applicationURL = 'https://discordapp.com/developers/applications/';
68
69 /**
70 * @link https://github.com/discord/discord-api-docs/issues/2259#issuecomment-927180184
71 * @return array<string, scalar|bool|null>
72 */
73 protected function getInvalidateAccessTokenBodyParams(AccessToken $token, string $type):array{
74 return [
75 'client_id' => $this->options->key,
76 'client_secret' => $this->options->secret,
77 'token' => $token->accessToken,
78 'token_type_hint' => $type,
79 ];
80 }
81
82 /** @codeCoverageIgnore */
83 public function me():AuthenticatedUser{
84 $json = $this->getMeResponseData('/users/@me');
85
86 $userdata = [
87 'data' => $json,
88 'avatar' => sprintf('https://cdn.discordapp.com/avatars/%s/%s.png', $json['id'], $json['avatar']),
89 'displayName' => $json['global_name'],
90 'email' => $json['email'],
91 'handle' => $json['username'],
92 'id' => $json['id'],
93 'url' => sprintf('https://discordapp.com/users/%s', $json['id']), // @me
94 ];
95
96 return new AuthenticatedUser($userdata);
97 }
98
99}