diff --git a/src/dashboard/scoreko-dev/views/Players.vue b/src/dashboard/scoreko-dev/views/Players.vue index be6c0da..9b82b53 100644 --- a/src/dashboard/scoreko-dev/views/Players.vue +++ b/src/dashboard/scoreko-dev/views/Players.vue @@ -506,7 +506,7 @@ const loadChallongeRecentTournaments = async () => { hasValidatedChallongeToken.value = false; const message = error instanceof Error ? error.message : 'Could not load tournaments.'; challongeTournamentsError.value = message.includes('401') - ? 'Challonge rejected the token (401 Unauthorized). Verify OAuth callback/client credentials or paste a valid personal API token.' + ? 'Challonge rejected the token (401 Unauthorized). Re-connect OAuth so it grants scopes (me, tournaments:read, participants:read) or paste a valid personal API token.' : message; challongeRecentTournaments.value = []; } finally { diff --git a/src/extension/challonge.ts b/src/extension/challonge.ts index 7984bf0..30f8b9d 100644 --- a/src/extension/challonge.ts +++ b/src/extension/challonge.ts @@ -5,6 +5,15 @@ import { nodecg } from './util/nodecg.js'; const CHALLONGE_API_BASE = 'https://api.challonge.com/v2.1'; const CHALLONGE_OAUTH_AUTHORIZE_ENDPOINT = 'https://api.challonge.com/oauth/authorize'; const CHALLONGE_OAUTH_TOKEN_ENDPOINT = 'https://api.challonge.com/oauth/token'; +const CHALLONGE_OAUTH_SCOPES = [ + 'me', + 'tournaments:read', + 'tournaments:write', + 'matches:read', + 'matches:write', + 'participants:read', + 'participants:write', +].join(' '); const CHALLONGE_OAUTH_CALLBACK_PATH = '/challonge/callback'; const CHALLONGE_OAUTH_DEFAULT_PORT = 34921; const CHALLONGE_OAUTH_SESSION_TTL_MS = 10 * 60 * 1000; @@ -448,6 +457,7 @@ nodecg.listenFor('challonge:createOAuthSession', async (_payload: unknown, ack) response_type: 'code', client_id: oauthConfig.clientId, redirect_uri: getCallbackUrl(oauthConfig.callbackPort), + scope: CHALLONGE_OAUTH_SCOPES, state, });