Login page can also enter prompt page.

This commit is contained in:
Yang Luo
2021-06-20 22:17:03 +08:00
parent a43db3e55a
commit b189993547
5 changed files with 101 additions and 52 deletions

View File

@ -34,7 +34,7 @@ func codeToResponse(code *object.Code) *Response {
} }
} }
func (c *ApiController) HandleLoggedIn(user *object.User, form *RequestForm) *Response { func (c *ApiController) HandleLoggedIn(application *object.Application, user *object.User, form *RequestForm) *Response {
userId := user.GetId() userId := user.GetId()
resp := &Response{} resp := &Response{}
if form.Type == ResponseTypeLogin { if form.Type == ResponseTypeLogin {
@ -50,6 +50,11 @@ func (c *ApiController) HandleLoggedIn(user *object.User, form *RequestForm) *Re
code := object.GetOAuthCode(userId, clientId, responseType, redirectUri, scope, state) code := object.GetOAuthCode(userId, clientId, responseType, redirectUri, scope, state)
resp = codeToResponse(code) resp = codeToResponse(code)
if application.HasPromptPage() {
// The prompt page needs the user to be signed in
c.SetSessionUser(userId)
}
} else { } else {
resp = &Response{Status: "error", Msg: fmt.Sprintf("Unknown response type: %s", form.Type)} resp = &Response{Status: "error", Msg: fmt.Sprintf("Unknown response type: %s", form.Type)}
} }
@ -174,7 +179,8 @@ func (c *ApiController) Login() {
if msg != "" { if msg != "" {
resp = &Response{Status: "error", Msg: msg, Data: ""} resp = &Response{Status: "error", Msg: msg, Data: ""}
} else { } else {
resp = c.HandleLoggedIn(user, &form) application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
resp = c.HandleLoggedIn(application, user, &form)
} }
} else if form.Provider != "" { } else if form.Provider != "" {
application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application)) application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
@ -244,16 +250,9 @@ func (c *ApiController) Login() {
// object.LinkMemberAccount(userId, "avatar", avatar) // object.LinkMemberAccount(userId, "avatar", avatar)
//} //}
resp = c.HandleLoggedIn(user, &form) resp = c.HandleLoggedIn(application, user, &form)
} else { } else {
// Sign up via OAuth // Sign up via OAuth
//if userId := object.GetUserIdByField(application, "email", userInfo.Email); userId != "" {
// resp = c.HandleLoggedIn(userId, &form)
//
// object.LinkUserAccount(userId, provider.Type, userInfo.Id)
//}
if !application.EnableSignUp { if !application.EnableSignUp {
resp = &Response{Status: "error", Msg: fmt.Sprintf("The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support", provider.Type, userInfo.Username, userInfo.DisplayName)} resp = &Response{Status: "error", Msg: fmt.Sprintf("The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support", provider.Type, userInfo.Username, userInfo.DisplayName)}
c.Data["json"] = resp c.Data["json"] = resp
@ -292,7 +291,7 @@ func (c *ApiController) Login() {
object.LinkUserAccount(user, provider.Type, userInfo.Id) object.LinkUserAccount(user, provider.Type, userInfo.Id)
resp = c.HandleLoggedIn(user, &form) resp = c.HandleLoggedIn(application, user, &form)
} }
//resp = &Response{Status: "ok", Msg: "", Data: res} //resp = &Response{Status: "ok", Msg: "", Data: res}
} else { // form.Method != "signup" } else { // form.Method != "signup"

View File

@ -430,8 +430,8 @@ class App extends Component {
<Route exact path="/signup" render={(props) => this.renderHomeIfLoggedIn(<SignupPage {...props} />)}/> <Route exact path="/signup" render={(props) => this.renderHomeIfLoggedIn(<SignupPage {...props} />)}/>
<Route exact path="/signup/:applicationName" render={(props) => this.renderHomeIfLoggedIn(<SignupPage {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account)}} />)}/> <Route exact path="/signup/:applicationName" render={(props) => this.renderHomeIfLoggedIn(<SignupPage {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account)}} />)}/>
<Route exact path="/login" render={(props) => this.renderHomeIfLoggedIn(<SelfLoginPage {...props} />)}/> <Route exact path="/login" render={(props) => this.renderHomeIfLoggedIn(<SelfLoginPage {...props} />)}/>
<Route exact path="/signup/oauth/authorize" render={(props) => <LoginPage type={"code"} mode={"signup"} {...props} />}/> <Route exact path="/signup/oauth/authorize" render={(props) => <LoginPage type={"code"} mode={"signup"} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account)}} />}/>
<Route exact path="/login/oauth/authorize" render={(props) => <LoginPage type={"code"} mode={"signin"} {...props} />}/> <Route exact path="/login/oauth/authorize" render={(props) => <LoginPage type={"code"} mode={"signin"} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account)}} />}/>
<Route exact path="/callback" component={AuthCallback}/> <Route exact path="/callback" component={AuthCallback}/>
<Route exact path="/forget" render={(props) => this.renderHomeIfLoggedIn(<SelfForgetPage {...props} />)}/> <Route exact path="/forget" render={(props) => this.renderHomeIfLoggedIn(<SelfForgetPage {...props} />)}/>
<Route exact path="/forget/:applicationName" render={(props) => this.renderHomeIfLoggedIn(<ForgetPage {...props} />)}/> <Route exact path="/forget/:applicationName" render={(props) => this.renderHomeIfLoggedIn(<ForgetPage {...props} />)}/>

