forked from lunanting/cangku
112 lines
2.9 KiB
JavaScript
112 lines
2.9 KiB
JavaScript
'use strict';
|
||
|
||
const express = require('express');
|
||
const {
|
||
ThirdPartySsoError,
|
||
createSsoClient,
|
||
listSsoClients,
|
||
rotateSsoClientSecret,
|
||
updateSsoClient,
|
||
} = require('../services/thirdPartySsoService');
|
||
const {
|
||
createDirectApiKey,
|
||
rotateDirectApiKey,
|
||
updateDirectReturnUrls,
|
||
} = require('../services/thirdPartySsoDirectService');
|
||
|
||
const router = express.Router();
|
||
|
||
function sendError(res, error) {
|
||
return res.status(error instanceof ThirdPartySsoError ? error.status : 500).json({
|
||
error: error.message || '统一认证应用管理失败',
|
||
code: error instanceof ThirdPartySsoError ? error.code : 'SERVER_ERROR',
|
||
});
|
||
}
|
||
|
||
router.get('/', async (_req, res) => {
|
||
try {
|
||
return res.json({ clients: await listSsoClients() });
|
||
} catch (error) {
|
||
return sendError(res, error);
|
||
}
|
||
});
|
||
|
||
router.post('/', async (req, res) => {
|
||
try {
|
||
const client = await createSsoClient(req.body || {}, req.user || {});
|
||
return res.status(201).json({
|
||
client,
|
||
warning: client.clientSecret
|
||
? 'client_secret 仅在本次创建时返回,请交给第三方后安全保存。'
|
||
: '公开客户端不使用 client_secret,必须使用 PKCE。',
|
||
});
|
||
} catch (error) {
|
||
return sendError(res, error);
|
||
}
|
||
});
|
||
|
||
router.post('/direct-api-key', async (req, res) => {
|
||
try {
|
||
return res.status(201).json({
|
||
credential: await createDirectApiKey(req.body || {}, req.user || {}),
|
||
warning: 'API Key 仅在本次创建时返回,只能保存在第三方后端。',
|
||
});
|
||
} catch (error) {
|
||
return sendError(res, error);
|
||
}
|
||
});
|
||
|
||
router.post('/:clientId/rotate-api-key', async (req, res) => {
|
||
try {
|
||
return res.json({
|
||
credential: await rotateDirectApiKey(req.params.clientId, req.user || {}),
|
||
warning: '新 API Key 仅在本次返回,旧 Key 已立即失效。',
|
||
});
|
||
} catch (error) {
|
||
return sendError(res, error);
|
||
}
|
||
});
|
||
|
||
router.patch('/:clientId/direct-return-urls', async (req, res) => {
|
||
try {
|
||
return res.json({
|
||
client: await updateDirectReturnUrls(req.params.clientId, req.body || {}, req.user || {}),
|
||
});
|
||
} catch (error) {
|
||
return sendError(res, error);
|
||
}
|
||
});
|
||
|
||
router.patch('/:clientId', async (req, res) => {
|
||
try {
|
||
return res.json({
|
||
client: await updateSsoClient(req.params.clientId, req.body || {}, req.user || {}),
|
||
});
|
||
} catch (error) {
|
||
return sendError(res, error);
|
||
}
|
||
});
|
||
|
||
router.post('/:clientId/rotate-secret', async (req, res) => {
|
||
try {
|
||
return res.json({
|
||
client: await rotateSsoClientSecret(req.params.clientId, req.user || {}),
|
||
warning: '新 client_secret 仅在本次返回,旧密钥已立即失效。',
|
||
});
|
||
} catch (error) {
|
||
return sendError(res, error);
|
||
}
|
||
});
|
||
|
||
router.delete('/:clientId', async (req, res) => {
|
||
try {
|
||
return res.json({
|
||
client: await updateSsoClient(req.params.clientId, { status: 'disabled' }, req.user || {}),
|
||
});
|
||
} catch (error) {
|
||
return sendError(res, error);
|
||
}
|
||
});
|
||
|
||
module.exports = router;
|