feat: fix login encrypt and prettier .vscode (#1481)

Co-authored-by: yikai <yikai@didiglobal.com>
pull/1483/head
bobowiki 1 year ago committed by GitHub
parent f8832afa87
commit 89c049dd62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,35 +1,41 @@
{ {
"editor.codeActionsOnSave": { "editor.codeActionsOnSave": {
"source.fixAll.eslint": true "source.fixAll.eslint": true
}, },
"[html]": { "[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnPaste": true,
"editor.formatOnSave": true
},
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode" "editor.defaultFormatter": "esbenp.prettier-vscode"
}, },
"[typescript]": { "[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode", "editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnPaste": true, "editor.formatOnPaste": true,
"editor.formatOnSave": true "editor.formatOnSave": true
}, },
"[typescriptreact]": { "[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode", "editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnPaste": true, "editor.formatOnSave": true
"editor.formatOnSave": true },
}, "[json]": {
"typescript.tsdk":"./node_modules/typescript/lib" "editor.defaultFormatter": "esbenp.prettier-vscode",
} "editor.formatOnSave": true
},
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnPaste": true,
"editor.formatOnSave": true
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnPaste": true,
"editor.formatOnSave": true
},
"[less]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnPaste": true,
"editor.formatOnSave": true
},
"typescript.tsdk": "./node_modules/typescript/lib"
}

