Merge pull request #725 from ONLYOFFICE/bugfix/tfa

Fix redirect and close reset dialog
This commit is contained in:
Alexey Safronov 2022-07-20 13:09:57 +03:00 committed by GitHub
commit 0ee18542ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 49 additions and 26 deletions

View File

@ -376,7 +376,7 @@ export function getTfaSettings() {
export function setTfaSettings(type) {
return request({
method: "put",
url: "/settings/tfaapp",
url: "/settings/tfaappwithlink",
data: { type: type },
});
}
@ -424,17 +424,21 @@ export function getTfaSecretKeyAndQR(confirmKey = null) {
return request(options);
}
export function validateTfaCode(code) {
export function validateTfaCode(code, confirmKey = null) {
const data = {
code,
};
return request({
const options = {
method: "post",
url: "/settings/tfaapp/validate",
skipLogout: true,
data,
});
};
if (confirmKey) options.headers = { confirm: confirmKey };
return request(options);
}
export function getBackupStorage() {

View File

@ -53,6 +53,8 @@ class AuthStore {
if (this.isAuthenticated && !skipModules) {
this.userStore.user && requests.push(this.moduleStore.init());
!this.settingsStore.passwordSettings &&
requests.push(this.settingsStore.getPortalPasswordSettings());
}
return Promise.all(requests);

View File

@ -54,8 +54,8 @@ class TfaStore {
return api.user.loginWithTfaCode(userName, passwordHash, code);
};
loginWithCodeAndCookie = async (code) => {
return api.settings.validateTfaCode(code);
loginWithCodeAndCookie = async (code, confirmKey = null) => {
return api.settings.validateTfaCode(code, confirmKey);
};
getBackupCodes = async () => {

View File

@ -4,6 +4,7 @@ import ModalDialog from "@appserver/components/modal-dialog";
import Button from "@appserver/components/button";
import Text from "@appserver/components/text";
import { withTranslation } from "react-i18next";
import { withRouter } from "react-router";
import ModalDialogContainer from "../ModalDialogContainer";
import toastr from "studio/toastr";
@ -13,11 +14,11 @@ class ResetApplicationDialogComponent extends React.Component {
}
resetApp = async () => {
const { resetTfaApp, history, id } = this.props;
const { resetTfaApp, id, onClose, history } = this.props;
onClose && onClose();
try {
const res = await resetTfaApp(id);
if (res) history.push(res);
if (res) history.push(res.replace(window.location.origin, ""));
} catch (e) {
toastr.error(e);
}
@ -60,10 +61,11 @@ class ResetApplicationDialogComponent extends React.Component {
}
}
const ResetApplicationDialog = withTranslation([
"ResetApplicationDialog",
"Common",
])(ResetApplicationDialogComponent);
const ResetApplicationDialog = withRouter(
withTranslation(["ResetApplicationDialog", "Common"])(
ResetApplicationDialogComponent
)
);
ResetApplicationDialog.propTypes = {
visible: PropTypes.bool.isRequired,

View File

@ -588,7 +588,7 @@ class SectionBodyContent extends React.PureComponent {
export default withRouter(
inject(({ auth, peopleStore }) => {
const { isAdmin, userStore, settingsStore, tfaStore } = auth;
const { isAdmin, userStore, settingsStore, tfaStore, logout } = auth;
const { user: viewer, changeTheme } = userStore;
const {
@ -649,6 +649,7 @@ export default withRouter(
changeTheme,
selectedTheme: viewer.theme,
setIsLoading: loadingStore.setIsLoading,
logout,
};
})(
observer(

View File

@ -45,6 +45,7 @@ public class TfaappController : BaseSettingsController
private readonly StudioSmsNotificationSettingsHelper _studioSmsNotificationSettingsHelper;
private readonly InstanceCrypto _instanceCrypto;
private readonly Signature _signature;
private readonly SecurityContext _securityContext;
public TfaappController(
MessageService messageService,
@ -65,6 +66,7 @@ public class TfaappController : BaseSettingsController
IMemoryCache memoryCache,
InstanceCrypto instanceCrypto,
Signature signature,
SecurityContext securityContext,
IHttpContextAccessor httpContextAccessor) : base(apiContext, memoryCache, webItemManager, httpContextAccessor)
{
_smsProviderManager = smsProviderManager;
@ -82,6 +84,7 @@ public class TfaappController : BaseSettingsController
_studioSmsNotificationSettingsHelper = studioSmsNotificationSettingsHelper;
_instanceCrypto = instanceCrypto;
_signature = signature;
_securityContext = securityContext;
}
[HttpGet("tfaapp")]
@ -119,11 +122,12 @@ public class TfaappController : BaseSettingsController
}
[HttpPost("tfaapp/validate")]
[Authorize(AuthenticationSchemes = "confirm", Roles = "TfaActivation,Everyone")]
[Authorize(AuthenticationSchemes = "confirm", Roles = "TfaActivation,TfaAuth,Everyone")]
public bool TfaValidateAuthCode(TfaValidateRequestsDto inDto)
{
ApiContext.AuthByClaim();
var user = _userManager.GetUsers(_authContext.CurrentAccount.ID);
_securityContext.Logout();
return _tfaManager.ValidateAuthCode(user, inDto.Code);
}
@ -235,6 +239,17 @@ public class TfaappController : BaseSettingsController
return result;
}
[HttpPut("tfaappwithlink")]
public async Task<object> TfaSettingsLink(TfaRequestsDto inDto)
{
if (await TfaSettings(inDto))
{
return TfaConfirmUrl();
}
return string.Empty;
}
[HttpGet("tfaapp/setup")]
[Authorize(AuthenticationSchemes = "confirm", Roles = "TfaActivation")]
public SetupCode TfaAppGenerateSetupCode()
@ -296,10 +311,10 @@ public class TfaappController : BaseSettingsController
}
[HttpPut("tfaappnewapp")]
public object TfaAppNewApp(TfaRequestsDto inDto)
public async Task<object> TfaAppNewApp(TfaRequestsDto inDto)
{
var id = inDto?.Id ?? Guid.Empty;
var isMe = id.Equals(Guid.Empty) || id.Equals(_authContext.CurrentAccount.ID);
var isMe = id.Equals(Guid.Empty) || id.Equals(_authContext.CurrentAccount.ID);
var user = _userManager.GetUsers(id);
@ -323,6 +338,7 @@ public class TfaappController : BaseSettingsController
if (isMe)
{
await _cookiesManager.ResetTenantCookie();
return _commonLinkUtility.GetConfirmationUrl(user.Email, ConfirmType.TfaActivation);
}

View File

@ -89,6 +89,7 @@ const TfaActivationForm = withLoader((props) => {
const onSubmit = async () => {
try {
const { user, hash } = (location && location.state) || {};
const { linkData } = props;
setIsLoading(true);
@ -96,7 +97,7 @@ const TfaActivationForm = withLoader((props) => {
const url = await loginWithCode(user, hash, code);
history.push(url || "/");
} else {
const url = await loginWithCodeAndCookie(code);
const url = await loginWithCodeAndCookie(code, linkData.confirmHeader);
history.push(url || "/");
}
} catch (e) {

View File

@ -60,6 +60,7 @@ const TfaAuthForm = withLoader((props) => {
const onSubmit = async () => {
try {
const { user, hash } = (location && location.state) || {};
const { linkData } = props;
setIsLoading(true);
@ -67,7 +68,7 @@ const TfaAuthForm = withLoader((props) => {
const url = await loginWithCode(user, hash, code);
history.push(url || "/");
} else {
const url = await loginWithCodeAndCookie(code);
const url = await loginWithCodeAndCookie(code, linkData.confirmHeader);
history.push(url || "/");
}
} catch (e) {

View File

@ -94,17 +94,16 @@ const TwoFactorAuth = (props) => {
setIsSaving(true);
try {
await setTfaSettings(type);
const res = await setTfaSettings(type);
toastr.success(t("SuccessfullySaveSettingsMessage"));
saveToSessionStorage("defaultTfaSettings", type);
setIsSaving(false);
setShowReminder(false);
if (type !== "none") {
if (res) {
setIsInit(false);
const link = await getTfaConfirmLink();
history.push(link.replace(window.location.origin, ""));
history.push(res.replace(window.location.origin, ""));
}
} catch (error) {
toastr.error(error);
@ -117,7 +116,6 @@ const TwoFactorAuth = (props) => {
setShowReminder(false);
};
if (isMobile && !isInit && !isLoading) {
return <TfaLoader />;
}

View File

@ -261,8 +261,6 @@ public class CookiesManager
_tenantCookieSettingsHelper.SetForTenant(tenant.Id, settings);
await _dbLoginEventsManager.LogOutAllActiveConnectionsForTenant(tenant.Id);
AuthenticateMeAndSetCookies(tenant.Id, _securityContext.CurrentAccount.ID, MessageAction.LoginSuccess);
}
public string AuthenticateMeAndSetCookies(int tenantId, Guid userId, MessageAction action, bool session = false)