cangku/backend/src/services/authConfig.js

115 lines
3.7 KiB
JavaScript

const database = require('../config/database');
const DEFAULT_AUTH_CONFIG = {
authBaseUrl: '',
dingtalkEnabled: false,
dingtalkAppKey: '',
dingtalkAppSecret: '',
dingtalkSyncRootDeptId: 1,
googleEnabled: false,
googleClientId: '',
googleClientSecret: '',
};
const PUBLIC_AUTH_CONFIG_CACHE_TTL_MS = Math.max(
Number(process.env.PUBLIC_AUTH_CONFIG_CACHE_TTL_SECONDS) || 300,
30
) * 1000;
let publicAuthConfigCache = null;
let publicAuthConfigCacheExpiresAt = 0;
function normalizeBoolean(value) {
return value === true || value === 1 || value === '1';
}
function mapRowToConfig(row) {
if (!row) {
return { ...DEFAULT_AUTH_CONFIG };
}
return {
id: row.id,
authBaseUrl: row.auth_base_url || '',
dingtalkEnabled: normalizeBoolean(row.dingtalk_enabled),
dingtalkAppKey: row.dingtalk_app_key || '',
dingtalkAppSecret: row.dingtalk_app_secret || '',
dingtalkSyncRootDeptId: Number(row.dingtalk_sync_root_dept_id || 1),
googleEnabled: normalizeBoolean(row.google_enabled),
googleClientId: row.google_client_id || '',
googleClientSecret: row.google_client_secret || '',
};
}
async function getAuthConfig() {
const rows = await database.local.query(
`SELECT id, auth_base_url, dingtalk_enabled, dingtalk_app_key, dingtalk_app_secret,
dingtalk_sync_root_dept_id, google_enabled, google_client_id, google_client_secret
FROM auth_configs
ORDER BY id ASC
LIMIT 1`
);
return mapRowToConfig(rows[0]);
}
async function getPublicAuthConfig() {
const now = Date.now();
if (publicAuthConfigCache && publicAuthConfigCacheExpiresAt > now) {
return publicAuthConfigCache;
}
let config;
try {
config = await getAuthConfig();
} catch (error) {
if (publicAuthConfigCache) {
return publicAuthConfigCache;
}
throw error;
}
const publicConfig = {
authBaseUrl: config.authBaseUrl,
dingtalkEnabled: config.dingtalkEnabled && Boolean(config.dingtalkAppKey && config.dingtalkAppSecret),
googleEnabled: config.googleEnabled && Boolean(config.googleClientId && config.googleClientSecret),
};
publicAuthConfigCache = publicConfig;
publicAuthConfigCacheExpiresAt = now + PUBLIC_AUTH_CONFIG_CACHE_TTL_MS;
return publicConfig;
}
async function saveAuthConfig(input) {
const current = await getAuthConfig();
publicAuthConfigCache = null;
publicAuthConfigCacheExpiresAt = 0;
const payload = {
auth_base_url: typeof input.authBaseUrl === 'string' ? input.authBaseUrl.trim() : current.authBaseUrl,
dingtalk_enabled: input.dingtalkEnabled === undefined ? (current.dingtalkEnabled ? 1 : 0) : (input.dingtalkEnabled ? 1 : 0),
dingtalk_app_key: typeof input.dingtalkAppKey === 'string' ? input.dingtalkAppKey.trim() : current.dingtalkAppKey,
dingtalk_app_secret: typeof input.dingtalkAppSecret === 'string' ? input.dingtalkAppSecret.trim() : current.dingtalkAppSecret,
dingtalk_sync_root_dept_id:
input.dingtalkSyncRootDeptId === undefined
? current.dingtalkSyncRootDeptId
: Number(input.dingtalkSyncRootDeptId || 1),
google_enabled: input.googleEnabled === undefined ? (current.googleEnabled ? 1 : 0) : (input.googleEnabled ? 1 : 0),
google_client_id: typeof input.googleClientId === 'string' ? input.googleClientId.trim() : current.googleClientId,
google_client_secret: typeof input.googleClientSecret === 'string' ? input.googleClientSecret.trim() : current.googleClientSecret,
};
if (current.id) {
await database.local.update('auth_configs', current.id, payload);
return getAuthConfig();
}
await database.local.insert('auth_configs', payload);
return getAuthConfig();
}
module.exports = {
DEFAULT_AUTH_CONFIG,
getAuthConfig,
getPublicAuthConfig,
saveAuthConfig,
};