Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions extensions/gdpr/js/src/forum/extenders/extendUserSettingsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,18 @@ export default function extendUserSettingsPage() {
override('flarum/forum/components/SettingsPage', 'dataItems', function (): ItemList<Mithril.Children> {
const items = new ItemList<Mithril.Children>();

items.add(
'gdprErasure',
<div className="Form-group gdprErasure-container">
<p className="helpText">{app.translator.trans('flarum-gdpr.forum.settings.request_erasure_help')}</p>
<Button className="Button Button-gdprErasure" icon="fas fa-user-minus" onclick={() => app.modal.show(RequestErasureModal as any)}>
{app.translator.trans('flarum-gdpr.forum.settings.request_erasure_button')}
</Button>
</div>,
50
);
if (this.user === app.session.user) {
items.add(
'gdprErasure',
<div className="Form-group gdprErasure-container">
<p className="helpText">{app.translator.trans('flarum-gdpr.forum.settings.request_erasure_help')}</p>
<Button className="Button Button-gdprErasure" icon="fas fa-user-minus" onclick={() => app.modal.show(RequestErasureModal as any)}>
{app.translator.trans('flarum-gdpr.forum.settings.request_erasure_button')}
</Button>
</div>,
50
);
}

items.add(
'gdprExport',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
import app from 'flarum/forum/app';
import FormModal from 'flarum/common/components/FormModal';
import FormModal, { IFormModalAttrs } from 'flarum/common/components/FormModal';
import Button from 'flarum/common/components/Button';
import Stream from 'flarum/common/utils/Stream';
import Form from 'flarum/common/components/Form';

export default class NicknameModal extends FormModal {
oninit(vnode) {
import type Mithril from 'mithril';
import type User from 'flarum/common/models/User';

export interface IChangeNicknameModalAttrs extends IFormModalAttrs {
user: User;
}

export default class ChangeNicknameModal<CustomAttrs extends IChangeNicknameModalAttrs = IChangeNicknameModalAttrs> extends FormModal<CustomAttrs> {
nickname!: Stream<string>;

oninit(vnode: Mithril.Vnode<CustomAttrs, this>) {
super.oninit(vnode);
this.nickname = Stream(app.session.user.displayName());
this.nickname = Stream(this.attrs.user.displayName());
}

className() {
return 'NickameModal Modal--small';
return 'ChangeNicknameModal Modal--small';
}

title() {
Expand All @@ -35,17 +44,17 @@ export default class NicknameModal extends FormModal {
);
}

onsubmit(e) {
onsubmit(e: Event) {
e.preventDefault();

if (this.nickname() === app.session.user.displayName()) {
if (this.nickname() === this.attrs.user.displayName()) {
this.hide();
return;
}

this.loading = true;

app.session.user
this.attrs.user
.save(
{ nickname: this.nickname() },
{
Expand Down
4 changes: 2 additions & 2 deletions extensions/nicknames/js/src/forum/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { extend } from 'flarum/common/extend';
import Button from 'flarum/common/components/Button';
import extractText from 'flarum/common/utils/extractText';
import Stream from 'flarum/common/utils/Stream';
import NickNameModal from './components/NicknameModal';
import ChangeNicknameModal from './components/ChangeNicknameModal';

export { default as extend } from './extend';

Expand All @@ -14,7 +14,7 @@ app.initializers.add('flarum-nicknames', () => {
if (this.user.canEditNickname()) {
items.add(
'changeNickname',
<Button className="Button" onclick={() => app.modal.show(NickNameModal)}>
<Button className="Button" onclick={() => app.modal.show(ChangeNicknameModal, { user: this.user })}>
{app.translator.trans('flarum-nicknames.forum.settings.change_nickname_button')}
</Button>
);
Expand Down
62 changes: 33 additions & 29 deletions framework/core/js/src/forum/components/ChangeEmailModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@ import RequestError from '../../common/utils/RequestError';
import ItemList from '../../common/utils/ItemList';
import Form from '../../common/components/Form';

import type User from '../../common/models/User';

export interface IChangeEmailModalAttrs extends IFormModalAttrs {
user: User;
}
/**
* The `ChangeEmailModal` component shows a modal dialog which allows the user
* to change their email address.
*/
export default class ChangeEmailModal<CustomAttrs extends IFormModalAttrs = IFormModalAttrs> extends FormModal<CustomAttrs> {
export default class ChangeEmailModal<CustomAttrs extends IChangeEmailModalAttrs = IChangeEmailModalAttrs> extends FormModal<CustomAttrs> {
/**
* The value of the email input.
*/
Expand All @@ -30,7 +35,7 @@ export default class ChangeEmailModal<CustomAttrs extends IFormModalAttrs = IFor
oninit(vnode: Mithril.Vnode<CustomAttrs, this>) {
super.oninit(vnode);

this.email = Stream(app.session.user!.email() || '');
this.email = Stream(this.attrs.user.email() || '');
this.password = Stream('');
}

Expand Down Expand Up @@ -75,31 +80,26 @@ export default class ChangeEmailModal<CustomAttrs extends IFormModalAttrs = IFor
items.add(
'email',
<div className="Form-group">
<input
type="email"
name="email"
className="FormControl"
placeholder={app.session.user!.email()}
bidi={this.email}
disabled={this.loading}
/>
<input type="email" name="email" className="FormControl" placeholder={this.attrs.user.email()} bidi={this.email} disabled={this.loading} />
</div>
);

items.add(
'password',
<div className="Form-group">
<input
type="password"
name="password"
className="FormControl"
autocomplete="current-password"
placeholder={app.translator.trans('core.forum.change_email.confirm_password_placeholder')}
bidi={this.password}
disabled={this.loading}
/>
</div>
);
if (!app.session.user?.isAdmin()) {
items.add(
'password',
<div className="Form-group">
<input
type="password"
name="password"
className="FormControl"
autocomplete="current-password"
placeholder={app.translator.trans('core.forum.change_email.confirm_password_placeholder')}
bidi={this.password}
disabled={this.loading}
/>
</div>
);
}

items.add(
'submit',
Expand All @@ -119,21 +119,25 @@ export default class ChangeEmailModal<CustomAttrs extends IFormModalAttrs = IFor

// If the user hasn't actually entered a different email address, we don't
// need to do anything. Woot!
if (this.email() === app.session.user!.email()) {
if (this.email() === this.attrs.user.email()) {
this.hide();
return;
}

this.loading = true;
this.alertAttrs = null;

app.session
.user!.save(this.requestAttributes(), {
this.attrs.user
.save(this.requestAttributes(), {
errorHandler: this.onerror.bind(this),
meta: { password: this.password() },
...(!app.session.user?.isAdmin() ? { meta: { password: this.password() } } : {}),
})
.then(() => {
this.success = true;
if (!app.session.user?.isAdmin()) {
this.success = true;
} else {
this.hide();
}
})
.catch(() => {})
.then(this.loaded.bind(this));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
import app from '../../forum/app';
import app from '../app';
import FormModal, { IFormModalAttrs } from '../../common/components/FormModal';
import Button from '../../common/components/Button';
import Mithril from 'mithril';
import ItemList from '../../common/utils/ItemList';
import Form from '../../common/components/Form';

import type User from '../../common/models/User';

export interface IRequestPasswordResetModalAttrs extends IFormModalAttrs {
user: User;
}

/**
* The `ChangePasswordModal` component shows a modal dialog which allows the
* The `RequestPasswordResetModal` component shows a modal dialog which allows the
* user to send themself a password reset email.
*/
export default class ChangePasswordModal<CustomAttrs extends IFormModalAttrs = IFormModalAttrs> extends FormModal<CustomAttrs> {
export default class RequestPasswordResetModal<
CustomAttrs extends IRequestPasswordResetModalAttrs = IRequestPasswordResetModalAttrs
> extends FormModal<CustomAttrs> {
className() {
return 'ChangePasswordModal Modal--small';
return 'RequestPasswordResetModal Modal--small';
}

title() {
return app.translator.trans('core.forum.change_password.title');
return app.translator.trans('core.forum.request_password_reset.title');
}

content() {
Expand All @@ -29,13 +37,13 @@ export default class ChangePasswordModal<CustomAttrs extends IFormModalAttrs = I
fields() {
const fields = new ItemList<Mithril.Children>();

fields.add('help', <p className="helpText">{app.translator.trans('core.forum.change_password.text')}</p>);
fields.add('help', <p className="helpText">{app.translator.trans('core.forum.request_password_reset.text')}</p>);

fields.add(
'submit',
<div className="Form-group Form-controls">
<Button className="Button Button--primary Button--block" type="submit" loading={this.loading}>
{app.translator.trans('core.forum.change_password.send_button')}
{app.translator.trans('core.forum.request_password_reset.send_button')}
</Button>
</div>
);
Expand All @@ -58,6 +66,6 @@ export default class ChangePasswordModal<CustomAttrs extends IFormModalAttrs = I
}

requestBody() {
return { email: app.session.user!.email() };
return { email: this.attrs.user.email() };
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export default class SessionDropdown<CustomAttrs extends ISessionDropdownAttrs =

items.add(
'settings',
<LinkButton icon="fas fa-cog" href={app.route('settings')}>
<LinkButton icon="fas fa-cog" href={app.route('user.settings', { username: user.slug() })}>
{app.translator.trans('core.forum.header.settings_button')}
</LinkButton>,
50
Expand Down
24 changes: 17 additions & 7 deletions framework/core/js/src/forum/components/SettingsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Switch from '../../common/components/Switch';
import Button from '../../common/components/Button';
import FieldSet from '../../common/components/FieldSet';
import NotificationGrid from './NotificationGrid';
import ChangePasswordModal from './ChangePasswordModal';
import RequestPasswordResetModal from './RequestPasswordResetModal';
import ChangeEmailModal from './ChangeEmailModal';
import listItems from '../../common/helpers/listItems';
import extractText from '../../common/utils/extractText';
Expand All @@ -27,7 +27,13 @@ export default class SettingsPage<CustomAttrs extends IUserPageAttrs = IUserPage
oninit(vnode: Mithril.Vnode<CustomAttrs, this>) {
super.oninit(vnode);

this.show(app.session.user!);
const routeUsername = m.route.param('username');

if (routeUsername !== app.session.user?.slug() && !app.session.user?.isAdmin()) {
m.route.set('/');
}

this.loadUser(routeUsername);

app.setTitle(extractText(app.translator.trans('core.forum.settings.title')));
}
Expand Down Expand Up @@ -86,16 +92,16 @@ export default class SettingsPage<CustomAttrs extends IUserPageAttrs = IUserPage
const items = new ItemList<Mithril.Children>();

items.add(
'changePassword',
<Button className="Button" onclick={() => app.modal.show(ChangePasswordModal)}>
{app.translator.trans('core.forum.settings.change_password_button')}
'requestPasswordReset',
<Button className="Button" onclick={() => app.modal.show(RequestPasswordResetModal, { user: this.user })}>
{app.translator.trans('core.forum.settings.request_password_reset_button')}
</Button>,
100
);

items.add(
'changeEmail',
<Button className="Button" onclick={() => app.modal.show(ChangeEmailModal)}>
<Button className="Button" onclick={() => app.modal.show(ChangeEmailModal, { user: this.user })}>
{app.translator.trans('core.forum.settings.change_email_button')}
</Button>,
90
Expand Down Expand Up @@ -191,7 +197,11 @@ export default class SettingsPage<CustomAttrs extends IUserPageAttrs = IUserPage

this.user!.savePreferences({ colorScheme: mode.id }).then(() => {
this.colorSchemeLoading = false;
app.setColorScheme(mode.id);

if (this.user === app.session.user) {
app.setColorScheme(mode.id);
}

m.redraw();
});
}}
Expand Down
4 changes: 2 additions & 2 deletions framework/core/js/src/forum/components/UserPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,11 @@ export default class UserPage<CustomAttrs extends IUserPageAttrs = IUserPageAttr
90
);

if (isActor) {
if (isActor || app.session.user?.isAdmin()) {
items.add('separator', <Separator />, -90);
items.add(
'settings',
<LinkButton href={app.route('settings')} icon="fas fa-cog">
<LinkButton href={app.route('user.settings', { username: user.slug() })} icon="fas fa-cog">
{app.translator.trans('core.forum.user.settings_link')}
</LinkButton>,
-100
Expand Down
4 changes: 2 additions & 2 deletions framework/core/js/src/forum/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ export default function (app: ForumApplication) {
component: () => import('./components/DiscussionsUserPage'),
resolverClass: UserPageResolver,
},

settings: { path: '/settings', component: () => import('./components/SettingsPage') },
'user.settings': { path: '/u/:username/settings', component: () => import('./components/SettingsPage'), resolverClass: UserPageResolver },
'user.security': { path: '/u/:username/security', component: () => import('./components/UserSecurityPage'), resolverClass: UserPageResolver },

notifications: { path: '/notifications', component: () => import('./components/NotificationsPage') },
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { app } from '../../../../src/forum';
import ModalManager from '../../../../src/common/components/ModalManager';
import GlobalDiscussionsSearchSource from '../../../../src/forum/components/GlobalDiscussionsSearchSource';
import ChangeEmailModal from '../../../../src/forum/components/ChangeEmailModal';
import ChangePasswordModal from '../../../../src/forum/components/ChangePasswordModal';
import RequestPasswordResetModal from '../../../../src/forum/components/RequestPasswordResetModal';
import ForgotPasswordModal from '../../../../src/forum/components/ForgotPasswordModal';
import LogInModal from '../../../../src/forum/components/LogInModal';
import NewAccessTokenModal from '../../../../src/forum/components/NewAccessTokenModal';
Expand All @@ -21,18 +21,18 @@ describe('Modals', () => {
test('ChangeEmailModal renders', () => {
const manager = mq(ModalManager, { state: app.modal });

app.modal.show(ChangeEmailModal);
app.modal.show(ChangeEmailModal, { user: app.session.user! });

manager.redraw();

expect(app.modal.modalList.length).toEqual(1);
expect(manager).toHaveElement('.ModalManager');
});

test('ChangePasswordModal renders', () => {
test('RequestPasswordResetModal renders', () => {
const manager = mq(ModalManager, { state: app.modal });

app.modal.show(ChangePasswordModal);
app.modal.show(RequestPasswordResetModal, { user: app.session.user! });

manager.redraw();

Expand Down
Loading
Loading