View File

@ -108,6 +108,41 @@ export function hasPromptPage(application) {
return isAffiliationPrompted(application); return isAffiliationPrompted(application);
} }
function isAffiliationAnswered(user, application) {
if (!isAffiliationPrompted(application)) {
return true;
}
if (user === null) {
return false;
}
return user.affiliation !== "";
}
function isProviderItemAnswered(user, application, providerItem) {
if (user === null) {
return false;
}
const provider = providerItem.provider;
const linkedValue = user[provider.type.toLowerCase()];
return linkedValue !== undefined && linkedValue !== "";
}
export function isPromptAnswered(user, application) {
if (!isAffiliationAnswered(user, application)) {
return false;
}
const providerItems = getAllPromptedProviderItems(application);
for (let i = 0; i < providerItems.length; i ++) {
if (!isProviderItemAnswered(user, application, providerItems[i])) {
return false;
}
}
return true;
}
export function parseJson(s) { export function parseJson(s) {
if (s === "") { if (s === "") {
return null; return null;

View File

@ -92,9 +92,16 @@ class LoginPage extends React.Component {
} }
} }
onUpdateAccount(account) {
this.props.onUpdateAccount(account);
}
onFinish(values) { onFinish(values) {
const application = this.getApplicationObj();
const ths = this;
values["type"] = this.state.type; values["type"] = this.state.type;
const oAuthParams = Util.getOAuthGetParameters(); const oAuthParams = Util.getOAuthGetParameters();
AuthBackend.login(values, oAuthParams) AuthBackend.login(values, oAuthParams)
.then((res) => { .then((res) => {
if (res.status === 'ok') { if (res.status === 'ok') {
@ -104,7 +111,32 @@ class LoginPage extends React.Component {
Setting.goToLink("/"); Setting.goToLink("/");
} else if (responseType === "code") { } else if (responseType === "code") {
const code = res.data; const code = res.data;
Setting.goToLink(`${oAuthParams.redirectUri}?code=${code}&state=${oAuthParams.state}`);
if (Setting.hasPromptPage(application)) {
AuthBackend.getAccount("")
.then((res) => {
let account = null;
if (res.status === "ok") {
account = res.data;
account.organization = res.data2;
this.onUpdateAccount(account);
if (Setting.isPromptAnswered(account, application)) {
Setting.goToLink(`${oAuthParams.redirectUri}?code=${code}&state=${oAuthParams.state}`);
} else {
Setting.goToLinkSoft(ths, `/prompt/${application.name}?redirectUri=${oAuthParams.redirectUri}&code=${code}&state=${oAuthParams.state}`);
}
} else {
if (res.msg !== "Please sign in first") {
Setting.showMessage("error", `Failed to sign in: ${res.msg}`);
}
}
});
} else {
Setting.goToLink(`${oAuthParams.redirectUri}?code=${code}&state=${oAuthParams.state}`);
}
// Util.showMessage("success", `Authorization code: ${res.data}`); // Util.showMessage("success", `Authorization code: ${res.data}`);
} }
} else { } else {
@ -195,9 +227,10 @@ class LoginPage extends React.Component {
name="normal_login" name="normal_login"
initialValues={{ initialValues={{
organization: application.organization, organization: application.organization,
application: application.name,
remember: true remember: true
}} }}
onFinish={this.onFinish.bind(this)} onFinish={(values) => {this.onFinish(values)}}
style={{width: "250px"}} style={{width: "250px"}}
size="large" size="large"
> >

View File

@ -126,52 +126,34 @@ class PromptPage extends React.Component {
) )
} }
isProviderItemAnswered(application, providerItem) {
if (this.state.user === null) {
return false;
}
const provider = providerItem.provider;
const linkedValue = this.state.user[provider.type.toLowerCase()];
return linkedValue !== undefined && linkedValue !== "";
}
isAffiliationAnswered(application) {
if (!Setting.isAffiliationPrompted(application)) {
return true;
}
if (this.state.user === null) {
return false;
}
return this.state.user.affiliation !== "";
}
isAnswered(application) {
if (!this.isAffiliationAnswered(application)) {
return false;
}
const providerItems = Setting.getAllPromptedProviderItems(application);
for (let i = 0; i < providerItems.length; i ++) {
if (!this.isProviderItemAnswered(application, providerItems[i])) {
return false;
}
}
return true;
}
onUpdateAccount(account) { onUpdateAccount(account) {
this.props.onUpdateAccount(account); this.props.onUpdateAccount(account);
} }
getRedirectUrl() {
// "/prompt/app-example?redirectUri=http://localhost:2000/callback&code=8eb113b072296818f090&state=app-example"
const params = new URLSearchParams(this.props.location.search);
const redirectUri = params.get("redirectUri");
const code = params.get("code");
const state = params.get("state");
if (redirectUri === null || code === null || state === null) {
return "";
}
return `${redirectUri}?code=${code}&state=${state}`;
}
logout() { logout() {
AuthBackend.logout() AuthBackend.logout()
.then((res) => { .then((res) => {
if (res.status === 'ok') { if (res.status === 'ok') {
this.onUpdateAccount(null); this.onUpdateAccount(null);
Setting.goToLogin(this, this.getApplicationObj()); const redirectUrl = this.getRedirectUrl();
if (redirectUrl !== "") {
Setting.goToLink(redirectUrl);
} else {
Setting.goToLogin(this, this.getApplicationObj());
}
} else { } else {
Setting.showMessage("error", `Failed to log out: ${res.msg}`); Setting.showMessage("error", `Failed to log out: ${res.msg}`);
} }
@ -245,7 +227,7 @@ class PromptPage extends React.Component {
</Col> </Col>
</Row> </Row>
<div style={{marginTop: "50px"}}> <div style={{marginTop: "50px"}}>
<Button disabled={!this.isAnswered(application)} type="primary" size="large" onClick={() => {this.submitUserEdit(true)}}>{i18next.t("signup:Submit and complete")}</Button> <Button disabled={!Setting.isPromptAnswered(this.state.user, application)} type="primary" size="large" onClick={() => {this.submitUserEdit(true)}}>{i18next.t("signup:Submit and complete")}</Button>
</div> </div>
</div> </div>
</Col> </Col>