feat(openvpn): suggest available OIDC ports and add deployment assets

This commit is contained in:
opsx committed 2026-10-21 01:19:49 +08:00
1 parent d6a9a92ad0
commit 003f755b37
14 files changed
+244 -7

No files matched your search

+36 -2
View File
@@ -30,7 +30,11 @@
<div class="field-tip">{{ $t('oidcGuide.baseTip') }}</div>
</el-form-item>
<el-form-item :label="$t('oidcGuide.listenPort')">
<el-input-number v-model="config.oidc_http_port" :min="1024" :max="65535" />
<div class="port-controls">
<el-button :disabled="portLoading || !config.oidc_http_port || config.oidc_http_port <= 1024" @click="stepPort(-1)">−</el-button>
<el-input-number v-model="config.oidc_http_port" :controls="false" :min="1024" :max="65535" :disabled="portLoading" @change="changePort" />
<el-button :disabled="portLoading || !config.oidc_http_port || config.oidc_http_port >= 65535" @click="stepPort(1)">+</el-button>
</div>
<div class="field-tip">{{ $t('oidcGuide.portTip') }}</div>
</el-form-item>
<el-alert type="warning" :closable="false" class="guide-alert" :title="$t('oidcGuide.callbackTitle')">
@@ -44,9 +48,38 @@
</template>
<script setup>
import { computed } from 'vue'
import { computed, onMounted, ref } from 'vue'
import { ElMessage } from 'element-plus'
import { useI18n } from 'vue-i18n'
import api from '../api'
const props = defineProps({ config: { type: Object, required: true }, editing: { type: Boolean, default: false } })
const { t } = useI18n()
const portLoading = ref(false)
async function requestPort(from, direction, previous = null) {
portLoading.value = true
try {
const params = from == null ? {} : { from, direction }
const { data } = await api.get('/tunnels/openvpn/oidc-port', { params })
props.config.oidc_http_port = data.port
} catch (error) {
if (Number.isInteger(previous)) props.config.oidc_http_port = previous
ElMessage.error(error.response?.data?.error || t('oidcGuide.portLookupFailed'))
} finally {
portLoading.value = false
}
}
function stepPort(direction) {
const previous = Number(props.config.oidc_http_port)
requestPort(previous + direction, direction, previous)
}
function changePort(value, previous) {
if (!Number.isInteger(value) || value === previous) return
requestPort(value, value < previous ? -1 : 1, previous)
}
onMounted(() => {
if (!props.editing) requestPort(null, 1)
})
const callbackUrl = computed(() => `${(props.config.oidc_base_url || 'https://vpn-login.example.com').replace(/\/+$/, '')}/oauth2/callback`)
const guideStep = computed(() => !props.config.oidc_client_id ? 0
: !props.config.oidc_issuer || (!props.config.oidc_client_secret && !props.editing) ? 1
@@ -61,6 +94,7 @@ const guideStep = computed(() => !props.config.oidc_client_id ? 0
.guide-alert p { margin: 8px 0 0; line-height: 1.5; }
.guide-alert ol { padding-left: 20px; line-height: 1.7; }
.field-tip { margin-top: 4px; color: var(--text-secondary); font-size: 12px; line-height: 1.5; }
.port-controls { display: flex; gap: 6px; align-items: center; }
code { overflow-wrap: anywhere; }
@media (max-width: 720px) { .guide-steps { overflow-x: auto; justify-content: flex-start; } .guide-steps :deep(.el-step) { min-width: 120px; } }
</style>