fix(fe): enable captcha at user level

This commit is contained in:
hexxa 2022-01-27 22:22:54 +08:00 committed by Hexxa
parent b0e280ee70
commit 99b424ee2a
9 changed files with 54 additions and 87 deletions

View file

@ -89,12 +89,10 @@ export interface GetSharingDirResp {
} }
export interface ClientConfigMsg { export interface ClientConfigMsg {
clientCfg: ClientConfig;
}
export interface ClientConfig {
siteName: string; siteName: string;
siteDesc: string; siteDesc: string;
bg: BgConfig; bg: BgConfig;
captchaEnabled?: boolean;
} }
export interface ClientErrorReport { export interface ClientErrorReport {
@ -154,7 +152,7 @@ export interface IFilesClient {
export interface ISettingsClient { export interface ISettingsClient {
health: () => Promise<Response>; health: () => Promise<Response>;
getClientCfg: () => Promise<Response>; getClientCfg: () => Promise<Response>;
setClientCfg: (cfg: ClientConfig) => Promise<Response>; setClientCfg: (cfg: ClientConfigMsg) => Promise<Response>;
reportErrors: (reports: List<ClientErrorReport>) => Promise<Response>; reportErrors: (reports: List<ClientErrorReport>) => Promise<Response>;
} }

View file

@ -1,7 +1,7 @@
import { List } from "immutable"; import { List } from "immutable";
import { BaseClient, Response, userIDParam, Quota } from "."; import { BaseClient, Response, userIDParam, Quota } from ".";
import { ClientConfig, ClientErrorReport } from "./"; import { ClientConfigMsg, ClientErrorReport } from "./";
export class SettingsClient extends BaseClient { export class SettingsClient extends BaseClient {
constructor(url: string) { constructor(url: string) {
@ -22,13 +22,11 @@ export class SettingsClient extends BaseClient {
}); });
}; };
setClientCfg = (cfg: ClientConfig): Promise<Response> => { setClientCfg = (cfg: ClientConfigMsg): Promise<Response> => {
return this.do({ return this.do({
method: "patch", method: "patch",
url: `${this.url}/v1/settings/client`, url: `${this.url}/v1/settings/client`,
data: { data: cfg,
clientCfg: cfg,
},
}); });
}; };

View file

@ -15,7 +15,6 @@ export const resps = {
status: 200, status: 200,
statusText: "", statusText: "",
data: { data: {
clientCfg: {
siteName: "", siteName: "",
siteDesc: "", siteDesc: "",
bg: { bg: {
@ -26,48 +25,12 @@ export const resps = {
}, },
}, },
}, },
},
reportErrorsMockResp: { reportErrorsMockResp: {
status: 200, status: 200,
statusText: "", statusText: "",
data: {}, data: {},
}, },
}; };
export class MockSettingsClient {
private url: string;
private resps: SettingsClientResps;
constructor(url: string) {
this.url = url;
this.resps = resps;
}
setMock = (resps: SettingsClientResps) => {
this.resps = resps;
};
wrapPromise = (resp: any): Promise<any> => {
return new Promise<any>((resolve) => {
resolve(resp);
});
};
health = (): Promise<Response> => {
return this.wrapPromise(this.resps.healthMockResp);
};
setClientCfg = (): Promise<Response> => {
return this.wrapPromise(this.resps.setClientCfgMockResp);
};
getClientCfg = (): Promise<Response> => {
return this.wrapPromise(this.resps.getClientCfgMockResp);
};
reportErrors = (): Promise<Response> => {
return this.wrapPromise(this.resps.reportErrorsMockResp);
};
}
export class JestSettingsClient { export class JestSettingsClient {
url: string = ""; url: string = "";

View file

@ -34,6 +34,7 @@ describe("Login", () => {
const pane = new AuthPane({ const pane = new AuthPane({
login: coreState.login, login: coreState.login,
msg: coreState.msg, msg: coreState.msg,
ui: coreState.ui,
update: (updater: (prevState: ICoreState) => ICoreState) => {}, update: (updater: (prevState: ICoreState) => ICoreState) => {},
}); });

View file

@ -124,7 +124,7 @@ describe("State Manager", () => {
// ui // ui
expect(coreState.ui.bg).toEqual( expect(coreState.ui.bg).toEqual(
settingsResps.getClientCfgMockResp.data.clientCfg.bg settingsResps.getClientCfgMockResp.data.bg
); );
}); });
@ -226,7 +226,7 @@ describe("State Manager", () => {
// ui // ui
expect(coreState.ui.bg).toEqual( expect(coreState.ui.bg).toEqual(
settingsResps.getClientCfgMockResp.data.clientCfg.bg settingsResps.getClientCfgMockResp.data.bg
); );
}); });

View file

