网站首页 网站源码
website
站点相关全部源代码,隐藏了一些关于服务器的信息
@{
    Layout = null;
}

<!DOCTYPE html>

<html lang="zh-Hans">
<head>
    <title>SecurityStamp迁移工具 - 认证中心</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <link rel="stylesheet" href="@Url.Content("~/css/global.css")" asp-append-version="true"/>
</head>
<body>
    <div class="container wide-container">
        <div class="header">
            <h1>SecurityStamp迁移工具</h1>
            <p>将现有用户的SecurityStamp更新为新的安全格式</p>
        </div>

        @if (TempData["Message"] is string message)
        {
            <div class="success-message">
                @message
            </div>
        }

        @if (TempData["Error"] is string error)
        {
            <div class="error-message">
                @error
            </div>
        }

        <!-- 批量迁移区域 -->
        <div class="section">
            <h2>批量迁移</h2>
            <p>此操作将更新所有用户的SecurityStamp为新的安全格式。建议在系统维护期间执行。</p>
            
            <div class="warning-section">
                <div class="warning-icon">
                    <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                        <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path>
                        <line x1="12" y1="9" x2="12" y2="13"></line>
                        <line x1="12" y1="17" x2="12.01" y2="17"></line>
                    </svg>
                </div>
                <div class="warning-content">
                    <h3>重要提醒</h3>
                    <p>执行迁移后,所有用户将被强制重新登录。请确保在合适的时间执行此操作。</p>
                </div>
            </div>

            <form method="post" asp-action="MigrateSecurityStamps" onsubmit="return confirmMigration()">
                @Html.AntiForgeryToken()
                <button type="submit" class="danger-button">
                    执行批量迁移
                </button>
            </form>
        </div>

        <!-- 单用户操作区域 -->
        <div class="section">
            <h2>单用户操作</h2>
            
            <div class="input-section">
                <label class="input-label" for="userId">用户ID</label>
                <div class="input-wrapper">
                    <input 
                        id="userId"
                        type="text" 
                        class="text-input" 
                        placeholder="请输入用户ID"
                    />
                </div>
            </div>

            <div class="action-buttons">
                <button type="button" class="submit-button" onclick="validateUserSecurityStamp()">
                    验证SecurityStamp
                </button>
                <button type="button" class="danger-button" onclick="forceUserReauth()">
                    强制重新登录
                </button>
            </div>

            <div id="userResult" class="result-section" style="display: none;">
                <!-- 结果将在这里显示 -->
            </div>
        </div>

        <div class="footer">
            <p>SecurityStamp迁移工具 - 仅限系统管理员使用</p>
        </div>
    </div>

    <script src="@Url.Content("~/js/ui-components.js")" asp-append-version="true"></script>
    <script>
        function confirmMigration() {
            return confirm('您确定要执行SecurityStamp批量迁移吗?\n\n此操作将:\n1. 更新所有用户的SecurityStamp\n2. 强制所有用户重新登录\n3. 提高系统安全性\n\n建议在系统维护期间执行。');
        }

        async function validateUserSecurityStamp() {
            const userId = document.getElementById('userId').value;
            if (!userId.trim()) {
                alert('请输入用户ID');
                return;
            }

            try {
                const response = await fetch('/validate-user-security-stamp', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded',
                        'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]').value
                    },
                    body: `userId=${encodeURIComponent(userId)}`
                });

                const result = await response.json();
                displayResult(result, '验证结果');
            } catch (error) {
                displayResult({ success: false, message: '请求失败: ' + error.message }, '验证结果');
            }
        }

        async function forceUserReauth() {
            const userId = document.getElementById('userId').value;
            if (!userId.trim()) {
                alert('请输入用户ID');
                return;
            }

            if (!confirm(`确定要强制用户 ${userId} 重新登录吗?`)) {
                return;
            }

            try {
                const response = await fetch('/force-user-reauth', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded',
                        'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]').value
                    },
                    body: `userId=${encodeURIComponent(userId)}&reason=${encodeURIComponent('管理员手动操作')}`
                });

                const result = await response.json();
                displayResult(result, '操作结果');
            } catch (error) {
                displayResult({ success: false, message: '请求失败: ' + error.message }, '操作结果');
            }
        }

        function displayResult(result, title) {
            const resultDiv = document.getElementById('userResult');
            const messageClass = result.success ? 'success-message' : 'error-message';
            
            let content = `<h3>${title}</h3>`;
            content += `<div class="${messageClass}">${result.message}</div>`;
            
            if (result.success && result.currentKey) {
                content += `<p><strong>当前SecurityStamp:</strong> ${result.currentKey}</p>`;
                content += `<p><strong>格式状态:</strong> ${result.isValid ? '有效' : '无效'}</p>`;
            }
            
            resultDiv.innerHTML = content;
            resultDiv.style.display = 'block';
        }
    </script>

    <style>
        .section {
            margin-bottom: 40px;
            padding: 24px;
            background: var(--bg-secondary);
            border-radius: var(--radius);
            border: 1px solid var(--border-color);
        }

        .section h2 {
            color: var(--text-primary);
            margin-bottom: 12px;
            font-size: 20px;
            font-weight: 600;
        }

        .section p {
            color: var(--text-secondary);
            margin-bottom: 20px;
            line-height: 1.5;
        }

        .result-section {
            margin-top: 20px;
            padding: 16px;
            background: var(--bg-primary);
            border-radius: var(--radius-sm);
            border: 1px solid var(--border-color);
        }

        .result-section h3 {
            margin-bottom: 12px;
            color: var(--text-primary);
            font-size: 16px;
        }
    </style>
</body>
</html>
loading