show example after api token generated

This commit is contained in:
MaysWind
2025-11-03 23:05:44 +08:00
parent 03c342f6f6
commit 7c3c1bbd6a
19 changed files with 49 additions and 7 deletions
+1
View File
@@ -124,6 +124,7 @@ func (a *TokensApi) TokenGenerateAPIHandler(c *core.WebContext) (any, *errs.Erro
generateAPITokenResp := &models.TokenGenerateAPIResponse{ generateAPITokenResp := &models.TokenGenerateAPIResponse{
Token: token, Token: token,
APIBaseUrl: a.CurrentConfig().RootUrl + "api",
} }
return generateAPITokenResp, nil return generateAPITokenResp, nil
+1
View File
@@ -45,6 +45,7 @@ type TokenRevokeRequest struct {
// TokenGenerateAPIResponse represents all response parameters of generated api token // TokenGenerateAPIResponse represents all response parameters of generated api token
type TokenGenerateAPIResponse struct { type TokenGenerateAPIResponse struct {
Token string `json:"token"` Token string `json:"token"`
APIBaseUrl string `json:"apiBaseUrl"`
} }
// TokenGenerateMCPResponse represents all response parameters of generated mcp token // TokenGenerateMCPResponse represents all response parameters of generated mcp token
+1
View File
@@ -1453,6 +1453,7 @@
"Disable": "Deaktivieren", "Disable": "Deaktivieren",
"Disabled": "Deaktiviert", "Disabled": "Deaktiviert",
"Configuration": "Configuration", "Configuration": "Configuration",
"Example": "Example",
"Token": "Token", "Token": "Token",
"Copy": "Kopieren", "Copy": "Kopieren",
"Visible": "Sichtbar", "Visible": "Sichtbar",
+1
View File
@@ -1453,6 +1453,7 @@
"Disable": "Disable", "Disable": "Disable",
"Disabled": "Disabled", "Disabled": "Disabled",
"Configuration": "Configuration", "Configuration": "Configuration",
"Example": "Example",
"Token": "Token", "Token": "Token",
"Copy": "Copy", "Copy": "Copy",
"Visible": "Visible", "Visible": "Visible",
+1
View File
@@ -1453,6 +1453,7 @@
"Disable": "Desactivar", "Disable": "Desactivar",
"Disabled": "Desactivado", "Disabled": "Desactivado",
"Configuration": "Configuration", "Configuration": "Configuration",
"Example": "Example",
"Token": "Token", "Token": "Token",
"Copy": "Copiar", "Copy": "Copiar",
"Visible": "Visible", "Visible": "Visible",
+1
View File
@@ -1453,6 +1453,7 @@
"Disable": "Désactiver", "Disable": "Désactiver",
"Disabled": "Désactivé", "Disabled": "Désactivé",
"Configuration": "Configuration", "Configuration": "Configuration",
"Example": "Example",
"Token": "Jeton", "Token": "Jeton",
"Copy": "Copier", "Copy": "Copier",
"Visible": "Visible", "Visible": "Visible",
+1
View File
@@ -1453,6 +1453,7 @@
"Disable": "Disabilita", "Disable": "Disabilita",
"Disabled": "Disabilitato", "Disabled": "Disabilitato",
"Configuration": "Configuration", "Configuration": "Configuration",
"Example": "Example",
"Token": "Token", "Token": "Token",
"Copy": "Copia", "Copy": "Copia",
"Visible": "Visibile", "Visible": "Visibile",
+1
View File
@@ -1453,6 +1453,7 @@
"Disable": "無効", "Disable": "無効",
"Disabled": "無効になっています", "Disabled": "無効になっています",
"Configuration": "Configuration", "Configuration": "Configuration",
"Example": "Example",
"Token": "Token", "Token": "Token",
"Copy": "コピー", "Copy": "コピー",
"Visible": "見える", "Visible": "見える",
+1
View File
@@ -1453,6 +1453,7 @@
"Disable": "비활성화", "Disable": "비활성화",
"Disabled": "비활성화됨", "Disabled": "비활성화됨",
"Configuration": "설정", "Configuration": "설정",
"Example": "Example",
"Token": "토큰", "Token": "토큰",
"Copy": "복사", "Copy": "복사",
"Visible": "표시", "Visible": "표시",
+1
View File
@@ -1453,6 +1453,7 @@
"Disable": "Uitschakelen", "Disable": "Uitschakelen",
"Disabled": "Uitgeschakeld", "Disabled": "Uitgeschakeld",
"Configuration": "Configuratie", "Configuration": "Configuratie",
"Example": "Example",
"Token": "Token", "Token": "Token",
"Copy": "Kopiëren", "Copy": "Kopiëren",
"Visible": "Zichtbaar", "Visible": "Zichtbaar",
+1
View File
@@ -1453,6 +1453,7 @@
"Disable": "Desabilitar", "Disable": "Desabilitar",
"Disabled": "Desabilitado", "Disabled": "Desabilitado",
"Configuration": "Configuration", "Configuration": "Configuration",
"Example": "Example",
"Token": "Token", "Token": "Token",
"Copy": "Copiar", "Copy": "Copiar",
"Visible": "Visível", "Visible": "Visível",
+1
View File
@@ -1453,6 +1453,7 @@
"Disable": "Отключить", "Disable": "Отключить",
"Disabled": "Отключено", "Disabled": "Отключено",
"Configuration": "Configuration", "Configuration": "Configuration",
"Example": "Example",
"Token": "Token", "Token": "Token",
"Copy": "Копировать", "Copy": "Копировать",
"Visible": "Видимый", "Visible": "Видимый",
+1
View File
@@ -1453,6 +1453,7 @@
"Disable": "ปิดใช้งาน", "Disable": "ปิดใช้งาน",
"Disabled": "ปิดใช้งานแล้ว", "Disabled": "ปิดใช้งานแล้ว",
"Configuration": "การตั้งค่า", "Configuration": "การตั้งค่า",
"Example": "Example",
"Token": "โทเค็น", "Token": "โทเค็น",
"Copy": "คัดลอก", "Copy": "คัดลอก",
"Visible": "มองเห็น", "Visible": "มองเห็น",
+1
View File
@@ -1453,6 +1453,7 @@
"Disable": "Вимкнути", "Disable": "Вимкнути",
"Disabled": "Вимкнено", "Disabled": "Вимкнено",
"Configuration": "Configuration", "Configuration": "Configuration",
"Example": "Example",
"Token": "Token", "Token": "Token",
"Copy": "Копіювати", "Copy": "Копіювати",
"Visible": "Видимий", "Visible": "Видимий",
+1
View File
@@ -1453,6 +1453,7 @@
"Disable": "Tắt", "Disable": "Tắt",
"Disabled": "Đã tắt", "Disabled": "Đã tắt",
"Configuration": "Configuration", "Configuration": "Configuration",
"Example": "Example",
"Token": "Token", "Token": "Token",
"Copy": "Sao chép", "Copy": "Sao chép",
"Visible": "Hiển thị", "Visible": "Hiển thị",
+1
View File
@@ -1453,6 +1453,7 @@
"Disable": "禁用", "Disable": "禁用",
"Disabled": "禁用", "Disabled": "禁用",
"Configuration": "配置", "Configuration": "配置",
"Example": "示例",
"Token": "令牌", "Token": "令牌",
"Copy": "复制", "Copy": "复制",
"Visible": "可见", "Visible": "可见",
+1
View File
@@ -1453,6 +1453,7 @@
"Disable": "停用", "Disable": "停用",
"Disabled": "停用", "Disabled": "停用",
"Configuration": "設定", "Configuration": "設定",
"Example": "範例",
"Token": "令牌", "Token": "令牌",
"Copy": "複製", "Copy": "複製",
"Visible": "可見", "Visible": "可見",
+1
View File
@@ -21,6 +21,7 @@ export interface TokenRevokeRequest {
export interface TokenGenerateAPIResponse { export interface TokenGenerateAPIResponse {
readonly token: string; readonly token: string;
readonly apiBaseUrl: string;
} }
export interface TokenGenerateMCPResponse { export interface TokenGenerateMCPResponse {
@@ -7,6 +7,17 @@
</div> </div>
</template> </template>
<v-card-text class="py-0 w-100 d-flex justify-center" v-if="tokenType === 'api' && generatedToken && serverUrl">
<v-switch class="bidirectional-switch" color="secondary"
:label="tt('Example')"
v-model="showAPIExample"
@click="showAPIExample = !showAPIExample">
<template #prepend>
<span>{{ tt('Token') }}</span>
</template>
</v-switch>
</v-card-text>
<v-card-text class="py-0 w-100 d-flex justify-center" v-if="tokenType === 'mcp' && generatedToken && serverUrl"> <v-card-text class="py-0 w-100 d-flex justify-center" v-if="tokenType === 'mcp' && generatedToken && serverUrl">
<v-switch class="bidirectional-switch" color="secondary" <v-switch class="bidirectional-switch" color="secondary"
:label="tt('Configuration')" :label="tt('Configuration')"
@@ -78,11 +89,14 @@
</v-col> </v-col>
</v-row> </v-row>
</div> </div>
<div class="w-100 code-container" v-if="generatedToken"> <div class="w-100 code-container" v-if="generatedToken">
<v-textarea class="w-100 always-cursor-text" :readonly="true" <v-textarea class="w-100 always-cursor-text" :readonly="true"
:rows="4" :value="generatedToken" v-if="!showMCPConfiguration || !serverUrl" /> :rows="4" :value="generatedToken" v-if="(tokenType === 'api' && (!showAPIExample || !serverUrl)) || (tokenType === 'mcp' && (!showMCPConfiguration || !serverUrl))" />
<v-textarea class="w-100 always-cursor-text" :readonly="true" <v-textarea class="w-100 always-cursor-text" :readonly="true"
:rows="15" :value="mcpServerConfiguration" v-if="showMCPConfiguration && serverUrl" /> :rows="5" :value="apiExample" v-if="tokenType === 'api' && showAPIExample && serverUrl" />
<v-textarea class="w-100 always-cursor-text" :readonly="true"
:rows="15" :value="mcpServerConfiguration" v-if="tokenType === 'mcp' && showMCPConfiguration && serverUrl" />
</div> </div>
</v-card-text> </v-card-text>
@@ -121,7 +135,7 @@ import { useI18n } from '@/locales/helpers.ts';
import { useTokensStore } from '@/stores/token.ts'; import { useTokensStore } from '@/stores/token.ts';
import { type NameValue } from '@/core/base.ts'; import { type NameValue } from '@/core/base.ts';
import { type TokenGenerateMCPResponse } from '@/models/token.ts'; import { type TokenGenerateAPIResponse, type TokenGenerateMCPResponse } from '@/models/token.ts';
import { isAPITokenEnabled, isMCPServerEnabled } from '@/lib/server_settings.ts'; import { isAPITokenEnabled, isMCPServerEnabled } from '@/lib/server_settings.ts';
import { copyTextToClipboard } from '@/lib/ui/common.ts'; import { copyTextToClipboard } from '@/lib/ui/common.ts';
@@ -144,6 +158,7 @@ const tokenExpirationTime = ref<number>(86400);
const tokenCustomExpirationTime = ref<number>(86400); const tokenCustomExpirationTime = ref<number>(86400);
const currentPassword = ref<string>(''); const currentPassword = ref<string>('');
const generating = ref<boolean>(false); const generating = ref<boolean>(false);
const showAPIExample = ref<boolean>(false);
const showMCPConfiguration = ref<boolean>(false); const showMCPConfiguration = ref<boolean>(false);
const serverUrl = ref<string>(''); const serverUrl = ref<string>('');
const generatedToken = ref<string>(''); const generatedToken = ref<string>('');
@@ -162,6 +177,10 @@ const tokenTypeOptions = computed<NameValue[]>(() => {
return options; return options;
}); });
const apiExample = computed<string>(() => {
return `curl -H 'Authorization: Bearer ${generatedToken.value}' '${serverUrl.value}/v1/users/profile/get.json'`;
});
const mcpServerConfiguration = computed<string>(() => { const mcpServerConfiguration = computed<string>(() => {
return '{\n' + return '{\n' +
' "mcpServers": {\n' + ' "mcpServers": {\n' +
@@ -183,6 +202,7 @@ function open(): Promise<void> {
tokenExpirationTime.value = 86400; tokenExpirationTime.value = 86400;
tokenCustomExpirationTime.value = 86400; tokenCustomExpirationTime.value = 86400;
generating.value = false; generating.value = false;
showAPIExample.value = false;
showMCPConfiguration.value = false; showMCPConfiguration.value = false;
serverUrl.value = ''; serverUrl.value = '';
generatedToken.value = ''; generatedToken.value = '';
@@ -208,7 +228,9 @@ function generateToken(): void {
generating.value = false; generating.value = false;
currentPassword.value = ''; currentPassword.value = '';
if (tokenType.value === 'mcp') { if (tokenType.value === 'api') {
serverUrl.value = (result as TokenGenerateAPIResponse).apiBaseUrl;
} else if (tokenType.value === 'mcp') {
serverUrl.value = (result as TokenGenerateMCPResponse).mcpUrl; serverUrl.value = (result as TokenGenerateMCPResponse).mcpUrl;
} }
@@ -223,7 +245,9 @@ function generateToken(): void {
} }
function copy(): void { function copy(): void {
if (showMCPConfiguration.value) { if (tokenType.value === 'api' && showAPIExample.value) {
copyTextToClipboard(apiExample.value, buttonContainer.value);
} else if (tokenType.value === 'mcp' && showMCPConfiguration.value) {
copyTextToClipboard(mcpServerConfiguration.value, buttonContainer.value); copyTextToClipboard(mcpServerConfiguration.value, buttonContainer.value);
} else { } else {
copyTextToClipboard(generatedToken.value, buttonContainer.value); copyTextToClipboard(generatedToken.value, buttonContainer.value);