Skip to content

Commit

Permalink
修改认证信息存储方式,避免认证信息异常
Browse files Browse the repository at this point in the history
  • Loading branch information
whyour committed Dec 30, 2024
1 parent 75f91e1 commit 678e3e2
Show file tree
Hide file tree
Showing 14 changed files with 326 additions and 230 deletions.
22 changes: 11 additions & 11 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@
**/*.svg
**/*.ejs
**/*.html
.umi
.umi-production
.umi-test
.history
.tmp
node_modules
/.umi
/.umi-production
/.umi-test
/.history
/.tmp
/node_modules
npm-debug.log*
yarn-error.log
yarn.lock
package-lock.json
static
data
/static
/data
DS_Store
src/.umi
src/.umi-production
src/.umi-test
/src/.umi
/src/.umi-production
/src/.umi-test
.env.local
.env
version.ts
Expand Down
2 changes: 1 addition & 1 deletion back/api/system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default (app: Router) => {
const logger: Logger = Container.get('logger');
try {
const userService = Container.get(UserService);
const authInfo = await userService.getUserInfo();
const authInfo = await userService.getAuthInfo();
const { version, changeLog, changeLogLink, publishTime } =
await parseVersion(config.versionFile);

Expand Down
2 changes: 1 addition & 1 deletion back/api/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export default (app: Router) => {
const logger: Logger = Container.get('logger');
try {
const userService = Container.get(UserService);
const authInfo = await userService.getUserInfo();
const authInfo = await userService.getAuthInfo();
res.send({
code: 200,
data: {
Expand Down
25 changes: 23 additions & 2 deletions back/data/system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export enum AuthDataType {
'notification' = 'notification',
'removeLogFrequency' = 'removeLogFrequency',
'systemConfig' = 'systemConfig',
'authConfig' = 'authConfig',
}

export interface SystemConfigInfo {
Expand All @@ -46,11 +47,31 @@ export interface LoginLogInfo {
status?: LoginStatus;
}

export interface AuthInfo {
username: string;
password: string;
retries: number;
lastlogon: number;
lastip: string;
lastaddr: string;
platform: string;
isTwoFactorChecking: boolean;
token: string;
tokens: Record<string, string>;
twoFactorActivated: boolean;
twoFactorActived: boolean;
twoFactorSecret: string;
avatar: string;
}

export type SystemModelInfo = SystemConfigInfo &
Partial<NotificationInfo> &
LoginLogInfo;
LoginLogInfo &
Partial<AuthInfo>;

export interface SystemInstance extends Model<SystemInfo, SystemInfo>, SystemInfo { }
export interface SystemInstance
extends Model<SystemInfo, SystemInfo>,
SystemInfo {}
export const SystemModel = sequelize.define<SystemInstance>('Auth', {
ip: DataTypes.STRING,
type: DataTypes.STRING,
Expand Down
24 changes: 11 additions & 13 deletions back/loaders/express.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,14 @@ import cors from 'cors';
import routes from '../api';
import config from '../config';
import { UnauthorizedError, expressjwt } from 'express-jwt';
import fs from 'fs/promises';
import { getPlatform, getToken, safeJSONParse } from '../config/util';
import Container from 'typedi';
import OpenService from '../services/open';
import { getPlatform, getToken } from '../config/util';
import rewrite from 'express-urlrewrite';
import UserService from '../services/user';
import * as Sentry from '@sentry/node';
import { EnvModel } from '../data/env';
import { errors } from 'celebrate';
import { createProxyMiddleware } from 'http-proxy-middleware';
import { serveEnv } from '../config/serverEnv';
import Logger from './logger';
import { IKeyvStore, shareStore } from '../shared/store';

export default ({ app }: { app: Application }) => {
app.set('trust proxy', 'loopback');
Expand Down Expand Up @@ -58,8 +54,10 @@ export default ({ app }: { app: Application }) => {
app.use(async (req, res, next) => {
const headerToken = getToken(req);
if (req.path.startsWith('/open/')) {
const openService = Container.get(OpenService);
const doc = await openService.findTokenByValue(headerToken);
const apps = await shareStore.getApps();
const doc = apps?.filter((x) =>
x.tokens?.find((y) => y.value === headerToken),
)?.[0];
if (doc && doc.tokens && doc.tokens.length > 0) {
const currentToken = doc.tokens.find((x) => x.value === headerToken);
const keyMatch = req.path.match(/\/open\/([a-z]+)\/*/);
Expand All @@ -83,9 +81,9 @@ export default ({ app }: { app: Application }) => {
return next();
}

