-
This commit is contained in:
@ -61,6 +61,8 @@ const Tokens: React.FC = () => {
|
||||
const [tokenDetailsVisible, setTokenDetailsVisible] = useState(false);
|
||||
const [selectedToken, setSelectedToken] = useState<TokenWithApp | null>(null);
|
||||
const [newTokenResponse, setNewTokenResponse] = useState<CreateTokenResponse | null>(null);
|
||||
const [verifyResult, setVerifyResult] = useState<any>(null);
|
||||
const [verifyLoading, setVerifyLoading] = useState(false);
|
||||
const [form] = Form.useForm();
|
||||
const [verifyForm] = Form.useForm();
|
||||
|
||||
@ -169,8 +171,17 @@ const Tokens: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleOpenVerifyModal = () => {
|
||||
verifyForm.resetFields();
|
||||
setVerifyResult(null);
|
||||
setVerifyLoading(false);
|
||||
setVerifyModalVisible(true);
|
||||
};
|
||||
|
||||
const handleVerifyToken = async (values: any) => {
|
||||
try {
|
||||
setVerifyLoading(true);
|
||||
|
||||
const verifyRequest: VerifyRequest = {
|
||||
app_id: values.app_id,
|
||||
type: 'static',
|
||||
@ -178,64 +189,40 @@ const Tokens: React.FC = () => {
|
||||
permissions: values.permissions || [],
|
||||
};
|
||||
|
||||
console.log('Verifying token with request:', verifyRequest);
|
||||
const response = await apiService.verifyToken(verifyRequest);
|
||||
console.log('Token verification response:', response);
|
||||
|
||||
Modal.info({
|
||||
title: 'Token Verification Result',
|
||||
width: 600,
|
||||
content: (
|
||||
<div>
|
||||
<Space direction="vertical" size="middle" style={{ width: '100%' }}>
|
||||
<div>
|
||||
<Text strong>Status: </Text>
|
||||
{response.valid ? (
|
||||
<Tag color="green" icon={<CheckCircleOutlined />}>VALID</Tag>
|
||||
) : (
|
||||
<Tag color="red" icon={<ExclamationCircleOutlined />}>INVALID</Tag>
|
||||
)}
|
||||
</div>
|
||||
// Store the result in state to display in the modal
|
||||
setVerifyResult(response);
|
||||
|
||||
{response.permissions && response.permissions.length > 0 && (
|
||||
<div>
|
||||
<Text strong>Permissions:</Text>
|
||||
<div style={{ marginTop: '8px' }}>
|
||||
{response.permissions.map(permission => (
|
||||
<Tag key={permission} color="blue">{permission}</Tag>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{response.permission_results && (
|
||||
<div>
|
||||
<Text strong>Permission Check Results:</Text>
|
||||
<div style={{ marginTop: '8px' }}>
|
||||
{Object.entries(response.permission_results).map(([permission, granted]) => (
|
||||
<div key={permission} style={{ marginBottom: '4px' }}>
|
||||
<Tag color={granted ? 'green' : 'red'}>
|
||||
{permission}: {granted ? 'GRANTED' : 'DENIED'}
|
||||
</Tag>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{response.error && (
|
||||
<Alert
|
||||
message="Error"
|
||||
description={response.error}
|
||||
type="error"
|
||||
showIcon
|
||||
/>
|
||||
)}
|
||||
</Space>
|
||||
</div>
|
||||
),
|
||||
});
|
||||
// Show success message
|
||||
if (response && response.valid) {
|
||||
message.success('Token verification completed successfully!', 3);
|
||||
} else {
|
||||
message.warning('Token verification completed - token is invalid', 3);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to verify token:', error);
|
||||
message.error('Failed to verify token');
|
||||
|
||||
// Store error result in state
|
||||
setVerifyResult({
|
||||
valid: false,
|
||||
error: error instanceof Error ? error.message : 'An unexpected error occurred while verifying the token.',
|
||||
errorDetails: {
|
||||
networkError: true,
|
||||
suggestions: [
|
||||
'Check your network connection',
|
||||
'Verify the token format is correct',
|
||||
'Ensure the selected application is correct',
|
||||
'Confirm the API server is running'
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
message.error('Failed to verify token. Please check your network connection and try again.');
|
||||
} finally {
|
||||
setVerifyLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
@ -339,7 +326,7 @@ const Tokens: React.FC = () => {
|
||||
<Space>
|
||||
<Button
|
||||
icon={<CheckCircleOutlined />}
|
||||
onClick={() => setVerifyModalVisible(true)}
|
||||
onClick={handleOpenVerifyModal}
|
||||
>
|
||||
Verify Token
|
||||
</Button>
|
||||
@ -514,8 +501,10 @@ const Tokens: React.FC = () => {
|
||||
open={verifyModalVisible}
|
||||
onCancel={() => setVerifyModalVisible(false)}
|
||||
onOk={() => verifyForm.submit()}
|
||||
width={600}
|
||||
confirmLoading={verifyLoading}
|
||||
width={800}
|
||||
>
|
||||
<Space direction="vertical" size="large" style={{ width: '100%' }}>
|
||||
<Form
|
||||
form={verifyForm}
|
||||
layout="vertical"
|
||||
@ -562,6 +551,159 @@ const Tokens: React.FC = () => {
|
||||
</Checkbox.Group>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
|
||||
{/* Verification Results */}
|
||||
{verifyResult && (
|
||||
<div>
|
||||
<Title level={4} style={{ marginBottom: '16px' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||||
{verifyResult.valid ? (
|
||||
<CheckCircleOutlined style={{ color: '#52c41a' }} />
|
||||
) : (
|
||||
<ExclamationCircleOutlined style={{ color: '#ff4d4f' }} />
|
||||
)}
|
||||
Verification Results
|
||||
</div>
|
||||
</Title>
|
||||
|
||||
<Space direction="vertical" size="large" style={{ width: '100%' }}>
|
||||
{/* Overall Status */}
|
||||
<Card size="small" style={{ backgroundColor: verifyResult.valid ? '#f6ffed' : '#fff2f0' }}>
|
||||
<Space direction="vertical" size="small" style={{ width: '100%' }}>
|
||||
<div>
|
||||
<Text strong>Token Status: </Text>
|
||||
{verifyResult.valid ? (
|
||||
<Tag color="green" icon={<CheckCircleOutlined />} style={{ fontSize: '14px' }}>
|
||||
VALID
|
||||
</Tag>
|
||||
) : (
|
||||
<Tag color="red" icon={<ExclamationCircleOutlined />} style={{ fontSize: '14px' }}>
|
||||
INVALID
|
||||
</Tag>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{verifyResult.permitted !== undefined && (
|
||||
<div>
|
||||
<Text strong>Permission Status: </Text>
|
||||
{verifyResult.permitted ? (
|
||||
<Tag color="green" icon={<CheckCircleOutlined />} style={{ fontSize: '14px' }}>
|
||||
ALL PERMISSIONS GRANTED
|
||||
</Tag>
|
||||
) : (
|
||||
<Tag color="orange" icon={<ExclamationCircleOutlined />} style={{ fontSize: '14px' }}>
|
||||
SOME PERMISSIONS DENIED
|
||||
</Tag>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{verifyResult.token_type && (
|
||||
<div>
|
||||
<Text strong>Token Type: </Text>
|
||||
<Tag color="blue" style={{ fontSize: '14px' }}>
|
||||
{verifyResult.token_type.toUpperCase()}
|
||||
</Tag>
|
||||
</div>
|
||||
)}
|
||||
</Space>
|
||||
</Card>
|
||||
|
||||
{/* Token Permissions */}
|
||||
{verifyResult.permissions && verifyResult.permissions.length > 0 && (
|
||||
<div>
|
||||
<Text strong style={{ fontSize: '16px' }}>Available Token Permissions:</Text>
|
||||
<div style={{ marginTop: '12px', padding: '12px', backgroundColor: '#fafafa', borderRadius: '6px' }}>
|
||||
<Space wrap>
|
||||
{verifyResult.permissions.map((permission: string) => (
|
||||
<Tag key={permission} color="blue" style={{ margin: '2px' }}>
|
||||
{permission}
|
||||
</Tag>
|
||||
))}
|
||||
</Space>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Requested Permission Results */}
|
||||
{verifyResult.permission_results && Object.keys(verifyResult.permission_results).length > 0 && (
|
||||
<div>
|
||||
<Text strong style={{ fontSize: '16px' }}>Requested Permission Results:</Text>
|
||||
<div style={{ marginTop: '12px' }}>
|
||||
{Object.entries(verifyResult.permission_results).map(([permission, granted]) => (
|
||||
<div key={permission} style={{
|
||||
marginBottom: '8px',
|
||||
padding: '8px 12px',
|
||||
backgroundColor: granted ? '#f6ffed' : '#fff2f0',
|
||||
borderRadius: '4px',
|
||||
border: `1px solid ${granted ? '#b7eb8f' : '#ffccc7'}`
|
||||
}}>
|
||||
<Space>
|
||||
{granted ? (
|
||||
<CheckCircleOutlined style={{ color: '#52c41a' }} />
|
||||
) : (
|
||||
<ExclamationCircleOutlined style={{ color: '#ff4d4f' }} />
|
||||
)}
|
||||
<Text strong>{permission}</Text>
|
||||
<Tag color={granted ? 'green' : 'red'} style={{ marginLeft: 'auto' }}>
|
||||
{granted ? 'GRANTED' : 'DENIED'}
|
||||
</Tag>
|
||||
</Space>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Error Information */}
|
||||
{verifyResult.error && (
|
||||
<Alert
|
||||
message="Verification Error"
|
||||
description={verifyResult.error}
|
||||
type="error"
|
||||
showIcon
|
||||
style={{ marginTop: '16px' }}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Error Details with Suggestions */}
|
||||
{verifyResult.errorDetails && verifyResult.errorDetails.networkError && (
|
||||
<div>
|
||||
<Text type="secondary">
|
||||
Please check:
|
||||
</Text>
|
||||
<ul style={{ marginTop: '8px', paddingLeft: '20px' }}>
|
||||
{verifyResult.errorDetails.suggestions.map((suggestion: string, index: number) => (
|
||||
<li key={index}>{suggestion}</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Additional Information */}
|
||||
{(verifyResult.expires_at || verifyResult.max_valid_at) && (
|
||||
<div>
|
||||
<Text strong style={{ fontSize: '16px' }}>Token Timing Information:</Text>
|
||||
<div style={{ marginTop: '12px', padding: '12px', backgroundColor: '#fafafa', borderRadius: '6px' }}>
|
||||
{verifyResult.expires_at && (
|
||||
<div style={{ marginBottom: '8px' }}>
|
||||
<Text strong>Expires At: </Text>
|
||||
<Text code>{new Date(verifyResult.expires_at).toLocaleString()}</Text>
|
||||
</div>
|
||||
)}
|
||||
{verifyResult.max_valid_at && (
|
||||
<div>
|
||||
<Text strong>Max Valid Until: </Text>
|
||||
<Text code>{new Date(verifyResult.max_valid_at).toLocaleString()}</Text>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Space>
|
||||
</div>
|
||||
)}
|
||||
</Space>
|
||||
</Modal>
|
||||
|
||||
{/* Token Details Modal */}
|
||||
|
||||
@ -78,6 +78,7 @@ export interface VerifyRequest {
|
||||
|
||||
export interface VerifyResponse {
|
||||
valid: boolean;
|
||||
permitted: boolean;
|
||||
user_id?: string;
|
||||
permissions: string[];
|
||||
permission_results?: Record<string, boolean>;
|
||||
|
||||
Reference in New Issue
Block a user