@ -12,6 +12,7 @@
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^13.5.0",
"ahooks": "^3.7.8", "ahooks": "^3.7.8",
"antd": "^5.4.7", "antd": "^5.4.7",
"buffer": "^6.0.3",
"classnames": "^2.3.2", "classnames": "^2.3.2",
"dayjs": "^1.11.9", "dayjs": "^1.11.9",
"echarts": "^5.4.3", "echarts": "^5.4.3",
@ -32,7 +33,8 @@
"build": "craco build", "build": "craco build",
"test": "react-scripts test", "test": "react-scripts test",
"eject": "react-scripts eject", "eject": "react-scripts eject",
"lint": "eslint -c .eslintrc.js src --ext .ts,.tsx,.js,.jsx --fix" "lint": "eslint -c .eslintrc.js src --ext .ts,.tsx,.js,.jsx --fix",
"format": "prettier --write src/"
}, },
"eslintConfig": { "eslintConfig": {
"extends": [ "extends": [

@ -1,14 +1,14 @@
.header-wrapper { .header-wrapper {
display: flex;
width: 100%;
justify-content: space-between;
.logo {
display: flex; display: flex;
width: 100%; flex-direction: column;
justify-content: space-between; width: 50px;
.logo { img {
display: flex; flex: 1;
flex-direction: column; object-fit: contain;
width: 50px;
img {
flex: 1;
object-fit: contain;
}
} }
} }
}

@ -1,3 +0,0 @@
// .custom-icon {
// color: red !important;
// }

@ -1,6 +1,5 @@
import { createFromIconfontCN } from '@ant-design/icons'; import { createFromIconfontCN } from '@ant-design/icons';
import React from 'react'; import React from 'react';
import style from './index.module.less';
const MyIcon = createFromIconfontCN({ const MyIcon = createFromIconfontCN({
scriptUrl: '//at.alicdn.com/t/c/font_4254722_vw34zn7su2.js', // 在 iconfont.cn 上生成 scriptUrl: '//at.alicdn.com/t/c/font_4254722_vw34zn7su2.js', // 在 iconfont.cn 上生成
@ -9,7 +8,7 @@ const MyIcon = createFromIconfontCN({
type MyComponentProps = React.HTMLProps<HTMLDivElement> & { type: string }; type MyComponentProps = React.HTMLProps<HTMLDivElement> & { type: string };
const IconFont: React.FC<MyComponentProps> = props => { const IconFont: React.FC<MyComponentProps> = props => {
return <MyIcon className={style['custom-icon']} {...props}></MyIcon>; return <MyIcon {...props}></MyIcon>;
}; };
export default IconFont; export default IconFont;

@ -52,7 +52,7 @@ const LayoutCom = (props: ILayoutCom) => {
style={{ style={{
backgroundColor: myThemes.backgroundColor.bg1, backgroundColor: myThemes.backgroundColor.bg1,
height: `calc(100vh - ${isHeader ? '64px' : '0px'})`, height: `calc(100vh - ${isHeader ? '64px' : '0px'})`,
margin: isHeader ? '10px 10px 0px' : '0px', margin: isHeader ? '10px 10px 0px 0px' : '0px',
}} }}
> >
{isSider && ( {isSider && (

@ -1,5 +1,5 @@
.tenant_wrapper { .tenant_wrapper {
.opreate_btn { .opreate_btn {
padding: 0px; padding: 0px;
} }
} }

@ -1,5 +1,5 @@
.tenant_wrapper { .tenant_wrapper {
.opreate_btn { .opreate_btn {
padding: 0px; padding: 0px;
} }
} }

@ -1,37 +1,37 @@
.login-wrapper { .login-wrapper {
display: grid; display: grid;
grid-template-columns: 1fr 550px; grid-template-columns: 1fr 550px;
grid-template-rows: 1fr; grid-template-rows: 1fr;
height: 100%; height: 100%;
.login-bgi { .login-bgi {
background: url('https://gw.alipayobjects.com/zos/rmsportal/FfdJeJRQWjEeGTpqgBKj.png') no-repeat fixed center center; background: url('https://gw.alipayobjects.com/zos/rmsportal/FfdJeJRQWjEeGTpqgBKj.png') no-repeat fixed center center;
background-size: contain; background-size: contain;
}
.login-form-wrapper {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.img-wrapper {
width: 50px;
display: flex;
flex-direction: column;
img {
flex: 1;
object-fit: contain;
}
} }
.login-form-wrapper { .tip {
margin-block-start: 12px;
margin-block-end: 36px;
}
.form-content {
width: 330px;
.login-edit {
display: flex; display: flex;
flex-direction: column; justify-content: space-between;
justify-content: center;
align-items: center; align-items: center;
.img-wrapper { }
width: 50px;
display: flex;
flex-direction: column;
img {
flex: 1;
object-fit: contain;
}
}
.tip {
margin-block-start: 12px;
margin-block-end: 36px;
}
.form-content {
width: 330px;
.login-edit {
display: flex;
justify-content: space-between;
align-items: center;
}
}
} }
}
} }

@ -4,7 +4,7 @@ import service from './service';
import { LockOutlined, UserOutlined } from '@ant-design/icons'; import { LockOutlined, UserOutlined } from '@ant-design/icons';
import style from './index.module.less'; import style from './index.module.less';
import { useRequest } from 'ahooks'; import { useRequest } from 'ahooks';
import { setToken } from '@/utils'; import { encrypt, genKey, setToken } from '@/utils';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { STR_MAP } from '@/config/i18n/locales/constants'; import { STR_MAP } from '@/config/i18n/locales/constants';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -20,7 +20,7 @@ const Login = () => {
const [form] = Form.useForm(); const [form] = Form.useForm();
const navigate = useNavigate(); const navigate = useNavigate();
const { validateFields } = form; const { validateFields } = form;
const [remenberMe, setRemenberMe] = useState(0); const [rememberMe, setRememberMe] = useState(1);
const { t } = useTranslation(); const { t } = useTranslation();
const { run, loading } = useRequest(service.fetchLogin, { const { run, loading } = useRequest(service.fetchLogin, {
@ -36,17 +36,20 @@ const Login = () => {
const handleLogin = useCallback(() => { const handleLogin = useCallback(() => {
validateFields() validateFields()
.then(values => { .then(async values => {
console.log('value:::', values, remenberMe); const { password, username } = values;
let key = genKey();
let encodePassword = await encrypt(password, key);
key = key.split('').reverse().join('');
run({ run({
password: '1BsL68bUgS52alKirqFprU1QfWJyPFlb3dA2AzEMc6kMTpTHN1doEN4=', password: encodePassword,
rememberMe: 1, tag: key,
tag: 'lw4xNmj6QuamOFsy', username,
username: 'baoxinyi_user', rememberMe,
}); });
}) })
.catch(err => console.log('err:::', err)); .catch(err => console.log('err:::', err));
}, [remenberMe, validateFields, run]); }, [validateFields, run, rememberMe]);
const formNode = useMemo( const formNode = useMemo(
() => ( () => (
@ -88,10 +91,9 @@ const Login = () => {
<Form.Item name="rememberMe"> <Form.Item name="rememberMe">
<div className={style['login-edit']}> <div className={style['login-edit']}>
<Checkbox <Checkbox
value={1} checked={Boolean(rememberMe)}
checked
onChange={e => { onChange={e => {
setRemenberMe(e.target.checked ? 1 : 0); setRememberMe(Number(e.target.checked));
}} }}
> >
{t(STR_MAP.REMERBER_PASSWORD)} {t(STR_MAP.REMERBER_PASSWORD)}
@ -113,7 +115,7 @@ const Login = () => {
</Form.Item> </Form.Item>
</Form> </Form>
), ),
[form, loading, handleLogin, t] [form, loading, rememberMe, handleLogin, t]
); );
const items: TabsProps['items'] = [ const items: TabsProps['items'] = [

@ -1,5 +1,5 @@
.tenant_wrapper { .tenant_wrapper {
.opreate_btn { .opreate_btn {
padding: 0px; padding: 0px;
} }
} }

@ -1,5 +1,5 @@
.tenant_wrapper { .tenant_wrapper {
.opreate_btn { .opreate_btn {
padding: 0px; padding: 0px;
} }
} }

@ -1,3 +1,3 @@
/// <reference types="react-scripts" /> /// <reference types="react-scripts" />
declare module '*.less'; declare module '*.less';
declare module 'crypto-browserify' {} declare module 'crypto-js';

@ -1,40 +1,5 @@
import Cookie from 'js-cookie'; import Cookie from 'js-cookie';
// import { Buffer } from 'buffer'; import { Buffer } from 'buffer';
// import crypto from 'crypto-browserify';
// /**
// * generate key
// * @returns {string} key(length 16)
// */
// export function genKey() {
// let chars = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
// let result = '';
// for (let i = 16; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
// return result;
// }
// /**
// * encode message
// * @param msg message
// * @param key key
// * @returns {string} encoded message
// */
// export function encrypt(msg: string, key: string) {
// try {
// let pwd = Buffer.from(key);
// let iv = (crypto as any).randomBytes(12);
// let cipher = (crypto as any).createCipheriv('aes-128-gcm', pwd, iv);
// let enc = cipher.update(msg, 'utf8', 'base64');
// enc += cipher.final('base64');
// let tags = cipher.getAuthTag();
// enc = Buffer.from(enc, 'base64') as any;
// let totalLength = iv.length + enc.length + tags.length;
// let bufferMsg = Buffer.concat([iv, enc as any, tags], totalLength);
// return bufferMsg.toString('base64');
// } catch (e) {
// console.log('Encrypt is error', e);
// return null;
// }
// }
import _ from 'lodash'; import _ from 'lodash';
// is plain object // is plain object
@ -89,4 +54,36 @@ const isEmpty = (value: any) => {
return typeof value === 'object' ? _.isEmpty(value) : isNilValue(value); return typeof value === 'object' ? _.isEmpty(value) : isNilValue(value);
}; };
export { isPlainObject, isEmpty, filterEmptyField, setToken, removeToken, getToken }; function genKey() {
let chars = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
let result = '';
for (let i = 16; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
return result;
}
async function encrypt(msg: string, key: any) {
try {
let pwd = Buffer.from(key);
const cryptoKey = await window.crypto.subtle.importKey('raw', pwd, { name: 'AES-GCM' }, false, ['encrypt']);
const iv = window.crypto.getRandomValues(new Uint8Array(12));
const encodedMsg = new TextEncoder().encode(msg);
const encryptedData = await window.crypto.subtle.encrypt(
{
name: 'AES-GCM',
iv: iv,
},
cryptoKey,
encodedMsg
);
const encryptedArray = new Uint8Array(encryptedData);
const totalLength = iv.length + encryptedArray.length;
const combinedArray = new Uint8Array(totalLength);
combinedArray.set(iv);
combinedArray.set(encryptedArray, iv.length);
return btoa(String.fromCharCode(...combinedArray));
} catch (e) {
return null;
}
}
export { isPlainObject, isEmpty, filterEmptyField, setToken, removeToken, getToken, genKey, encrypt };

@ -124,7 +124,6 @@ function request<T>(url: string, config: RequestOptions): Promise<Response<T>> {
return fetch(url, config as any).then(function onfulfilled(response) { return fetch(url, config as any).then(function onfulfilled(response) {
let { status, statusText } = response; let { status, statusText } = response;
console.log('status:::', status, response);
if (status >= 200 && status < 400) { if (status >= 200 && status < 400) {
let result; let result;
switch (responseType) { switch (responseType) {
@ -141,10 +140,11 @@ function request<T>(url: string, config: RequestOptions): Promise<Response<T>> {
result = response.arrayBuffer(); result = response.arrayBuffer();
break; break;
} }
// business code
result?.then(res => { result?.then(res => {
if (res?.code === 200) { if (!res?.success) {
// console.log(':::'); notification.error({
message: res.message,
});
} }
}); });
return result; return result;

@ -1,11 +1,8 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "es5", "target": "es2015",
"lib": ["dom", "dom.iterable", "esnext"], "lib": ["dom", "dom.iterable", "esnext"],
"typeRoots": [ "typeRoots": ["node_modules/@types", "src/typings"],
"node_modules/@types",
"src/typings"
],
"allowJs": true, "allowJs": true,
"skipLibCheck": true, "skipLibCheck": true,
"esModuleInterop": true, "esModuleInterop": true,
@ -22,8 +19,8 @@
"baseUrl": "./", "baseUrl": "./",
"paths": { "paths": {
// baseUrl // baseUrl
"@/*": ["src/*"], "@/*": ["src/*"]
}, }
}, },
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx"] "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx"]
} }

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save