const data = await fs.readFile(config.authConfigFile, 'utf8');
if (data && headerToken) {
const { token = '', tokens = {} } = safeJSONParse(data);
const authInfo = await shareStore.getAuthInfo();
if (authInfo && headerToken) {
const { token = '', tokens = {} } = authInfo;
if (headerToken === token || tokens[req.platform] === headerToken) {
return next();
}
Expand All @@ -103,8 +101,8 @@ export default ({ app }: { app: Application }) => {
if (!['/api/user/init', '/api/user/notification/init'].includes(req.path)) {
return next();
}
const userService = Container.get(UserService);
const authInfo = await userService.getUserInfo();
const authInfo =
(await shareStore.getAuthInfo()) || ({} as IKeyvStore['authInfo']);

let isInitialized = true;
if (
Expand Down
40 changes: 39 additions & 1 deletion back/loaders/initData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,49 @@ import { initPosition } from '../data/env';
import { AuthDataType, SystemModel } from '../data/system';
import SystemService from '../services/system';
import UserService from '../services/user';
import { writeFile } from 'fs/promises';
import { writeFile, readFile } from 'fs/promises';
import { safeJSONParse } from '../config/util';
import OpenService from '../services/open';
import { shareStore } from '../shared/store';

export default async () => {
const cronService = Container.get(CronService);
const envService = Container.get(EnvService);
const dependenceService = Container.get(DependenceService);
const systemService = Container.get(SystemService);
const userService = Container.get(UserService);
const openService = Container.get(OpenService);

// 初始化增加系统配置
await SystemModel.upsert({ type: AuthDataType.systemConfig });
await SystemModel.upsert({ type: AuthDataType.notification });
await SystemModel.upsert({ type: AuthDataType.authConfig });
const authConfig = await SystemModel.findOne({
where: { type: AuthDataType.authConfig },
});
if (!authConfig?.info) {
let authInfo = {
username: 'admin',
password: 'admin',
};
try {
const content = await readFile(config.authConfigFile, 'utf8');
authInfo = safeJSONParse(content);
} catch (error) {}
if (authConfig?.id) {
await SystemModel.update(
{ info: authInfo },
{
where: { id: authConfig.id },
},
);
} else {
await SystemModel.create({
info: authInfo,
type: AuthDataType.authConfig,
});
}
}

// 初始化通知配置
const notifyConfig = await userService.getNotificationMode();
Expand Down Expand Up @@ -169,4 +200,11 @@ export default async () => {
// 初始化保存一次ck和定时任务数据
await cronService.autosave_crontab();
await envService.set_envs();

const authInfo = await userService.getAuthInfo();
const apps = await openService.findApps();
await shareStore.updateAuthInfo(authInfo);
if (apps?.length) {
await shareStore.updateApps(apps);
}
};
6 changes: 0 additions & 6 deletions back/loaders/initFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ const bakPath = path.join(dataPath, 'bak/');
const samplePath = path.join(rootPath, 'sample/');
const tmpPath = path.join(logPath, '.tmp/');
const confFile = path.join(configPath, 'config.sh');
const authConfigFile = path.join(configPath, 'auth.json');
const sampleConfigFile = path.join(samplePath, 'config.sample.sh');
const sampleAuthFile = path.join(samplePath, 'auth.sample.json');
const sampleTaskShellFile = path.join(samplePath, 'task.sample.sh');
const sampleNotifyJsFile = path.join(samplePath, 'notify.js');
const sampleNotifyPyFile = path.join(samplePath, 'notify.py');
Expand All @@ -40,7 +38,6 @@ const sshdPath = path.join(dataPath, 'ssh.d');
const systemLogPath = path.join(dataPath, 'syslog');

export default async () => {
const authFileExist = await fileExist(authConfigFile);
const confFileExist = await fileExist(confFile);
const scriptDirExist = await fileExist(scriptPath);
const preloadDirExist = await fileExist(preloadPath);
Expand Down Expand Up @@ -100,9 +97,6 @@ export default async () => {
}

// 初始化文件
if (!authFileExist) {
await fs.writeFile(authConfigFile, await fs.readFile(sampleAuthFile));
}

if (!confFileExist) {
await fs.writeFile(confFile, await fs.readFile(sampleConfigFile));
Expand Down
11 changes: 5 additions & 6 deletions back/loaders/sock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import sockJs from 'sockjs';
import { Server } from 'http';
import { Container } from 'typedi';
import SockService from '../services/sock';
import config from '../config/index';
import fs from 'fs/promises';
import { getPlatform, safeJSONParse } from '../config/util';
import { getPlatform } from '../config/util';
import { shareStore } from '../shared/store';

export default async ({ server }: { server: Server }) => {
const echo = sockJs.createServer({ prefix: '/api/ws', log: () => {} });
Expand All @@ -15,11 +14,11 @@ export default async ({ server }: { server: Server }) => {
conn.close('404');
}

const data = await fs.readFile(config.authConfigFile, 'utf8');
const authInfo = await shareStore.getAuthInfo();
const platform = getPlatform(conn.headers['user-agent'] || '') || 'desktop';
const headerToken = conn.url.replace(`${conn.pathname}?token=`, '');
if (data) {
const { token = '', tokens = {} } = safeJSONParse(data);
if (authInfo) {
const { token = '', tokens = {} } = authInfo;
if (headerToken === token || tokens[platform] === headerToken) {
sockService.addClient(conn);

Expand Down
25 changes: 13 additions & 12 deletions back/services/open.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import { Service, Inject } from 'typedi';
import winston from 'winston';
import { createRandomString } from '../config/util';
import config from '../config';
import { App, AppModel } from '../data/open';
import { v4 as uuidV4 } from 'uuid';
import sequelize, { Op } from 'sequelize';
import { shareStore } from '../shared/store';

@Service()
export default class OpenService {
constructor(@Inject('logger') private logger: winston.Logger) {}

public async findTokenByValue(token: string): Promise<App | null> {
public async findApps(): Promise<App[] | null> {
const docs = await this.find({});
const doc = docs.filter((x) => x.tokens?.find((y) => y.value === token));
return doc[0];
return docs;
}

public async create(payload: App): Promise<App> {
Expand All @@ -34,17 +33,19 @@ export default class OpenService {
name: payload.name,
scopes: payload.scopes,
id: payload.id,
} as any);
} as App);
return { ...newDoc, tokens: [] };
}

private async updateDb(payload: App): Promise<App> {
private async updateDb(payload: Partial<App>): Promise<App> {
await AppModel.update(payload, { where: { id: payload.id } });
return await this.getDb({ id: payload.id });
const apps = await this.find({});
await shareStore.updateApps(apps);
return apps?.find((x) => x.id === payload.id) as App;
}

public async getDb(query: any): Promise<App> {
const doc: any = await AppModel.findOne({ where: query });
public async getDb(query: Record<string, any>): Promise<App> {
const doc = await AppModel.findOne({ where: query });
if (!doc) {
throw new Error(`App ${JSON.stringify(query)} not found`);
}
Expand All @@ -56,7 +57,7 @@ export default class OpenService {
}

public async resetSecret(id: number): Promise<App> {
const tab: any = {
const tab: Partial<App> = {
client_secret: createRandomString(24, 24),
tokens: [],
id,
Expand All @@ -74,7 +75,7 @@ export default class OpenService {
public async list(
searchText: string = '',
sort: any = {},
query: any = {},
query: Record<string, any> = {},
): Promise<App[]> {
let condition = { ...query };
if (searchText) {
Expand All @@ -101,7 +102,7 @@ export default class OpenService {
}
}

private async find(query: any, sort?: any): Promise<App[]> {
private async find(query: Record<string, any>, sort?: any): Promise<App[]> {
const docs = await AppModel.findAll({ where: { ...query } });
return docs.map((x) => x.get({ plain: true }));
}
Expand Down
Loading

0 comments on commit 678e3e2

Please sign in to comment.