Skip to content

Commit

Permalink
Update UI text in main-part.tsx files
Browse files Browse the repository at this point in the history
  • Loading branch information
work7z committed Apr 15, 2024
1 parent 38b9a6b commit a7c658b
Show file tree
Hide file tree
Showing 16 changed files with 479 additions and 266 deletions.
1 change: 1 addition & 0 deletions devtools/lang/overwrriten/zh_CN-id-overwrite.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"Rc_TrzJNm": "管道转换",
"usvss": "海外版",
"cnvss": "国内版",
"newtoelb": "新加入 {0} 社区?",
"try.laftools.ide": "使用IDE风格的LafTools",
"dQwjNbi0y": "了解有关文档的更多信息",
"trywithclassicalwebui": "切换至传统Web风格",
Expand Down
9 changes: 1 addition & 8 deletions modules/server2/src/dao/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,7 @@ let loadDAO = async (): Promise<DaoRef> => {
console.log('initializing DAO Ref...')
lock = true;
try {
let sequelize = newSeq("s2")

try {
await sequelize.authenticate();
console.log('Connection has been established successfully.');
} catch (error) {
console.error('Unable to connect to the database:', error);
}
let sequelize = g_sequelize

// 2. redis
const client = await createClient({
Expand Down
60 changes: 0 additions & 60 deletions modules/server2/src/dao/model.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,66 +120,6 @@ export class RawGroupHistory extends Model<InferAttributes<RawGroupHistory>, Inf

export type UserRole = "webmaster" | "moderator" | "user"

export class SMSCodeRecord extends Model<InferAttributes<SMSCodeRecord>, InferCreationAttributes<SMSCodeRecord>> {
declare id: number;
declare userAcctId: string;
declare phoneNumber: string;
declare code: string;
declare dateValue: string;
declare createdAt: CreationOptional<Date> | null;
declare updatedAt: CreationOptional<Date> | null;
declare deleteAt: CreationOptional<Date> | null;
}

export class InvitationCode extends Model<InferAttributes<InvitationCode>, InferCreationAttributes<InvitationCode>> {
declare id: number | null;
declare code: string;
declare maxUseCount: number;
declare useCount: number;
declare expiredAt: Date;
declare createdAt: CreationOptional<Date> | null;
declare updatedAt: CreationOptional<Date> | null;
declare deleteAt: CreationOptional<Date> | null;
}

export class User extends Model<InferAttributes<User>, InferCreationAttributes<User>> {
declare id: number | null;
declare userAcctId: string; // unique text id, can not be changed
declare username?: string; // can be changed at any time, can be duplicate
declare uid?: number | null;
declare invitationCode: string;
declare phoneNumber: string;
declare vcode?: string;
declare email?: string;
declare source?: string;
declare password: string;
declare role: UserRole;
declare avatarPath?: string;
declare status: "newly-created" | "normal" | "banned" | "deleted";
declare topicCount: number; // the number of topics that's sent by this user up to now
declare replyCount: number;
declare banReason?: string | null; // the reason why this user is banned
declare banUntil?: Date | null;
// settings
declare cityId?: string; // city id, from fixed static data in node.js
declare goal?: string; // goal, from fixed static data in node.js

// timestamps
declare createdAt?: CreationOptional<Date> | null;
declare updatedAt?: CreationOptional<Date> | null;
declare deleteAt?: CreationOptional<Date> | null;
}

// model for UserToken
export class UserToken extends Model<InferAttributes<UserToken>, InferCreationAttributes<UserToken>> {
declare id: number;
declare userId: number;
declare token: string;
declare createdAt: CreationOptional<Date> | null;
declare updatedAt: CreationOptional<Date> | null;
declare deleteAt: CreationOptional<Date> | null;
}

// model for UserLoginLog
export class UserLoginLog extends Model<InferAttributes<UserLoginLog>, InferCreationAttributes<UserLoginLog>> {
declare id?: number;
Expand Down
31 changes: 30 additions & 1 deletion modules/server2/src/i18n/lang/zh_CN.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
{
"HZEGO_YeW": "这是一个测试字符串,表示“Hello World”,可以吗?"
"-dxG-aEe4w": "今天发送的短信验证码已达到最大数量。",
"4sQWoTgfr": "验证码已过期,请刷新页面重试",
"4sdQWoTgfr": "验证码已过期,请刷新页面后重试。",
"8s1R5nChx": "邀请码为空,该社区不对外开放,仅限受邀用户。",
"8s1dX": "系统中不存在邀请码,请检查是否存在大小写问题。",
"8sVG1RXhx": "密码应至少为 6 个字符",
"8sVG1RdXhx": "用户ID已存在",
"8sVG1kqXhx": "用户 ID 至少应为 2 个字符",
"8sVGdXhx": "用户 ID 只能包含字母和数字",
"8saIR-LCjyChx": "邀请码已过期",
"8saIt5r5nGxwwChx": "邀请码已用完",
"CuHqw9m": "{0} 不是有效的电话号码,当前系统仅接受 11 位数字的电话号码。",
"D_9sNBiZj": "您尝试的次数过多,请稍后再试。",
"HZEGO_YeW": "这是一个测试字符串,表示“Hello World”,可以吗?",
"HaU4NMabv": "验证码不正确,请重新输入或刷新图片。",
"K2UEY4ddl": "用户 ID 包含无效单词,请避免使用 {0}",
"RYlJHHwg3": "短信代码不正确。",
"TXdh_K": "密码",
"TdXddh_wK": "电话号码",
"Te3h_wK": "电话号码",
"TqXdd3h_wK": "电话号码",
"TqXddh_K": "验证码",
"TqXdh_K": "确认密码",
"Xddh_wK": "邀请代码",
"Y-svpKvUz": "两个密码不匹配",
"dsdfqw": "用户不存在",
"eqwee": "密码不正确",
"oHQNQ4mRw": "用户身份",
"wCcPJZK": "{0} 不是有效的电子邮件地址",
"wCctGPJZK": "{0} 不应为空"
}
47 changes: 41 additions & 6 deletions modules/server2/src/routes/auth.route.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,43 @@
import { Router } from 'express';
import { Request, Response, Router } from 'express';
import { AuthController } from '@controllers/auth.controller';
import { CreateUserDto } from '@dtos/users.dto';
import { Routes } from '@interfaces/routes.interface';
import { AuthMiddleware } from '@middlewares/auth.middleware';
import { ValidationMiddleware } from '@middlewares/validation.middleware';
import { URL_AUTH_GET_CAPTCHA, URL_AUTH_GET_SIGNIN, URL_AUTH_GET_SIGNOUT, URL_AUTH_GET_SIGNUP } from '@/web2share-copy/server_urls';
import { DotFn } from '@/i18n/TranslationUtils';
import { InfoFn } from '@/system/info';
import { DotFn, DotType } from '@/i18n/TranslationUtils';
import { InfoFn, RequestInfo } from '@/system/info';
import { SysResponse, TypeCaptchaResponse } from './_types';
import { CaptchaService } from '@/services/captcha.service';
import { handleSignInUser } from './auth/userAction';

export let getCookieGetterSetter = (req: Request, res: Response) => {
let getCookie = (name: string) => {
return req.cookies[name];
};
let setCookie = (name: string, value: string) => {
res.cookie(name, value);
};
return { getCookie, setCookie };
};
export type CommonHandlePass = {
Dot: DotType;
Info: RequestInfo;
getCookie: (name: string) => string;
setCookie: (name: string, value: string) => void;
};
export let getCommonHandlePass = (req: Request, res: Response): CommonHandlePass => {
let Dot = DotFn(req);
let info = InfoFn(req);
let { getCookie, setCookie } = getCookieGetterSetter(req, res);

return {
Dot,
Info: info,
getCookie,
setCookie,
};
};
export class AuthRoute implements Routes {
public router = Router();
public auth = new AuthController();
Expand All @@ -21,9 +49,16 @@ export class AuthRoute implements Routes {

private initializeRoutes() {
// TODO: using JWT token for authentication
this.router.post(URL_AUTH_GET_SIGNIN, ValidationMiddleware(CreateUserDto), this.auth.logIn);
this.router.post(URL_AUTH_GET_SIGNUP, ValidationMiddleware(CreateUserDto), this.auth.signUp);
this.router.post(URL_AUTH_GET_SIGNOUT, AuthMiddleware, this.auth.logOut);
this.router.post(URL_AUTH_GET_SIGNIN, async (req, res) => {
let p = getCommonHandlePass(req, res);
handleSignInUser(req.body, p);
});
this.router.post(URL_AUTH_GET_SIGNUP, async (req, res) => {
//
});
this.router.post(URL_AUTH_GET_SIGNOUT, async (req, res) => {
//
});
this.router.get(URL_AUTH_GET_CAPTCHA, async (req, res) => {
let p = await this.captcha.generate();
res.send({
Expand Down
92 changes: 92 additions & 0 deletions modules/server2/src/routes/auth/action-types.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
'use server'

import dao from "@/dao";
import _ from "lodash";
import { CommonHandlePass } from "../auth.route";
import { getImgBase64Result } from "@/services/captcha.service";

export type AsyncCreateResponse<T> = {
message?: string, // normal message
error?: string, // error
data?: T
}

export type CheckRules = {
type: "non-empty" | "valid-email" | "check-fn" | "valid-phone",
name: string,
validateFn?: (val: string) => Promise<string | undefined>,
label?: string
}

export let validateEachRuleInArr = async (rules: CheckRules[], formData: any): Promise<AsyncCreateResponse<{}> | null> => {
let valid = true;
let lastMsg = ''
for (let rule of rules) {
if (rule.type === "non-empty") {
lastMsg = Dot("wCctGPJZK", "{0} should not be empty", rule.label)
if (!formData[rule.name]) {
valid = false;
break;
}
}
if (rule.type === "valid-email") {
lastMsg = Dot("wCcPJZK", "{0} is not a valid email", rule.label)
if (!formData[rule.name].includes("@")) {
valid = false;
break;
}
}
if (rule.type === "check-fn" && rule.validateFn) {
let result = await rule.validateFn(formData[rule.name])
if (result) {
lastMsg = result
valid = false;
break;
}
}
if (rule.type === "valid-phone" && rule.validateFn) {
if (formData[rule.name].length != 11) {
lastMsg = Dot("CuHqw9m", "{0} is not a valid phone number, currently system accept 11 digits telephone number only.", rule.label)
valid = false;
break;
}
}
}
if (valid) return null;
return {
error: lastMsg || "invalid form data"
}
}

export let fn_verifyVCode = (randomID: string, p: CommonHandlePass): any => {
let { getCookie, setCookie, Dot } = p
return {
type: "check-fn",
name: "vcode",
validateFn: async (val) => {
let daoRef = await dao()
let vcodeLabel = randomID
if (!vcodeLabel) {
return Dot("4sQWoTgfr", "Verification code is expired, please refresh the page and try again")
}
let fn_cleanVCode = async () => {
if (vcodeLabel) {
await daoRef.redis.del(vcodeLabel)
}
}
let vcodeValOrderIdx = await daoRef.redis.get(vcodeLabel)
if (_.isNil(vcodeValOrderIdx)) {
await fn_cleanVCode()
return Dot("4sdQWoTgfr", "Verification code is expired, please refresh the page and try again.")
}
let vcodeActualVal = getImgBase64Result(parseInt(vcodeValOrderIdx))
console.log('vcode', { vcodeActualVal, val })
if (_.toLower(vcodeActualVal) !== _.toLower(val)) {
await fn_cleanVCode()
return Dot("HaU4NMabv", "Verification code is incorrect, please re-input or refresh the image.")
}
await daoRef.redis.del(vcodeLabel)
return null;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@


import dao from "@/app/__CORE__/dao";
import { Dot } from "@/app/__CORE__/utils/TranslationUtils";
import { AsyncCreateResponse, CheckRules, fn_verifyVCode, validateEachRuleInArr } from "../action-types";
import { setCookie, getCookie, getCookies } from 'cookies-next';
import { cookies } from 'next/headers';
import { AsyncCreateResponse, CheckRules, fn_verifyVCode, validateEachRuleInArr } from "../../../../web2/app/[lang]/[category]/src/parts/user/register/action-types";
import _ from "lodash";
import { checkIfStrOnlyHasAlphanumeric } from "./utils";
import { randomUUID } from "crypto";
import { key_sessionGroup } from "../redis-types";
import { key_sessionGroup } from "../../../../web2/app/[lang]/[category]/src/parts/user/register/redis-types";
import path from "path";
import fs from 'fs'
import crypto from 'crypto'
import { isDevEnv } from "@/web2share-copy/env";

let dir = '' // getPreCompiledDir()
let keyFile = path.join(dir, 'private.key')
let privateKey = fs.readFileSync(keyFile, 'utf-8')
let privateKey = process.env.PRIVATE_KEY
if (isDevEnv()) {
privateKey = 'jr_E9PUkV'
}

export let getSignatureFromStr = (str: string) => {
return getMD5(str + privateKey) + 'v1' // signature plus version
}


export let getMD5 = (str: string) => {
let md5 = crypto.createHash('md5')
md5.update(str)
Expand Down
63 changes: 63 additions & 0 deletions modules/server2/src/routes/auth/handleAuthInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
'use server'

import { UserRole } from "@/dao/model";
import { UserModel } from "@/models/oldjava.model";
import _ from "lodash";
import { fn_add_user_into_active, fn_get_system_info_from_redis } from "./user-types";
import { getSignatureFromStr } from "./auth";
import { Elb3AuthBody, getUserInfoByUserAcctId } from "./userAction";
import { logger } from "@/utils/logger";

export type SystemInfoBody = {
userCount: number,
userOnlineCount: number,
peakOnlineCount: number,
}

export type AuthInfo = {
user: UserModel | null,
signedIn: boolean,
furtherUserDetail?: {
userRole: UserRole,
},
systemInfo: SystemInfoBody
}
export let header_ELB3_auth = "elb3-auth"
export type fn_getCookie = (name: string) => string

export default async (getCookie: fn_getCookie): Promise<AuthInfo> => {
let systemInfo = await fn_get_system_info_from_redis()
let elb3AuthStr = getCookie(header_ELB3_auth);
if (!_.isEmpty(elb3AuthStr)) {
try {
let [expiredTS, body, singature, version] = elb3AuthStr?.split(".") as string[];
let crtTime = new Date();
if (crtTime.getTime() > parseInt(expiredTS)) {
throw new Error("expired");
}
let c_sig = getSignatureFromStr(body);
if (c_sig != singature) {
throw new Error("signature not match");
}
let push: Elb3AuthBody = JSON.parse(atob(body))
let userInfo = await getUserInfoByUserAcctId(push.userAcctId)
await fn_add_user_into_active(push.userAcctId)
return {
systemInfo,
user: userInfo,
signedIn: userInfo != null,
}
} catch (e) {
// unable to decode, meaning it is not a valid elb3-auth
logger.error("decode error" + e)
// if they have elb3-auth, but it is not valid, then we should remove it and redirect the user to /login
}
} else {
// pass through
}
return {
systemInfo,
user: null,
signedIn: false
}
}
Loading

0 comments on commit a7c658b

Please sign in to comment.