@ -28,6 +28,7 @@ export interface UIProps {
isVertical: boolean; isVertical: boolean;
siteName: string; siteName: string;
siteDesc: string; siteDesc: string;
captchaEnabled: boolean;
bg: { bg: {
url: string; url: string;
repeat: string; repeat: string;
@ -111,6 +112,7 @@ export function initState(): ICoreState {
position: "", position: "",
align: "", align: "",
}, },
captchaEnabled: true,
control: { control: {
controls: Map<string, string>({ controls: Map<string, string>({
[panelTabs]: "filesPanel", [panelTabs]: "filesPanel",

View file

@ -57,6 +57,7 @@ export class Layers extends React.Component<Props, State, {}> {
<div id="root-container"> <div id="root-container">
<AuthPane <AuthPane
login={this.props.login} login={this.props.login}
ui={this.props.ui}
update={this.props.update} update={this.props.update}
msg={this.props.msg} msg={this.props.msg}
/> />

View file

@ -1,7 +1,7 @@
import * as React from "react"; import * as React from "react";
import { List } from "immutable"; import { List } from "immutable";
import { ICoreState, MsgProps } from "./core_state"; import { ICoreState, MsgProps, UIProps } from "./core_state";
import { Flexbox } from "./layout/flexbox"; import { Flexbox } from "./layout/flexbox";
import { updater } from "./state_updater"; import { updater } from "./state_updater";
import { alertMsg } from "../common/env"; import { alertMsg } from "../common/env";
@ -26,6 +26,7 @@ export interface LoginProps {
export interface Props { export interface Props {
login: LoginProps; login: LoginProps;
msg: MsgProps; msg: MsgProps;
ui: UIProps;
update?: (updater: (prevState: ICoreState) => ICoreState) => void; update?: (updater: (prevState: ICoreState) => ICoreState) => void;
} }
@ -106,6 +107,34 @@ export class AuthPane extends React.Component<Props, State, {}> {
}; };
render() { render() {
const row3 = this.props.ui.captchaEnabled ? (
<Flexbox
children={List([
<div className="input-wrap">
<input
id="captcha-input"
type="text"
onChange={this.changeCaptcha}
value={this.state.captchaInput}
placeholder={this.props.msg.pkg.get("login.captcha")}
/>
</div>,
<img
id="captcha"
src={`/v1/captchas/imgs?capid=${this.props.login.captchaID}`}
className={`captcha ${this.state.captchaLoaded ? "" : "hidden"}`}
onClick={this.refreshCaptcha}
onLoad={() => this.setState({ captchaLoaded: true })}
/>,
])}
childrenStyles={List([
{ justifyContent: "flex-start" },
{ justifyContent: "flex-end" },
])}
/>
) : null;
return ( return (
<div <div
id="pane-login" id="pane-login"
@ -144,33 +173,7 @@ export class AuthPane extends React.Component<Props, State, {}> {
/> />
</div> </div>
<Flexbox {row3}
children={List([
<div className="input-wrap">
<input
id="captcha-input"
type="text"
onChange={this.changeCaptcha}
value={this.state.captchaInput}
placeholder={this.props.msg.pkg.get("login.captcha")}
/>
</div>,
<img
id="captcha"
src={`/v1/captchas/imgs?capid=${this.props.login.captchaID}`}
className={`captcha ${
this.state.captchaLoaded ? "" : "hidden"
}`}
onClick={this.refreshCaptcha}
onLoad={() => this.setState({ captchaLoaded: true })}
/>,
])}
childrenStyles={List([
{ justifyContent: "flex-start" },
{ justifyContent: "flex-end" },
])}
/>
<button id="btn-login" onClick={this.login}> <button id="btn-login" onClick={this.login}>
{this.props.msg.pkg.get("login.login")} {this.props.msg.pkg.get("login.login")}

View file

@ -17,7 +17,7 @@ import {
roleUser, roleUser,
roleAdmin, roleAdmin,
visitorID, visitorID,
ClientConfig, ClientConfigMsg,
Preferences, Preferences,
} from "../client"; } from "../client";
import { FilesClient, shareIDQuery, shareDirQuery } from "../client/files"; import { FilesClient, shareIDQuery, shareDirQuery } from "../client/files";
@ -780,12 +780,12 @@ export class Updater {
return resp.status === 200 ? "" : errServer; return resp.status === 200 ? "" : errServer;
}; };
setClientCfgRemote = async (cfg: ClientConfig): Promise<string> => { setClientCfgRemote = async (cfg: ClientConfigMsg): Promise<string> => {
const resp = await this.settingsClient.setClientCfg(cfg); const resp = await this.settingsClient.setClientCfg(cfg);
return resp.status === 200 ? "" : errServer; return resp.status === 200 ? "" : errServer;
}; };
setClientCfg = (cfg: ClientConfig) => { setClientCfg = (cfg: ClientConfigMsg) => {
this.props.ui = { this.props.ui = {
...this.props.ui, ...this.props.ui,
siteName: cfg.siteName, siteName: cfg.siteName,
@ -810,10 +810,11 @@ export class Updater {
if (resp.status !== 200) { if (resp.status !== 200) {
return errServer; return errServer;
} }
const clientCfg = resp.data.clientCfg as ClientConfig; const clientCfg = resp.data as ClientConfigMsg;
this.props.ui.siteName = clientCfg.siteName; this.props.ui.siteName = clientCfg.siteName;
this.props.ui.siteDesc = clientCfg.siteDesc; this.props.ui.siteDesc = clientCfg.siteDesc;
this.props.ui.bg = clientCfg.bg; this.props.ui.bg = clientCfg.bg;
this.props.ui.captchaEnabled = clientCfg.captchaEnabled;
return ""; return "";
}; };