diff --git a/extensions/nicknames/composer.json b/extensions/nicknames/composer.json index 70568c433..b073c82e8 100644 --- a/extensions/nicknames/composer.json +++ b/extensions/nicknames/composer.json @@ -22,6 +22,7 @@ }, "flarum-extension": { "title": "Nicknames", + "category": "feature", "icon": { "name": "fas fa-user-tag", "backgroundColor": "#8E4529", diff --git a/extensions/nicknames/extend.php b/extensions/nicknames/extend.php index 228cbe491..a2b39b107 100644 --- a/extensions/nicknames/extend.php +++ b/extensions/nicknames/extend.php @@ -11,19 +11,19 @@ namespace Flarum\Nicknames; +use Flarum\Api\Serializer\UserSerializer; use Flarum\Event\ConfigureUserGambits; use Flarum\Extend; use Flarum\User\Event\Saving; use Flarum\User\User; +use Flarum\User\UserValidator; return [ (new Extend\Frontend('forum')) - ->js(__DIR__.'/js/dist/forum.js') - ->css(__DIR__.'/resources/less/forum.less'), + ->js(__DIR__.'/js/dist/forum.js'), (new Extend\Frontend('admin')) - ->js(__DIR__.'/js/dist/admin.js') - ->css(__DIR__.'/resources/less/admin.less'), + ->js(__DIR__.'/js/dist/admin.js'), (new Extend\User()) ->displayNameDriver('nickname', NicknameDriver::class), @@ -35,5 +35,13 @@ return [ ->listen(Saving::class, SaveNicknameToDatabase::class) ->listen(ConfigureUserGambits::class, SetUserNicknameGambit::class), - new Extend\Locales(__DIR__ . '/resources/locale'), + (new Extend\ApiSerializer(UserSerializer::class)) + ->attribute('canEditOwnNickname', function($serializer, $user) { + $actor = $serializer->getActor(); + return $actor->id === $user->id && $serializer->getActor()->can('editOwnNickname', $user); + }), + + (new Extend\Validator(UserValidator::class)) + ->configure(AddNicknameValidation::class), + ]; diff --git a/extensions/nicknames/js/src/admin/index.js b/extensions/nicknames/js/src/admin/index.js index 6664fb2dc..a119a765e 100644 --- a/extensions/nicknames/js/src/admin/index.js +++ b/extensions/nicknames/js/src/admin/index.js @@ -1,3 +1,29 @@ -app.initializers.add('flarum/nickname', () => { - console.log('[flarum/nickname] Hello, admin!'); -}); +app.initializers.add('flarum/nicknames', () => { + app.extensionData + .for('flarum-nicknames') + .registerSetting({ + setting: 'flarum-nicknames.unique', + type: 'boolean', + label: app.translator.trans('flarum-nicknames.admin.settings.unique_label') + }) + .registerSetting({ + setting: 'flarum-nicknames.regex', + type: 'text', + label: app.translator.trans('flarum-nicknames.admin.settings.regex_label') + }) + .registerSetting({ + setting: 'flarum-nicknames.min', + type: 'number', + label: app.translator.trans('flarum-nicknames.admin.settings.min_label') + }) + .registerSetting({ + setting: 'flarum-nicknames.max', + type: 'number', + label: app.translator.trans('flarum-nicknames.admin.settings.max_label') + }) + .registerPermission({ + icon: 'fas fa-user-tag', + label: app.translator.trans('flarum-nicknames.admin.permissions.edit_own_nickname_label'), + permission: 'user.editOwnNickname' + }, 'start') +}); diff --git a/extensions/nicknames/js/src/forum/components/NicknameModal.js b/extensions/nicknames/js/src/forum/components/NicknameModal.js index c7193a6b6..5544deb1a 100644 --- a/extensions/nicknames/js/src/forum/components/NicknameModal.js +++ b/extensions/nicknames/js/src/forum/components/NicknameModal.js @@ -13,7 +13,7 @@ export default class NicknameModal extends Modal { } title() { - return app.translator.trans('flarum-nicknames.forum.nickname.change'); + return app.translator.trans('flarum-nicknames.forum.change_nickname.title'); } content() { @@ -34,7 +34,7 @@ export default class NicknameModal extends Modal { className: 'Button Button--primary Button--block', type: 'submit', loading: this.loading, - }, app.translator.trans('flarum-nicknames.forum.nickname.submit_button'))} + }, app.translator.trans('flarum-nicknames.forum.change_nickname.submit_button'))} diff --git a/extensions/nicknames/js/src/forum/index.js b/extensions/nicknames/js/src/forum/index.js index 014ec75d5..d4a83fd5a 100644 --- a/extensions/nicknames/js/src/forum/index.js +++ b/extensions/nicknames/js/src/forum/index.js @@ -2,17 +2,23 @@ import { extend } from 'flarum/extend'; import Button from 'flarum/components/Button'; import EditUserModal from 'flarum/components/EditUserModal'; import SettingsPage from 'flarum/components/SettingsPage'; +import Model from 'flarum/Model'; +import User from 'flarum/models/User'; import extractText from 'flarum/utils/extractText'; import Stream from 'flarum/utils/Stream'; import NickNameModal from './components/NicknameModal'; app.initializers.add('flarum/nicknames', () => { + User.prototype.canEditOwnNickname = Model.attribute('canEditOwnNickname'); + extend(SettingsPage.prototype, 'accountItems', function (items) { - items.add('changeNickname', - - ); + if (this.user.canEditOwnNickname()) { + items.add('changeNickname', + + ); + } }); extend(EditUserModal.prototype, 'oninit', function () { @@ -22,9 +28,9 @@ app.initializers.add('flarum/nicknames', () => { extend(EditUserModal.prototype, 'fields', function (items) { items.add('nickname',
- +
, 100); }); diff --git a/extensions/nicknames/src/AddNicknameValidation.php b/extensions/nicknames/src/AddNicknameValidation.php new file mode 100644 index 000000000..a594eb6b4 --- /dev/null +++ b/extensions/nicknames/src/AddNicknameValidation.php @@ -0,0 +1,40 @@ +settings = $settings; + } + + public function __invoke($flarumValidator, Validator $validator) + { + $unique_nickname = ($this->settings->get('flarum-nicknames.unique')) ? 'unique:users,nickname' : ''; + + $validator->setRules([ + 'nickname' => [ + $unique_nickname, + function ($attribute, $value, $fail) { + $regex = $this->settings->get('flarum-nicknames.regex'); + if ($regex && !preg_match_all("/$regex/", $value)) { + $fail(app('translator')->trans('flarum-nicknames.api.invalid_nickname_message')); + } + }, + 'min:' . $this->settings->get('flarum-nicknames.min', 1), + 'max:' . $this->settings->get('flarum-nicknames.max', 150), + ], + ] + $validator->getRules()); + } +} diff --git a/extensions/nicknames/src/IdOnlyUserSlugDriver.php b/extensions/nicknames/src/IdOnlyUserSlugDriver.php index 91ad0005e..a07a2e057 100644 --- a/extensions/nicknames/src/IdOnlyUserSlugDriver.php +++ b/extensions/nicknames/src/IdOnlyUserSlugDriver.php @@ -6,8 +6,18 @@ namespace Flarum\Nicknames; use Flarum\Database\AbstractModel; use Flarum\Http\SlugDriverInterface; use Flarum\User\User; +use Flarum\User\UserRepository; class IdOnlyUserSlugDriver implements SlugDriverInterface { + /** + * @var $users UserRepository + */ + protected $users; + + public function __construct(UserRepository $users) + { + $this->users = $users; + } public function toSlug(AbstractModel $instance): string { @@ -16,6 +26,6 @@ class IdOnlyUserSlugDriver implements SlugDriverInterface { public function fromSlug(string $slug, User $actor): AbstractModel { - return User::where('id', $slug)->whereVisibleTo($actor)->firstOrFail(); + return $this->users->findOrFail($slug, $actor); } } diff --git a/extensions/nicknames/src/SaveNicknameToDatabase.php b/extensions/nicknames/src/SaveNicknameToDatabase.php index bdefd3e11..0b5bce8b4 100644 --- a/extensions/nicknames/src/SaveNicknameToDatabase.php +++ b/extensions/nicknames/src/SaveNicknameToDatabase.php @@ -13,15 +13,15 @@ class SaveNicknameToDatabase { $actor = $event->actor; $isSelf = $actor->id === $user->id; - $canEdit = $actor->can('edit', $user); $attributes = Arr::get($data, 'attributes', []); if (isset($attributes['nickname'])) { - if (!$isSelf) { - $actor->assertPermission($canEdit); + if ($isSelf) { + $actor->assertCan('editOwnNickname', $user); + } else { + $actor->assertCan('edit', $user); } $user->nickname = $attributes['nickname']; - $user->save(); } } }