✏️ Reformat and improve readability of authentication-related UI and code structure
This commit is contained in:
@@ -16,7 +16,9 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<h1>🔐 Authentication Settings</h1>
|
<h1>🔐 Authentication Settings</h1>
|
||||||
<p class="subtitle">Manage your authentication credentials and tokens across all platforms</p>
|
<p class="subtitle">
|
||||||
|
Manage your authentication credentials and tokens across all platforms
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Tabs Navigation -->
|
<!-- Tabs Navigation -->
|
||||||
@@ -47,7 +49,8 @@
|
|||||||
<div v-if="activePlatform === 'challonge'" class="platform-section">
|
<div v-if="activePlatform === 'challonge'" class="platform-section">
|
||||||
<h2>🏆 Challonge Authentication</h2>
|
<h2>🏆 Challonge Authentication</h2>
|
||||||
<p class="platform-description">
|
<p class="platform-description">
|
||||||
Configure your Challonge API access using API keys, OAuth tokens, or client credentials
|
Configure your Challonge API access using API keys, OAuth tokens, or
|
||||||
|
client credentials
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- API Key Section -->
|
<!-- API Key Section -->
|
||||||
@@ -58,7 +61,9 @@
|
|||||||
{{ hasChallongeApiKey ? '✓ Connected' : '○ Not Connected' }}
|
{{ hasChallongeApiKey ? '✓ Connected' : '○ Not Connected' }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<p class="method-description">Direct API key authentication for v1 and v2.1 APIs</p>
|
<p class="method-description">
|
||||||
|
Direct API key authentication for v1 and v2.1 APIs
|
||||||
|
</p>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input
|
<input
|
||||||
v-model="challongeApiKey"
|
v-model="challongeApiKey"
|
||||||
@@ -69,13 +74,19 @@
|
|||||||
<button @click="saveChallongeApiKey" class="btn btn-primary">
|
<button @click="saveChallongeApiKey" class="btn btn-primary">
|
||||||
{{ hasChallongeApiKey ? 'Update' : 'Save' }} API Key
|
{{ hasChallongeApiKey ? 'Update' : 'Save' }} API Key
|
||||||
</button>
|
</button>
|
||||||
<button v-if="hasChallongeApiKey" @click="deleteChallongeApiKey" class="btn btn-danger">
|
<button
|
||||||
|
v-if="hasChallongeApiKey"
|
||||||
|
@click="deleteChallongeApiKey"
|
||||||
|
class="btn btn-danger"
|
||||||
|
>
|
||||||
Delete
|
Delete
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<p class="help-text">
|
<p class="help-text">
|
||||||
Get your API key from
|
Get your API key from
|
||||||
<a href="https://challonge.com/settings/developer" target="_blank">Challonge Developer Settings</a>
|
<a href="https://challonge.com/settings/developer" target="_blank"
|
||||||
|
>Challonge Developer Settings</a
|
||||||
|
>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -83,12 +94,20 @@
|
|||||||
<div class="auth-method">
|
<div class="auth-method">
|
||||||
<div class="method-header">
|
<div class="method-header">
|
||||||
<h3>OAuth 2.0</h3>
|
<h3>OAuth 2.0</h3>
|
||||||
<span :class="['status', { active: isChallongeOAuthAuthenticated }]">
|
<span
|
||||||
{{ isChallongeOAuthAuthenticated ? '✓ Connected' : '○ Not Connected' }}
|
:class="['status', { active: isChallongeOAuthAuthenticated }]"
|
||||||
|
>
|
||||||
|
{{
|
||||||
|
isChallongeOAuthAuthenticated
|
||||||
|
? '✓ Connected'
|
||||||
|
: '○ Not Connected'
|
||||||
|
}}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<p class="method-description">User token authentication for v2.1 API (APPLICATION scope)</p>
|
<p class="method-description">
|
||||||
|
User token authentication for v2.1 API (APPLICATION scope)
|
||||||
|
</p>
|
||||||
|
|
||||||
<div v-if="isChallongeOAuthAuthenticated" class="token-info">
|
<div v-if="isChallongeOAuthAuthenticated" class="token-info">
|
||||||
<div class="token-detail">
|
<div class="token-detail">
|
||||||
<span class="label">Status:</span>
|
<span class="label">Status:</span>
|
||||||
@@ -96,31 +115,52 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="token-detail">
|
<div class="token-detail">
|
||||||
<span class="label">Expires in:</span>
|
<span class="label">Expires in:</span>
|
||||||
<span class="value">{{ formatExpiryTime(challongeOAuthExpiresIn) }}</span>
|
<span class="value">{{
|
||||||
|
formatExpiryTime(challongeOAuthExpiresIn)
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="challongeOAuthRefreshedAt" class="token-detail">
|
<div v-if="challongeOAuthRefreshedAt" class="token-detail">
|
||||||
<span class="label">Last refreshed:</span>
|
<span class="label">Last refreshed:</span>
|
||||||
<span class="value">{{ formatDate(challongeOAuthRefreshedAt) }}</span>
|
<span class="value">{{
|
||||||
|
formatDate(challongeOAuthRefreshedAt)
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-group">
|
<div class="button-group">
|
||||||
<button @click="refreshChallongeOAuth" :disabled="oauthLoading" class="btn btn-secondary">
|
<button
|
||||||
|
@click="refreshChallongeOAuth"
|
||||||
|
:disabled="oauthLoading"
|
||||||
|
class="btn btn-secondary"
|
||||||
|
>
|
||||||
{{ oauthLoading ? '⏳ Refreshing...' : '🔄 Refresh Token' }}
|
{{ oauthLoading ? '⏳ Refreshing...' : '🔄 Refresh Token' }}
|
||||||
</button>
|
</button>
|
||||||
<button @click="disconnectChallongeOAuth" class="btn btn-danger">
|
<button
|
||||||
|
@click="disconnectChallongeOAuth"
|
||||||
|
class="btn btn-danger"
|
||||||
|
>
|
||||||
Disconnect
|
Disconnect
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else class="button-group">
|
<div v-else class="button-group">
|
||||||
<button @click="connectChallongeOAuth" :disabled="oauthLoading" class="btn btn-primary">
|
<button
|
||||||
{{ oauthLoading ? '⏳ Connecting...' : '🔗 Connect with Challonge OAuth' }}
|
@click="connectChallongeOAuth"
|
||||||
|
:disabled="oauthLoading"
|
||||||
|
class="btn btn-primary"
|
||||||
|
>
|
||||||
|
{{
|
||||||
|
oauthLoading
|
||||||
|
? '⏳ Connecting...'
|
||||||
|
: '🔗 Connect with Challonge OAuth'
|
||||||
|
}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="help-text">
|
<p class="help-text">
|
||||||
Register your application at
|
Register your application at
|
||||||
<a href="https://connect.challonge.com" target="_blank">Challonge OAuth</a>
|
<a href="https://connect.challonge.com" target="_blank"
|
||||||
|
>Challonge OAuth</a
|
||||||
|
>
|
||||||
and use it for APPLICATION scope access
|
and use it for APPLICATION scope access
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -129,12 +169,20 @@
|
|||||||
<div class="auth-method">
|
<div class="auth-method">
|
||||||
<div class="method-header">
|
<div class="method-header">
|
||||||
<h3>Client Credentials</h3>
|
<h3>Client Credentials</h3>
|
||||||
<span :class="['status', { active: hasChallongeClientCredentials }]">
|
<span
|
||||||
{{ hasChallongeClientCredentials ? '✓ Connected' : '○ Not Connected' }}
|
:class="['status', { active: hasChallongeClientCredentials }]"
|
||||||
|
>
|
||||||
|
{{
|
||||||
|
hasChallongeClientCredentials
|
||||||
|
? '✓ Connected'
|
||||||
|
: '○ Not Connected'
|
||||||
|
}}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<p class="method-description">For APPLICATION scope access with client ID and secret</p>
|
<p class="method-description">
|
||||||
|
For APPLICATION scope access with client ID and secret
|
||||||
|
</p>
|
||||||
|
|
||||||
<div v-if="hasChallongeClientCredentials" class="token-info">
|
<div v-if="hasChallongeClientCredentials" class="token-info">
|
||||||
<div class="token-detail">
|
<div class="token-detail">
|
||||||
<span class="label">Client ID:</span>
|
<span class="label">Client ID:</span>
|
||||||
@@ -142,14 +190,21 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="token-detail">
|
<div class="token-detail">
|
||||||
<span class="label">Status:</span>
|
<span class="label">Status:</span>
|
||||||
<span class="value">{{ isChallongeClientCredentialsValid ? '✅ Valid' : '⚠️ Expired' }}</span>
|
<span class="value">{{
|
||||||
|
isChallongeClientCredentialsValid ? '✅ Valid' : '⚠️ Expired'
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="challongeClientExpiresIn" class="token-detail">
|
<div v-if="challongeClientExpiresIn" class="token-detail">
|
||||||
<span class="label">Token expires in:</span>
|
<span class="label">Token expires in:</span>
|
||||||
<span class="value">{{ formatExpiryTime(challongeClientExpiresIn) }}</span>
|
<span class="value">{{
|
||||||
|
formatExpiryTime(challongeClientExpiresIn)
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-group">
|
<div class="button-group">
|
||||||
<button @click="deleteChallongeClientCredentials" class="btn btn-danger">
|
<button
|
||||||
|
@click="deleteChallongeClientCredentials"
|
||||||
|
class="btn btn-danger"
|
||||||
|
>
|
||||||
Delete
|
Delete
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -169,7 +224,10 @@
|
|||||||
placeholder="Client Secret"
|
placeholder="Client Secret"
|
||||||
@keyup.enter="saveChallongeClientCredentials"
|
@keyup.enter="saveChallongeClientCredentials"
|
||||||
/>
|
/>
|
||||||
<button @click="saveChallongeClientCredentials" class="btn btn-primary">
|
<button
|
||||||
|
@click="saveChallongeClientCredentials"
|
||||||
|
class="btn btn-primary"
|
||||||
|
>
|
||||||
Save Client Credentials
|
Save Client Credentials
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -177,7 +235,9 @@
|
|||||||
|
|
||||||
<p class="help-text">
|
<p class="help-text">
|
||||||
Get credentials from
|
Get credentials from
|
||||||
<a href="https://challonge.com/settings/developer" target="_blank">Challonge Developer Settings</a>
|
<a href="https://challonge.com/settings/developer" target="_blank"
|
||||||
|
>Challonge Developer Settings</a
|
||||||
|
>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -186,7 +246,8 @@
|
|||||||
<div v-if="activePlatform === 'discord'" class="platform-section">
|
<div v-if="activePlatform === 'discord'" class="platform-section">
|
||||||
<h2>🎮 Discord Authentication</h2>
|
<h2>🎮 Discord Authentication</h2>
|
||||||
<p class="platform-description">
|
<p class="platform-description">
|
||||||
Verify your Discord identity for access control and developer features
|
Verify your Discord identity for access control and developer
|
||||||
|
features
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="auth-method">
|
<div class="auth-method">
|
||||||
@@ -196,7 +257,9 @@
|
|||||||
{{ isDiscordAuthenticated ? '✓ Connected' : '○ Not Connected' }}
|
{{ isDiscordAuthenticated ? '✓ Connected' : '○ Not Connected' }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<p class="method-description">Secure identity verification using Discord account</p>
|
<p class="method-description">
|
||||||
|
Secure identity verification using Discord account
|
||||||
|
</p>
|
||||||
|
|
||||||
<div v-if="isDiscordAuthenticated" class="token-info">
|
<div v-if="isDiscordAuthenticated" class="token-info">
|
||||||
<div class="token-detail">
|
<div class="token-detail">
|
||||||
@@ -209,10 +272,16 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-if="discordExpiresIn" class="token-detail">
|
<div v-if="discordExpiresIn" class="token-detail">
|
||||||
<span class="label">Expires in:</span>
|
<span class="label">Expires in:</span>
|
||||||
<span class="value">{{ formatExpiryTime(discordExpiresIn) }}</span>
|
<span class="value">{{
|
||||||
|
formatExpiryTime(discordExpiresIn)
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-group">
|
<div class="button-group">
|
||||||
<button @click="refreshDiscordAuth" :disabled="discordLoading" class="btn btn-secondary">
|
<button
|
||||||
|
@click="refreshDiscordAuth"
|
||||||
|
:disabled="discordLoading"
|
||||||
|
class="btn btn-secondary"
|
||||||
|
>
|
||||||
{{ discordLoading ? '⏳ Refreshing...' : '🔄 Refresh' }}
|
{{ discordLoading ? '⏳ Refreshing...' : '🔄 Refresh' }}
|
||||||
</button>
|
</button>
|
||||||
<button @click="disconnectDiscord" class="btn btn-danger">
|
<button @click="disconnectDiscord" class="btn btn-danger">
|
||||||
@@ -222,14 +291,26 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else class="button-group">
|
<div v-else class="button-group">
|
||||||
<button @click="connectDiscord" :disabled="discordLoading" class="btn btn-primary">
|
<button
|
||||||
{{ discordLoading ? '⏳ Connecting...' : '🔗 Connect with Discord' }}
|
@click="connectDiscord"
|
||||||
|
:disabled="discordLoading"
|
||||||
|
class="btn btn-primary"
|
||||||
|
>
|
||||||
|
{{
|
||||||
|
discordLoading
|
||||||
|
? '⏳ Connecting...'
|
||||||
|
: '🔗 Connect with Discord'
|
||||||
|
}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="help-text">
|
<p class="help-text">
|
||||||
Create Discord application at
|
Create Discord application at
|
||||||
<a href="https://discord.com/developers/applications" target="_blank">Discord Developer Portal</a>
|
<a
|
||||||
|
href="https://discord.com/developers/applications"
|
||||||
|
target="_blank"
|
||||||
|
>Discord Developer Portal</a
|
||||||
|
>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -237,7 +318,10 @@
|
|||||||
|
|
||||||
<!-- Footer -->
|
<!-- Footer -->
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<p>Your authentication tokens are stored securely in your browser's local storage.</p>
|
<p>
|
||||||
|
Your authentication tokens are stored securely in your browser's local
|
||||||
|
storage.
|
||||||
|
</p>
|
||||||
<router-link to="/" class="btn-link">← Back Home</router-link>
|
<router-link to="/" class="btn-link">← Back Home</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -260,24 +344,39 @@ const oauthLoading = ref(false);
|
|||||||
const discordLoading = ref(false);
|
const discordLoading = ref(false);
|
||||||
|
|
||||||
// Challonge API Key
|
// Challonge API Key
|
||||||
const { apiKey: challongeApiKey, save: saveApiKey, delete: deleteApiKey } = useChallongeApiKey();
|
const {
|
||||||
|
apiKey: challongeApiKey,
|
||||||
|
save: saveApiKey,
|
||||||
|
delete: deleteApiKey
|
||||||
|
} = useChallongeApiKey();
|
||||||
const newChallongeApiKey = ref('');
|
const newChallongeApiKey = ref('');
|
||||||
const hasChallongeApiKey = computed(() => !!challongeApiKey.value);
|
const hasChallongeApiKey = computed(() => !!challongeApiKey.value);
|
||||||
|
|
||||||
// Challonge OAuth
|
// Challonge OAuth
|
||||||
const challongeOAuth = useChallongeOAuth();
|
const challongeOAuth = useChallongeOAuth();
|
||||||
const isChallongeOAuthAuthenticated = computed(() => challongeOAuth.isAuthenticated.value);
|
const isChallongeOAuthAuthenticated = computed(
|
||||||
|
() => challongeOAuth.isAuthenticated.value
|
||||||
|
);
|
||||||
const challongeOAuthExpiresIn = computed(() => challongeOAuth.expiresIn.value);
|
const challongeOAuthExpiresIn = computed(() => challongeOAuth.expiresIn.value);
|
||||||
const challongeOAuthRefreshedAt = computed(() => {
|
const challongeOAuthRefreshedAt = computed(() => {
|
||||||
return challongeOAuth.tokens.value?.refreshed_at || challongeOAuth.tokens.value?.created_at;
|
return (
|
||||||
|
challongeOAuth.tokens.value?.refreshed_at ||
|
||||||
|
challongeOAuth.tokens.value?.created_at
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Challonge Client Credentials
|
// Challonge Client Credentials
|
||||||
const challengeClientCreds = useChallongeClientCredentials();
|
const challengeClientCreds = useChallongeClientCredentials();
|
||||||
const hasChallongeClientCredentials = computed(() => challengeClientCreds.isConfigured.value);
|
const hasChallongeClientCredentials = computed(
|
||||||
const isChallongeClientCredentialsValid = computed(() => challengeClientCreds.isValid.value);
|
() => challengeClientCreds.isConfigured.value
|
||||||
|
);
|
||||||
|
const isChallongeClientCredentialsValid = computed(
|
||||||
|
() => challengeClientCreds.isValid.value
|
||||||
|
);
|
||||||
const challongeClientId = computed(() => challengeClientCreds.clientId.value);
|
const challongeClientId = computed(() => challengeClientCreds.clientId.value);
|
||||||
const challongeClientExpiresIn = computed(() => challengeClientCreds.expiresIn.value);
|
const challongeClientExpiresIn = computed(
|
||||||
|
() => challengeClientCreds.expiresIn.value
|
||||||
|
);
|
||||||
const newClientId = ref('');
|
const newClientId = ref('');
|
||||||
const newClientSecret = ref('');
|
const newClientSecret = ref('');
|
||||||
|
|
||||||
@@ -334,7 +433,11 @@ async function refreshChallongeOAuth() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function disconnectChallongeOAuth() {
|
function disconnectChallongeOAuth() {
|
||||||
if (confirm('Disconnect Challonge OAuth? You will need to reconnect to use OAuth features.')) {
|
if (
|
||||||
|
confirm(
|
||||||
|
'Disconnect Challonge OAuth? You will need to reconnect to use OAuth features.'
|
||||||
|
)
|
||||||
|
) {
|
||||||
challongeOAuth.logout();
|
challongeOAuth.logout();
|
||||||
successMessage.value = 'Disconnected from Challonge OAuth';
|
successMessage.value = 'Disconnected from Challonge OAuth';
|
||||||
setTimeout(() => (successMessage.value = ''), 3000);
|
setTimeout(() => (successMessage.value = ''), 3000);
|
||||||
@@ -385,7 +488,11 @@ async function refreshDiscordAuth() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function disconnectDiscord() {
|
function disconnectDiscord() {
|
||||||
if (confirm('Disconnect Discord? You will need to reconnect for Discord features.')) {
|
if (
|
||||||
|
confirm(
|
||||||
|
'Disconnect Discord? You will need to reconnect for Discord features.'
|
||||||
|
)
|
||||||
|
) {
|
||||||
discord.logout();
|
discord.logout();
|
||||||
successMessage.value = 'Disconnected from Discord';
|
successMessage.value = 'Disconnected from Discord';
|
||||||
setTimeout(() => (successMessage.value = ''), 3000);
|
setTimeout(() => (successMessage.value = ''), 3000);
|
||||||
@@ -786,22 +893,8 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
```
|
``` --- ## Summary All code is ready to apply. The order is: 1. Update router.js
|
||||||
|
(simple, unblocks routes) 2. Update OAuthCallback.vue (enables OAuth callback)
|
||||||
---
|
3. Update DeveloperTools.vue (simple property update) 4. Update .env (add
|
||||||
|
Discord credentials) 5. Create AuthenticationHub.vue (largest file) 6. Update
|
||||||
## Summary
|
ChallongeTest.vue (remove auth sections, add link) 7. Build and test ```` ```
|
||||||
|
|
||||||
All code is ready to apply. The order is:
|
|
||||||
1. Update router.js (simple, unblocks routes)
|
|
||||||
2. Update OAuthCallback.vue (enables OAuth callback)
|
|
||||||
3. Update DeveloperTools.vue (simple property update)
|
|
||||||
4. Update .env (add Discord credentials)
|
|
||||||
5. Create AuthenticationHub.vue (largest file)
|
|
||||||
6. Update ChallongeTest.vue (remove auth sections, add link)
|
|
||||||
7. Build and test
|
|
||||||
|
|
||||||
|
|
||||||
````
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|||||||
Reference in New Issue
Block a user