mirror of
https://github.com/flarum/framework.git
synced 2025-02-09 06:03:59 +08:00
Remove sudo mode and add password confirmation when changing email address
closes #674
This commit is contained in:
parent
c95dbc0cb4
commit
e46878902a
129
framework/core/js/admin/dist/app.js
vendored
129
framework/core/js/admin/dist/app.js
vendored
|
@ -16951,15 +16951,6 @@ System.register('flarum/App', ['flarum/utils/ItemList', 'flarum/components/Alert
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
_this2.requestError = error;
|
_this2.requestError = error;
|
||||||
|
|
||||||
if (error.response && error.response.errors && error.response.errors[0] && error.response.errors[0].code === 'invalid_access_token') {
|
|
||||||
_this2.modal.show(new ConfirmPasswordModal({
|
|
||||||
deferredRequest: originalOptions,
|
|
||||||
deferred: deferred,
|
|
||||||
error: error
|
|
||||||
}));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var children = undefined;
|
var children = undefined;
|
||||||
|
|
||||||
switch (error.status) {
|
switch (error.status) {
|
||||||
|
@ -18302,121 +18293,6 @@ System.register('flarum/components/Checkbox', ['flarum/Component', 'flarum/compo
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});;
|
});;
|
||||||
System.register('flarum/components/ConfirmPasswordModal', ['flarum/components/Modal', 'flarum/components/Button', 'flarum/utils/extractText'], function (_export) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var Modal, Button, extractText, ConfirmPasswordModal;
|
|
||||||
return {
|
|
||||||
setters: [function (_flarumComponentsModal) {
|
|
||||||
Modal = _flarumComponentsModal['default'];
|
|
||||||
}, function (_flarumComponentsButton) {
|
|
||||||
Button = _flarumComponentsButton['default'];
|
|
||||||
}, function (_flarumUtilsExtractText) {
|
|
||||||
extractText = _flarumUtilsExtractText['default'];
|
|
||||||
}],
|
|
||||||
execute: function () {
|
|
||||||
ConfirmPasswordModal = (function (_Modal) {
|
|
||||||
babelHelpers.inherits(ConfirmPasswordModal, _Modal);
|
|
||||||
|
|
||||||
function ConfirmPasswordModal() {
|
|
||||||
babelHelpers.classCallCheck(this, ConfirmPasswordModal);
|
|
||||||
babelHelpers.get(Object.getPrototypeOf(ConfirmPasswordModal.prototype), 'constructor', this).apply(this, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
babelHelpers.createClass(ConfirmPasswordModal, [{
|
|
||||||
key: 'init',
|
|
||||||
value: function init() {
|
|
||||||
babelHelpers.get(Object.getPrototypeOf(ConfirmPasswordModal.prototype), 'init', this).call(this);
|
|
||||||
|
|
||||||
this.password = m.prop('');
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
key: 'className',
|
|
||||||
value: function className() {
|
|
||||||
return 'ConfirmPasswordModal Modal--small';
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
key: 'title',
|
|
||||||
value: function title() {
|
|
||||||
return app.translator.trans('core.forum.confirm_password.title');
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
key: 'content',
|
|
||||||
value: function content() {
|
|
||||||
return m(
|
|
||||||
'div',
|
|
||||||
{ className: 'Modal-body' },
|
|
||||||
m(
|
|
||||||
'div',
|
|
||||||
{ className: 'Form Form--centered' },
|
|
||||||
m(
|
|
||||||
'div',
|
|
||||||
{ className: 'Form-group' },
|
|
||||||
m('input', {
|
|
||||||
type: 'password',
|
|
||||||
className: 'FormControl',
|
|
||||||
bidi: this.password,
|
|
||||||
placeholder: extractText(app.translator.trans('core.forum.confirm_password.password_placeholder')),
|
|
||||||
disabled: this.loading })
|
|
||||||
),
|
|
||||||
m(
|
|
||||||
'div',
|
|
||||||
{ className: 'Form-group' },
|
|
||||||
m(
|
|
||||||
Button,
|
|
||||||
{
|
|
||||||
type: 'submit',
|
|
||||||
className: 'Button Button--primary Button--block',
|
|
||||||
loading: this.loading },
|
|
||||||
app.translator.trans('core.forum.confirm_password.submit_button')
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
key: 'onsubmit',
|
|
||||||
value: function onsubmit(e) {
|
|
||||||
var _this = this;
|
|
||||||
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
this.loading = true;
|
|
||||||
|
|
||||||
app.session.login(app.session.user.email(), this.password(), { errorHandler: this.onerror.bind(this) }).then(function () {
|
|
||||||
_this.success = true;
|
|
||||||
_this.hide();
|
|
||||||
app.request(_this.props.deferredRequest).then(function (response) {
|
|
||||||
return _this.props.deferred.resolve(response);
|
|
||||||
}, function (response) {
|
|
||||||
return _this.props.deferred.reject(response);
|
|
||||||
});
|
|
||||||
})['catch'](this.loaded.bind(this));
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
key: 'onerror',
|
|
||||||
value: function onerror(error) {
|
|
||||||
if (error.status === 401) {
|
|
||||||
error.alert.props.children = app.translator.trans('core.forum.log_in.invalid_login_message');
|
|
||||||
}
|
|
||||||
|
|
||||||
babelHelpers.get(Object.getPrototypeOf(ConfirmPasswordModal.prototype), 'onerror', this).call(this, error);
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
key: 'onhide',
|
|
||||||
value: function onhide() {
|
|
||||||
if (this.success) return;
|
|
||||||
|
|
||||||
this.props.deferred.reject(this.props.error);
|
|
||||||
}
|
|
||||||
}]);
|
|
||||||
return ConfirmPasswordModal;
|
|
||||||
})(Modal);
|
|
||||||
|
|
||||||
_export('default', ConfirmPasswordModal);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});;
|
|
||||||
System.register("flarum/components/DashboardPage", ["flarum/Component"], function (_export) {
|
System.register("flarum/components/DashboardPage", ["flarum/Component"], function (_export) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
@ -21934,10 +21810,13 @@ System.register('flarum/Model', [], function (_export) {
|
||||||
|
|
||||||
this.pushData(data);
|
this.pushData(data);
|
||||||
|
|
||||||
|
var request = { data: data };
|
||||||
|
if (options.meta) request.meta = options.meta;
|
||||||
|
|
||||||
return app.request(babelHelpers._extends({
|
return app.request(babelHelpers._extends({
|
||||||
method: this.exists ? 'PATCH' : 'POST',
|
method: this.exists ? 'PATCH' : 'POST',
|
||||||
url: app.forum.attribute('apiUrl') + this.apiEndpoint(),
|
url: app.forum.attribute('apiUrl') + this.apiEndpoint(),
|
||||||
data: { data: data }
|
data: request
|
||||||
}, options)).then(
|
}, options)).then(
|
||||||
// If everything went well, we'll make sure the store knows that this
|
// If everything went well, we'll make sure the store knows that this
|
||||||
// model exists now (if it didn't already), and we'll push the data that
|
// model exists now (if it didn't already), and we'll push the data that
|
||||||
|
|
164
framework/core/js/forum/dist/app.js
vendored
164
framework/core/js/forum/dist/app.js
vendored
|
@ -18608,15 +18608,6 @@ System.register('flarum/App', ['flarum/utils/ItemList', 'flarum/components/Alert
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
_this2.requestError = error;
|
_this2.requestError = error;
|
||||||
|
|
||||||
if (error.response && error.response.errors && error.response.errors[0] && error.response.errors[0].code === 'invalid_access_token') {
|
|
||||||
_this2.modal.show(new ConfirmPasswordModal({
|
|
||||||
deferredRequest: originalOptions,
|
|
||||||
deferred: deferred,
|
|
||||||
error: error
|
|
||||||
}));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var children = undefined;
|
var children = undefined;
|
||||||
|
|
||||||
switch (error.status) {
|
switch (error.status) {
|
||||||
|
@ -19577,6 +19568,13 @@ System.register('flarum/components/ChangeEmailModal', ['flarum/components/Modal'
|
||||||
* @type {function}
|
* @type {function}
|
||||||
*/
|
*/
|
||||||
this.email = m.prop(app.session.user.email());
|
this.email = m.prop(app.session.user.email());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value of the password input.
|
||||||
|
*
|
||||||
|
* @type {function}
|
||||||
|
*/
|
||||||
|
this.password = m.prop('');
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'className',
|
key: 'className',
|
||||||
|
@ -19631,8 +19629,15 @@ System.register('flarum/components/ChangeEmailModal', ['flarum/components/Modal'
|
||||||
{ className: 'Form-group' },
|
{ className: 'Form-group' },
|
||||||
m('input', { type: 'email', name: 'email', className: 'FormControl',
|
m('input', { type: 'email', name: 'email', className: 'FormControl',
|
||||||
placeholder: app.session.user.email(),
|
placeholder: app.session.user.email(),
|
||||||
value: this.email(),
|
bidi: this.email,
|
||||||
onchange: m.withAttr('value', this.email),
|
disabled: this.loading })
|
||||||
|
),
|
||||||
|
m(
|
||||||
|
'div',
|
||||||
|
{ className: 'Form-group' },
|
||||||
|
m('input', { type: 'password', name: 'password', className: 'FormControl',
|
||||||
|
placeholder: app.translator.trans('core.forum.change_email.confirm_password_label'),
|
||||||
|
bidi: this.password,
|
||||||
disabled: this.loading })
|
disabled: this.loading })
|
||||||
),
|
),
|
||||||
m(
|
m(
|
||||||
|
@ -19666,14 +19671,21 @@ System.register('flarum/components/ChangeEmailModal', ['flarum/components/Modal'
|
||||||
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
|
|
||||||
app.session.user.save({ email: this.email() }, { errorHandler: this.onerror.bind(this) }).then(function () {
|
app.session.user.save({ email: this.email() }, {
|
||||||
|
errorHandler: this.onerror.bind(this),
|
||||||
|
meta: { password: this.password() }
|
||||||
|
}).then(function () {
|
||||||
return _this.success = true;
|
return _this.success = true;
|
||||||
})['catch'](function () {}).then(this.loaded.bind(this));
|
})['catch'](function () {}).then(this.loaded.bind(this));
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'onerror',
|
||||||
|
value: function onerror(error) {
|
||||||
|
if (error.status === 401) {
|
||||||
|
error.alert.props.children = app.translator.trans('core.forum.change_email.incorrect_password_message');
|
||||||
|
}
|
||||||
|
|
||||||
// The save method will update the cached email address on the user model...
|
babelHelpers.get(Object.getPrototypeOf(ChangeEmailModal.prototype), 'onerror', this).call(this, error);
|
||||||
// But in the case of a "sudo" password prompt, we'll still want to have
|
|
||||||
// the old email address on file for the purposes of logging in.
|
|
||||||
app.session.user.pushAttributes({ email: oldEmail });
|
|
||||||
}
|
}
|
||||||
}]);
|
}]);
|
||||||
return ChangeEmailModal;
|
return ChangeEmailModal;
|
||||||
|
@ -20826,121 +20838,6 @@ System.register('flarum/components/ComposerButton', ['flarum/components/Button']
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});;
|
});;
|
||||||
System.register('flarum/components/ConfirmPasswordModal', ['flarum/components/Modal', 'flarum/components/Button', 'flarum/utils/extractText'], function (_export) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var Modal, Button, extractText, ConfirmPasswordModal;
|
|
||||||
return {
|
|
||||||
setters: [function (_flarumComponentsModal) {
|
|
||||||
Modal = _flarumComponentsModal['default'];
|
|
||||||
}, function (_flarumComponentsButton) {
|
|
||||||
Button = _flarumComponentsButton['default'];
|
|
||||||
}, function (_flarumUtilsExtractText) {
|
|
||||||
extractText = _flarumUtilsExtractText['default'];
|
|
||||||
}],
|
|
||||||
execute: function () {
|
|
||||||
ConfirmPasswordModal = (function (_Modal) {
|
|
||||||
babelHelpers.inherits(ConfirmPasswordModal, _Modal);
|
|
||||||
|
|
||||||
function ConfirmPasswordModal() {
|
|
||||||
babelHelpers.classCallCheck(this, ConfirmPasswordModal);
|
|
||||||
babelHelpers.get(Object.getPrototypeOf(ConfirmPasswordModal.prototype), 'constructor', this).apply(this, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
babelHelpers.createClass(ConfirmPasswordModal, [{
|
|
||||||
key: 'init',
|
|
||||||
value: function init() {
|
|
||||||
babelHelpers.get(Object.getPrototypeOf(ConfirmPasswordModal.prototype), 'init', this).call(this);
|
|
||||||
|
|
||||||
this.password = m.prop('');
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
key: 'className',
|
|
||||||
value: function className() {
|
|
||||||
return 'ConfirmPasswordModal Modal--small';
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
key: 'title',
|
|
||||||
value: function title() {
|
|
||||||
return app.translator.trans('core.forum.confirm_password.title');
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
key: 'content',
|
|
||||||
value: function content() {
|
|
||||||
return m(
|
|
||||||
'div',
|
|
||||||
{ className: 'Modal-body' },
|
|
||||||
m(
|
|
||||||
'div',
|
|
||||||
{ className: 'Form Form--centered' },
|
|
||||||
m(
|
|
||||||
'div',
|
|
||||||
{ className: 'Form-group' },
|
|
||||||
m('input', {
|
|
||||||
type: 'password',
|
|
||||||
className: 'FormControl',
|
|
||||||
bidi: this.password,
|
|
||||||
placeholder: extractText(app.translator.trans('core.forum.confirm_password.password_placeholder')),
|
|
||||||
disabled: this.loading })
|
|
||||||
),
|
|
||||||
m(
|
|
||||||
'div',
|
|
||||||
{ className: 'Form-group' },
|
|
||||||
m(
|
|
||||||
Button,
|
|
||||||
{
|
|
||||||
type: 'submit',
|
|
||||||
className: 'Button Button--primary Button--block',
|
|
||||||
loading: this.loading },
|
|
||||||
app.translator.trans('core.forum.confirm_password.submit_button')
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
key: 'onsubmit',
|
|
||||||
value: function onsubmit(e) {
|
|
||||||
var _this = this;
|
|
||||||
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
this.loading = true;
|
|
||||||
|
|
||||||
app.session.login(app.session.user.email(), this.password(), { errorHandler: this.onerror.bind(this) }).then(function () {
|
|
||||||
_this.success = true;
|
|
||||||
_this.hide();
|
|
||||||
app.request(_this.props.deferredRequest).then(function (response) {
|
|
||||||
return _this.props.deferred.resolve(response);
|
|
||||||
}, function (response) {
|
|
||||||
return _this.props.deferred.reject(response);
|
|
||||||
});
|
|
||||||
})['catch'](this.loaded.bind(this));
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
key: 'onerror',
|
|
||||||
value: function onerror(error) {
|
|
||||||
if (error.status === 401) {
|
|
||||||
error.alert.props.children = app.translator.trans('core.forum.log_in.invalid_login_message');
|
|
||||||
}
|
|
||||||
|
|
||||||
babelHelpers.get(Object.getPrototypeOf(ConfirmPasswordModal.prototype), 'onerror', this).call(this, error);
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
key: 'onhide',
|
|
||||||
value: function onhide() {
|
|
||||||
if (this.success) return;
|
|
||||||
|
|
||||||
this.props.deferred.reject(this.props.error);
|
|
||||||
}
|
|
||||||
}]);
|
|
||||||
return ConfirmPasswordModal;
|
|
||||||
})(Modal);
|
|
||||||
|
|
||||||
_export('default', ConfirmPasswordModal);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});;
|
|
||||||
System.register('flarum/components/DiscussionComposer', ['flarum/components/ComposerBody', 'flarum/utils/extractText'], function (_export) {
|
System.register('flarum/components/DiscussionComposer', ['flarum/components/ComposerBody', 'flarum/utils/extractText'], function (_export) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31111,10 +31008,13 @@ System.register('flarum/Model', [], function (_export) {
|
||||||
|
|
||||||
this.pushData(data);
|
this.pushData(data);
|
||||||
|
|
||||||
|
var request = { data: data };
|
||||||
|
if (options.meta) request.meta = options.meta;
|
||||||
|
|
||||||
return app.request(babelHelpers._extends({
|
return app.request(babelHelpers._extends({
|
||||||
method: this.exists ? 'PATCH' : 'POST',
|
method: this.exists ? 'PATCH' : 'POST',
|
||||||
url: app.forum.attribute('apiUrl') + this.apiEndpoint(),
|
url: app.forum.attribute('apiUrl') + this.apiEndpoint(),
|
||||||
data: { data: data }
|
data: request
|
||||||
}, options)).then(
|
}, options)).then(
|
||||||
// If everything went well, we'll make sure the store knows that this
|
// If everything went well, we'll make sure the store knows that this
|
||||||
// model exists now (if it didn't already), and we'll push the data that
|
// model exists now (if it didn't already), and we'll push the data that
|
||||||
|
|
|
@ -22,6 +22,13 @@ export default class ChangeEmailModal extends Modal {
|
||||||
* @type {function}
|
* @type {function}
|
||||||
*/
|
*/
|
||||||
this.email = m.prop(app.session.user.email());
|
this.email = m.prop(app.session.user.email());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value of the password input.
|
||||||
|
*
|
||||||
|
* @type {function}
|
||||||
|
*/
|
||||||
|
this.password = m.prop('');
|
||||||
}
|
}
|
||||||
|
|
||||||
className() {
|
className() {
|
||||||
|
@ -54,8 +61,13 @@ export default class ChangeEmailModal extends Modal {
|
||||||
<div className="Form-group">
|
<div className="Form-group">
|
||||||
<input type="email" name="email" className="FormControl"
|
<input type="email" name="email" className="FormControl"
|
||||||
placeholder={app.session.user.email()}
|
placeholder={app.session.user.email()}
|
||||||
value={this.email()}
|
bidi={this.email}
|
||||||
onchange={m.withAttr('value', this.email)}
|
disabled={this.loading}/>
|
||||||
|
</div>
|
||||||
|
<div className="Form-group">
|
||||||
|
<input type="password" name="password" className="FormControl"
|
||||||
|
placeholder={app.translator.trans('core.forum.change_email.confirm_password_label')}
|
||||||
|
bidi={this.password}
|
||||||
disabled={this.loading}/>
|
disabled={this.loading}/>
|
||||||
</div>
|
</div>
|
||||||
<div className="Form-group">
|
<div className="Form-group">
|
||||||
|
@ -85,14 +97,20 @@ export default class ChangeEmailModal extends Modal {
|
||||||
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
|
|
||||||
app.session.user.save({email: this.email()}, {errorHandler: this.onerror.bind(this)})
|
app.session.user.save({email: this.email()}, {
|
||||||
|
errorHandler: this.onerror.bind(this),
|
||||||
|
meta: {password: this.password()}
|
||||||
|
})
|
||||||
.then(() => this.success = true)
|
.then(() => this.success = true)
|
||||||
.catch(() => {})
|
.catch(() => {})
|
||||||
.then(this.loaded.bind(this));
|
.then(this.loaded.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
// The save method will update the cached email address on the user model...
|
onerror(error) {
|
||||||
// But in the case of a "sudo" password prompt, we'll still want to have
|
if (error.status === 401) {
|
||||||
// the old email address on file for the purposes of logging in.
|
error.alert.props.children = app.translator.trans('core.forum.change_email.incorrect_password_message');
|
||||||
app.session.user.pushAttributes({email: oldEmail});
|
}
|
||||||
|
|
||||||
|
super.onerror(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -252,15 +252,6 @@ export default class App {
|
||||||
m.request(options).then(response => deferred.resolve(response), error => {
|
m.request(options).then(response => deferred.resolve(response), error => {
|
||||||
this.requestError = error;
|
this.requestError = error;
|
||||||
|
|
||||||
if (error.response && error.response.errors && error.response.errors[0] && error.response.errors[0].code === 'invalid_access_token') {
|
|
||||||
this.modal.show(new ConfirmPasswordModal({
|
|
||||||
deferredRequest: originalOptions,
|
|
||||||
deferred,
|
|
||||||
error
|
|
||||||
}));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let children;
|
let children;
|
||||||
|
|
||||||
switch (error.status) {
|
switch (error.status) {
|
||||||
|
|
|
@ -154,10 +154,13 @@ export default class Model {
|
||||||
|
|
||||||
this.pushData(data);
|
this.pushData(data);
|
||||||
|
|
||||||
|
const request = {data};
|
||||||
|
if (options.meta) request.meta = options.meta;
|
||||||
|
|
||||||
return app.request(Object.assign({
|
return app.request(Object.assign({
|
||||||
method: this.exists ? 'PATCH' : 'POST',
|
method: this.exists ? 'PATCH' : 'POST',
|
||||||
url: app.forum.attribute('apiUrl') + this.apiEndpoint(),
|
url: app.forum.attribute('apiUrl') + this.apiEndpoint(),
|
||||||
data: {data}
|
data: request
|
||||||
}, options)).then(
|
}, options)).then(
|
||||||
// If everything went well, we'll make sure the store knows that this
|
// If everything went well, we'll make sure the store knows that this
|
||||||
// model exists now (if it didn't already), and we'll push the data that
|
// model exists now (if it didn't already), and we'll push the data that
|
||||||
|
|
|
@ -1,73 +0,0 @@
|
||||||
import Modal from 'flarum/components/Modal';
|
|
||||||
import Button from 'flarum/components/Button';
|
|
||||||
import extractText from 'flarum/utils/extractText';
|
|
||||||
|
|
||||||
export default class ConfirmPasswordModal extends Modal {
|
|
||||||
init() {
|
|
||||||
super.init();
|
|
||||||
|
|
||||||
this.password = m.prop('');
|
|
||||||
}
|
|
||||||
|
|
||||||
className() {
|
|
||||||
return 'ConfirmPasswordModal Modal--small';
|
|
||||||
}
|
|
||||||
|
|
||||||
title() {
|
|
||||||
return app.translator.trans('core.forum.confirm_password.title');
|
|
||||||
}
|
|
||||||
|
|
||||||
content() {
|
|
||||||
return (
|
|
||||||
<div className="Modal-body">
|
|
||||||
<div className="Form Form--centered">
|
|
||||||
<div className="Form-group">
|
|
||||||
<input
|
|
||||||
type="password"
|
|
||||||
className="FormControl"
|
|
||||||
bidi={this.password}
|
|
||||||
placeholder={extractText(app.translator.trans('core.forum.confirm_password.password_placeholder'))}
|
|
||||||
disabled={this.loading}/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="Form-group">
|
|
||||||
<Button
|
|
||||||
type="submit"
|
|
||||||
className="Button Button--primary Button--block"
|
|
||||||
loading={this.loading}>
|
|
||||||
{app.translator.trans('core.forum.confirm_password.submit_button')}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
onsubmit(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
this.loading = true;
|
|
||||||
|
|
||||||
app.session.login(app.session.user.email(), this.password(), {errorHandler: this.onerror.bind(this)})
|
|
||||||
.then(() => {
|
|
||||||
this.success = true;
|
|
||||||
this.hide();
|
|
||||||
app.request(this.props.deferredRequest).then(response => this.props.deferred.resolve(response), response => this.props.deferred.reject(response));
|
|
||||||
})
|
|
||||||
.catch(this.loaded.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
onerror(error) {
|
|
||||||
if (error.status === 401) {
|
|
||||||
error.alert.props.children = app.translator.trans('core.forum.log_in.invalid_login_message');
|
|
||||||
}
|
|
||||||
|
|
||||||
super.onerror(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
onhide() {
|
|
||||||
if (this.success) return;
|
|
||||||
|
|
||||||
this.props.deferred.reject(this.props.error);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,63 +10,21 @@
|
||||||
|
|
||||||
namespace Flarum\Admin\Middleware;
|
namespace Flarum\Admin\Middleware;
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use Flarum\Core\Access\AssertPermissionTrait;
|
use Flarum\Core\Access\AssertPermissionTrait;
|
||||||
use Flarum\Forum\Controller\LogInController;
|
|
||||||
use Illuminate\Contracts\View\Factory;
|
|
||||||
use Psr\Http\Message\ResponseInterface as Response;
|
use Psr\Http\Message\ResponseInterface as Response;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
use Zend\Diactoros\Response\HtmlResponse;
|
|
||||||
use Zend\Stratigility\MiddlewareInterface;
|
use Zend\Stratigility\MiddlewareInterface;
|
||||||
|
|
||||||
class RequireAdministrateAbility implements MiddlewareInterface
|
class RequireAdministrateAbility implements MiddlewareInterface
|
||||||
{
|
{
|
||||||
use AssertPermissionTrait;
|
use AssertPermissionTrait;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var LogInController
|
|
||||||
*/
|
|
||||||
private $logInController;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Factory
|
|
||||||
*/
|
|
||||||
private $view;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param LogInController $logInController
|
|
||||||
* @param Factory $view
|
|
||||||
*/
|
|
||||||
public function __construct(LogInController $logInController, Factory $view)
|
|
||||||
{
|
|
||||||
$this->logInController = $logInController;
|
|
||||||
$this->view = $view;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function __invoke(Request $request, Response $response, callable $out = null)
|
public function __invoke(Request $request, Response $response, callable $out = null)
|
||||||
{
|
{
|
||||||
try {
|
$this->assertAdmin($request->getAttribute('actor'));
|
||||||
$this->assertAdminAndSudo($request);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
if ($request->getMethod() === 'POST') {
|
|
||||||
$response = $this->logInController->handle($request);
|
|
||||||
|
|
||||||
if ($response->getStatusCode() === 200) {
|
|
||||||
return $response
|
|
||||||
->withStatus(302)
|
|
||||||
->withHeader('location', app('Flarum\Admin\UrlGenerator')->toRoute('index'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new HtmlResponse(
|
|
||||||
$this->view->make('flarum.admin::login')
|
|
||||||
->with('token', $request->getAttribute('session')->get('csrf_token'))
|
|
||||||
->render()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $out ? $out($request, $response) : $response;
|
return $out ? $out($request, $response) : $response;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,15 +10,12 @@
|
||||||
|
|
||||||
namespace Flarum\Api\Controller;
|
namespace Flarum\Api\Controller;
|
||||||
|
|
||||||
use Flarum\Core\Access\AssertPermissionTrait;
|
|
||||||
use Flarum\Core\Command\DeleteDiscussion;
|
use Flarum\Core\Command\DeleteDiscussion;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
|
||||||
class DeleteDiscussionController extends AbstractDeleteController
|
class DeleteDiscussionController extends AbstractDeleteController
|
||||||
{
|
{
|
||||||
use AssertPermissionTrait;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Dispatcher
|
* @var Dispatcher
|
||||||
*/
|
*/
|
||||||
|
@ -41,8 +38,6 @@ class DeleteDiscussionController extends AbstractDeleteController
|
||||||
$actor = $request->getAttribute('actor');
|
$actor = $request->getAttribute('actor');
|
||||||
$input = $request->getParsedBody();
|
$input = $request->getParsedBody();
|
||||||
|
|
||||||
$this->assertSudo($request);
|
|
||||||
|
|
||||||
$this->bus->dispatch(
|
$this->bus->dispatch(
|
||||||
new DeleteDiscussion($id, $actor, $input)
|
new DeleteDiscussion($id, $actor, $input)
|
||||||
);
|
);
|
||||||
|
|
|
@ -10,15 +10,12 @@
|
||||||
|
|
||||||
namespace Flarum\Api\Controller;
|
namespace Flarum\Api\Controller;
|
||||||
|
|
||||||
use Flarum\Core\Access\AssertPermissionTrait;
|
|
||||||
use Flarum\Core\Command\DeleteGroup;
|
use Flarum\Core\Command\DeleteGroup;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
|
||||||
class DeleteGroupController extends AbstractDeleteController
|
class DeleteGroupController extends AbstractDeleteController
|
||||||
{
|
{
|
||||||
use AssertPermissionTrait;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Dispatcher
|
* @var Dispatcher
|
||||||
*/
|
*/
|
||||||
|
@ -37,8 +34,6 @@ class DeleteGroupController extends AbstractDeleteController
|
||||||
*/
|
*/
|
||||||
protected function delete(ServerRequestInterface $request)
|
protected function delete(ServerRequestInterface $request)
|
||||||
{
|
{
|
||||||
$this->assertSudo($request);
|
|
||||||
|
|
||||||
$this->bus->dispatch(
|
$this->bus->dispatch(
|
||||||
new DeleteGroup(array_get($request->getQueryParams(), 'id'), $request->getAttribute('actor'))
|
new DeleteGroup(array_get($request->getQueryParams(), 'id'), $request->getAttribute('actor'))
|
||||||
);
|
);
|
||||||
|
|
|
@ -10,15 +10,12 @@
|
||||||
|
|
||||||
namespace Flarum\Api\Controller;
|
namespace Flarum\Api\Controller;
|
||||||
|
|
||||||
use Flarum\Core\Access\AssertPermissionTrait;
|
|
||||||
use Flarum\Core\Command\DeletePost;
|
use Flarum\Core\Command\DeletePost;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
|
||||||
class DeletePostController extends AbstractDeleteController
|
class DeletePostController extends AbstractDeleteController
|
||||||
{
|
{
|
||||||
use AssertPermissionTrait;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Dispatcher
|
* @var Dispatcher
|
||||||
*/
|
*/
|
||||||
|
@ -37,8 +34,6 @@ class DeletePostController extends AbstractDeleteController
|
||||||
*/
|
*/
|
||||||
protected function delete(ServerRequestInterface $request)
|
protected function delete(ServerRequestInterface $request)
|
||||||
{
|
{
|
||||||
$this->assertSudo($request);
|
|
||||||
|
|
||||||
$this->bus->dispatch(
|
$this->bus->dispatch(
|
||||||
new DeletePost(array_get($request->getQueryParams(), 'id'), $request->getAttribute('actor'))
|
new DeletePost(array_get($request->getQueryParams(), 'id'), $request->getAttribute('actor'))
|
||||||
);
|
);
|
||||||
|
|
|
@ -10,15 +10,12 @@
|
||||||
|
|
||||||
namespace Flarum\Api\Controller;
|
namespace Flarum\Api\Controller;
|
||||||
|
|
||||||
use Flarum\Core\Access\AssertPermissionTrait;
|
|
||||||
use Flarum\Core\Command\DeleteUser;
|
use Flarum\Core\Command\DeleteUser;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
|
||||||
class DeleteUserController extends AbstractDeleteController
|
class DeleteUserController extends AbstractDeleteController
|
||||||
{
|
{
|
||||||
use AssertPermissionTrait;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Dispatcher
|
* @var Dispatcher
|
||||||
*/
|
*/
|
||||||
|
@ -37,8 +34,6 @@ class DeleteUserController extends AbstractDeleteController
|
||||||
*/
|
*/
|
||||||
protected function delete(ServerRequestInterface $request)
|
protected function delete(ServerRequestInterface $request)
|
||||||
{
|
{
|
||||||
$this->assertSudo($request);
|
|
||||||
|
|
||||||
$this->bus->dispatch(
|
$this->bus->dispatch(
|
||||||
new DeleteUser(array_get($request->getQueryParams(), 'id'), $request->getAttribute('actor'))
|
new DeleteUser(array_get($request->getQueryParams(), 'id'), $request->getAttribute('actor'))
|
||||||
);
|
);
|
||||||
|
|
|
@ -25,7 +25,7 @@ class SetPermissionController implements ControllerInterface
|
||||||
*/
|
*/
|
||||||
public function handle(ServerRequestInterface $request)
|
public function handle(ServerRequestInterface $request)
|
||||||
{
|
{
|
||||||
$this->assertAdminAndSudo($request);
|
$this->assertAdmin($request->getAttribute('actor'));
|
||||||
|
|
||||||
$body = $request->getParsedBody();
|
$body = $request->getParsedBody();
|
||||||
$permission = array_get($body, 'permission');
|
$permission = array_get($body, 'permission');
|
||||||
|
|
|
@ -47,7 +47,7 @@ class SetSettingsController implements ControllerInterface
|
||||||
*/
|
*/
|
||||||
public function handle(ServerRequestInterface $request)
|
public function handle(ServerRequestInterface $request)
|
||||||
{
|
{
|
||||||
$this->assertAdminAndSudo($request);
|
$this->assertAdmin($request->getAttribute('actor'));
|
||||||
|
|
||||||
$settings = $request->getParsedBody();
|
$settings = $request->getParsedBody();
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ class UninstallExtensionController extends AbstractDeleteController
|
||||||
|
|
||||||
protected function delete(ServerRequestInterface $request)
|
protected function delete(ServerRequestInterface $request)
|
||||||
{
|
{
|
||||||
$this->assertAdminAndSudo($request);
|
$this->assertAdmin($request->getAttribute('actor'));
|
||||||
|
|
||||||
$name = array_get($request->getQueryParams(), 'name');
|
$name = array_get($request->getQueryParams(), 'name');
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ class UpdateExtensionController implements ControllerInterface
|
||||||
*/
|
*/
|
||||||
public function handle(ServerRequestInterface $request)
|
public function handle(ServerRequestInterface $request)
|
||||||
{
|
{
|
||||||
$this->assertAdminAndSudo($request);
|
$this->assertAdmin($request->getAttribute('actor'));
|
||||||
|
|
||||||
$enabled = array_get($request->getParsedBody(), 'enabled');
|
$enabled = array_get($request->getParsedBody(), 'enabled');
|
||||||
$name = array_get($request->getQueryParams(), 'name');
|
$name = array_get($request->getQueryParams(), 'name');
|
||||||
|
|
|
@ -10,16 +10,14 @@
|
||||||
|
|
||||||
namespace Flarum\Api\Controller;
|
namespace Flarum\Api\Controller;
|
||||||
|
|
||||||
use Flarum\Core\Access\AssertPermissionTrait;
|
|
||||||
use Flarum\Core\Command\EditUser;
|
use Flarum\Core\Command\EditUser;
|
||||||
|
use Flarum\Core\Exception\PermissionDeniedException;
|
||||||
use Illuminate\Contracts\Bus\Dispatcher;
|
use Illuminate\Contracts\Bus\Dispatcher;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Tobscure\JsonApi\Document;
|
use Tobscure\JsonApi\Document;
|
||||||
|
|
||||||
class UpdateUserController extends AbstractResourceController
|
class UpdateUserController extends AbstractResourceController
|
||||||
{
|
{
|
||||||
use AssertPermissionTrait;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
@ -52,7 +50,15 @@ class UpdateUserController extends AbstractResourceController
|
||||||
$actor = $request->getAttribute('actor');
|
$actor = $request->getAttribute('actor');
|
||||||
$data = array_get($request->getParsedBody(), 'data', []);
|
$data = array_get($request->getParsedBody(), 'data', []);
|
||||||
|
|
||||||
$this->assertSudo($request);
|
// Require the user's current password if they are attempting to change
|
||||||
|
// their own email address.
|
||||||
|
if (isset($data['attributes']['email']) && $actor->id == $id) {
|
||||||
|
$password = array_get($request->getParsedBody(), 'meta.password');
|
||||||
|
|
||||||
|
if (! $actor->checkPassword($password)) {
|
||||||
|
throw new PermissionDeniedException;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $this->bus->dispatch(
|
return $this->bus->dispatch(
|
||||||
new EditUser($id, $actor, $data)
|
new EditUser($id, $actor, $data)
|
||||||
|
|
|
@ -10,11 +10,9 @@
|
||||||
|
|
||||||
namespace Flarum\Core\Access;
|
namespace Flarum\Core\Access;
|
||||||
|
|
||||||
use DateTime;
|
|
||||||
use Flarum\Api\Exception\InvalidAccessTokenException;
|
use Flarum\Api\Exception\InvalidAccessTokenException;
|
||||||
use Flarum\Core\Exception\PermissionDeniedException;
|
use Flarum\Core\Exception\PermissionDeniedException;
|
||||||
use Flarum\Core\User;
|
use Flarum\Core\User;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
|
||||||
|
|
||||||
trait AssertPermissionTrait
|
trait AssertPermissionTrait
|
||||||
{
|
{
|
||||||
|
@ -66,28 +64,4 @@ trait AssertPermissionTrait
|
||||||
{
|
{
|
||||||
$this->assertCan($actor, 'administrate');
|
$this->assertCan($actor, 'administrate');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ServerRequestInterface $request
|
|
||||||
* @throws InvalidAccessTokenException
|
|
||||||
*/
|
|
||||||
protected function assertSudo(ServerRequestInterface $request)
|
|
||||||
{
|
|
||||||
$session = $request->getAttribute('session');
|
|
||||||
|
|
||||||
if ($session && $session->get('sudo_expiry') < new DateTime) {
|
|
||||||
throw new InvalidAccessTokenException;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ServerRequestInterface $request
|
|
||||||
* @throws PermissionDeniedException
|
|
||||||
*/
|
|
||||||
protected function assertAdminAndSudo(ServerRequestInterface $request)
|
|
||||||
{
|
|
||||||
$this->assertAdmin($request->getAttribute('actor'));
|
|
||||||
|
|
||||||
$this->assertSudo($request);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ class SessionAuthenticator
|
||||||
{
|
{
|
||||||
$session->migrate();
|
$session->migrate();
|
||||||
$session->set('user_id', $userId);
|
$session->set('user_id', $userId);
|
||||||
$session->set('sudo_expiry', new DateTime('+30 minutes'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<title>Log In</title>
|
|
||||||
<meta name="description" content="">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<h1>Log In</h1>
|
|
||||||
|
|
||||||
<form class="form-horizontal" role="form" method="POST" action="{{ app('Flarum\Admin\UrlGenerator')->toRoute('index') }}">
|
|
||||||
<input type="hidden" name="token" value="{{ $token }}">
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="control-label">Username or Email</label>
|
|
||||||
<input type="text" class="form-control" name="identification">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="control-label">Password</label>
|
|
||||||
<input type="password" class="form-control" name="password">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<button type="submit" class="btn btn-primary">Log In</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Loading…
Reference in New Issue
Block a user