mirror of
https://github.com/flarum/core.git
synced 2025-08-13 11:54:32 +02:00
Compare commits
13 Commits
dk/email-v
...
v1.8.2
Author | SHA1 | Date | |
---|---|---|---|
|
82e08e3fa5 | ||
|
2c4a2b8d9e | ||
|
00866fbba9 | ||
|
0d1d4d46d1 | ||
|
b1383a955f | ||
|
daeab48ae8 | ||
|
e03ca4406d | ||
|
7894c6a69b | ||
|
102e31754a | ||
|
8538f9c8f6 | ||
|
5a4bb7ccf2 | ||
|
d2a6329689 | ||
|
2bc2899a1d |
2
.github/workflows/frontend.yml
vendored
2
.github/workflows/frontend.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
backend_directory: ./
|
||||
js_package_manager: yarn
|
||||
cache_dependency_path: ./yarn.lock
|
||||
main_git_branch: main
|
||||
main_git_branch: 1.x
|
||||
enable_tests: true
|
||||
# @TODO: fix bundlewatch
|
||||
enable_bundlewatch: false
|
||||
|
@@ -1,10 +1,18 @@
|
||||
# Changelog
|
||||
|
||||
## [v1.8.2](https://github.com/flarum/framework/compare/v1.8.1...v1.8.2)
|
||||
### Fixed
|
||||
* suspended users can abuse avatar upload [#3890]
|
||||
* missing compat exports [#3888]
|
||||
|
||||
## [v1.8.1](https://github.com/flarum/framework/compare/v1.8.0...v1.8.1)
|
||||
### Fixed
|
||||
* recover temporary solution for html entities in browser title (e72541e35de4f71f9d870bbd9bb46ddf586bdf1d)
|
||||
* custom contrast color affected by parents (577890d89c593ae5b6cb96083fab69e2f1ae600c)
|
||||
* reply placeholder wrong positioning (253a3d281dbf5ce3fa712b629b80587cf67e7dbe)
|
||||
* (mentions) missed post mentions UI changes with lazy loading [#3832]
|
||||
* (mentions) cannot use newly introduced mentionables extender [#3849]
|
||||
* (mentions) missing slug from post mention links ([5a4bb7c](5a4bb7ccf226f66dd44816cb69b3d7cfe4ad7f7c))
|
||||
|
||||
## [v1.8.0](https://github.com/flarum/framework/compare/v1.7.1...v1.8.0)
|
||||
### Fixed
|
||||
|
@@ -50,7 +50,7 @@ class Akismet
|
||||
$client = new Client();
|
||||
|
||||
return $client->request('POST', "$this->apiUrl/$type", [
|
||||
'headers' => [
|
||||
'headers' => [
|
||||
'User-Agent' => "Flarum/$this->flarumVersion | Akismet/$this->extensionVersion",
|
||||
],
|
||||
'form_params' => $this->params,
|
||||
|
@@ -40,7 +40,6 @@ class AddCanFlagAttribute
|
||||
// If $actor is the post author, check to see if the setting is enabled
|
||||
return (bool) $this->settings->get('flarum-flags.can_flag_own');
|
||||
}
|
||||
|
||||
// $actor is not the post author
|
||||
return true;
|
||||
}
|
||||
|
@@ -31,10 +31,10 @@ class FlagSerializer extends AbstractSerializer
|
||||
}
|
||||
|
||||
return [
|
||||
'type' => $flag->type,
|
||||
'reason' => $flag->reason,
|
||||
'type' => $flag->type,
|
||||
'reason' => $flag->reason,
|
||||
'reasonDetail' => $flag->reason_detail,
|
||||
'createdAt' => $this->formatDate($flag->created_at),
|
||||
'createdAt' => $this->formatDate($flag->created_at),
|
||||
];
|
||||
}
|
||||
|
||||
|
@@ -78,15 +78,17 @@ return [
|
||||
->addInclude(['posts.mentionedBy', 'posts.mentionedBy.user', 'posts.mentionedBy.discussion'])
|
||||
->load([
|
||||
'posts.mentionsUsers', 'posts.mentionsPosts', 'posts.mentionsPosts.user',
|
||||
'posts.mentionsGroups'
|
||||
'posts.mentionsPosts.discussion', 'posts.mentionsGroups'
|
||||
])
|
||||
->loadWhere('posts.mentionedBy', [LoadMentionedByRelationship::class, 'mutateRelation'])
|
||||
->prepareDataForSerialization([LoadMentionedByRelationship::class, 'countRelation']),
|
||||
|
||||
(new Extend\ApiController(Controller\ListDiscussionsController::class))
|
||||
->load([
|
||||
'firstPost.mentionsUsers', 'firstPost.mentionsPosts', 'firstPost.mentionsPosts.user', 'firstPost.mentionsGroups',
|
||||
'lastPost.mentionsUsers', 'lastPost.mentionsPosts', 'lastPost.mentionsPosts.user', 'lastPost.mentionsGroups',
|
||||
'firstPost.mentionsUsers', 'firstPost.mentionsPosts',
|
||||
'firstPost.mentionsPosts.user', 'firstPost.mentionsPosts.discussion', 'firstPost.mentionsGroups',
|
||||
'lastPost.mentionsUsers', 'lastPost.mentionsPosts',
|
||||
'lastPost.mentionsPosts.user', 'lastPost.mentionsPosts.discussion', 'lastPost.mentionsGroups',
|
||||
]),
|
||||
|
||||
(new Extend\ApiController(Controller\ShowPostController::class))
|
||||
@@ -98,7 +100,7 @@ return [
|
||||
|
||||
(new Extend\ApiController(Controller\ListPostsController::class))
|
||||
->addInclude(['mentionedBy', 'mentionedBy.user', 'mentionedBy.discussion'])
|
||||
->load(['mentionsUsers', 'mentionsPosts', 'mentionsPosts.user', 'mentionsGroups'])
|
||||
->load(['mentionsUsers', 'mentionsPosts', 'mentionsPosts.user', 'mentionsPosts.discussion', 'mentionsGroups'])
|
||||
->loadWhere('mentionedBy', [LoadMentionedByRelationship::class, 'mutateRelation'])
|
||||
->prepareDataForSerialization([LoadMentionedByRelationship::class, 'countRelation']),
|
||||
|
||||
|
2
extensions/mentions/js/dist/forum.js
generated
vendored
2
extensions/mentions/js/dist/forum.js
generated
vendored
File diff suppressed because one or more lines are too long
2
extensions/mentions/js/dist/forum.js.map
generated
vendored
2
extensions/mentions/js/dist/forum.js.map
generated
vendored
File diff suppressed because one or more lines are too long
@@ -5,12 +5,9 @@ import TextEditorButton from 'flarum/common/components/TextEditorButton';
|
||||
import KeyboardNavigatable from 'flarum/common/utils/KeyboardNavigatable';
|
||||
|
||||
import AutocompleteDropdown from './fragments/AutocompleteDropdown';
|
||||
import MentionFormats from './mentionables/formats/MentionFormats';
|
||||
import MentionableModels from './mentionables/MentionableModels';
|
||||
|
||||
export default function addComposerAutocomplete() {
|
||||
app.mentionFormats = new MentionFormats();
|
||||
|
||||
const $container = $('<div class="ComposerBody-mentionsDropdownContainer"></div>');
|
||||
const dropdown = new AutocompleteDropdown();
|
||||
|
||||
|
@@ -118,7 +118,7 @@ export default function addMentionedByList() {
|
||||
});
|
||||
|
||||
const limit = 4;
|
||||
const overLimit = repliers.length > limit;
|
||||
const overLimit = post.mentionedByCount() > limit;
|
||||
|
||||
// Create a list of unique users who have replied. So even if a user has
|
||||
// replied twice, they will only be in this array once.
|
||||
@@ -136,7 +136,7 @@ export default function addMentionedByList() {
|
||||
// others" name to the end of the list. Clicking on it will display a modal
|
||||
// with a full list of names.
|
||||
if (overLimit) {
|
||||
const count = repliers.length - names.length;
|
||||
const count = post.mentionedByCount() - names.length;
|
||||
|
||||
names.push(app.translator.trans('flarum-mentions.forum.post.others_text', { count }));
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@ import type MentionFormat from '../mentionables/formats/MentionFormat';
|
||||
|
||||
export default class Mentionables implements IExtender<ForumApplication> {
|
||||
protected formats: (new () => MentionFormat)[] = [];
|
||||
protected mentionables: Record<string, (new () => MentionableModel)[]> = {};
|
||||
protected mentionables: Record<string, (new (...args: any[]) => MentionableModel)[]> = {};
|
||||
|
||||
/**
|
||||
* Register a new mention format.
|
||||
@@ -26,7 +26,7 @@ export default class Mentionables implements IExtender<ForumApplication> {
|
||||
* @param mentionable The mentionable instance to register.
|
||||
* Must extend MentionableModel.
|
||||
*/
|
||||
mentionable(symbol: string, mentionable: new () => MentionableModel): this {
|
||||
mentionable(symbol: string, mentionable: new (...args: any[]) => MentionableModel): this {
|
||||
if (!this.mentionables[symbol]) {
|
||||
this.mentionables[symbol] = [];
|
||||
}
|
||||
|
@@ -13,11 +13,14 @@ import addComposerAutocomplete from './addComposerAutocomplete';
|
||||
import PostMentionedNotification from './components/PostMentionedNotification';
|
||||
import UserMentionedNotification from './components/UserMentionedNotification';
|
||||
import GroupMentionedNotification from './components/GroupMentionedNotification';
|
||||
import MentionFormats from './mentionables/formats/MentionFormats';
|
||||
import UserPage from 'flarum/forum/components/UserPage';
|
||||
import LinkButton from 'flarum/common/components/LinkButton';
|
||||
import User from 'flarum/common/models/User';
|
||||
import Model from 'flarum/common/Model';
|
||||
|
||||
app.mentionFormats = new MentionFormats();
|
||||
|
||||
export { default as extend } from './extend';
|
||||
|
||||
app.initializers.add('flarum-mentions', function () {
|
||||
|
@@ -4,7 +4,7 @@ import TagMention from '../TagMention';
|
||||
|
||||
export default class HashMentionFormat extends MentionFormat {
|
||||
public mentionables: (new (...args: any[]) => MentionableModel)[] = [TagMention];
|
||||
protected extendable: boolean = false;
|
||||
protected extendable: boolean = true;
|
||||
|
||||
public trigger(): string {
|
||||
return '#';
|
||||
|
@@ -29,7 +29,7 @@ class LoadMentionedByRelationship
|
||||
$actor = RequestUtil::getActor($request);
|
||||
|
||||
return $query
|
||||
->with(['mentionsPosts', 'mentionsPosts.user', 'mentionsUsers'])
|
||||
->with(['mentionsPosts', 'mentionsPosts.user', 'mentionsPosts.discussion', 'mentionsUsers'])
|
||||
->whereVisibleTo($actor)
|
||||
->oldest()
|
||||
// Limiting a relationship results is only possible because
|
||||
@@ -50,6 +50,16 @@ class LoadMentionedByRelationship
|
||||
$loadable = $data->newCollection($data->posts)->filter(function ($post) {
|
||||
return $post instanceof Post;
|
||||
});
|
||||
|
||||
// firstPost and lastPost might have been included in the API response,
|
||||
// so we have to make sure counts are also loaded for them.
|
||||
if ($data->firstPost) {
|
||||
$loadable->push($data->firstPost);
|
||||
}
|
||||
|
||||
if ($data->lastPost) {
|
||||
$loadable->push($data->lastPost);
|
||||
}
|
||||
} elseif ($data instanceof Collection) {
|
||||
$loadable = $data;
|
||||
} elseif ($data instanceof Post) {
|
||||
|
@@ -9,6 +9,8 @@
|
||||
|
||||
namespace Flarum\Mentions\Formatter;
|
||||
|
||||
use Flarum\Discussion\Discussion;
|
||||
use Flarum\Http\SlugManager;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use s9e\TextFormatter\Renderer;
|
||||
use s9e\TextFormatter\Utils;
|
||||
@@ -21,9 +23,15 @@ class FormatPostMentions
|
||||
*/
|
||||
private $translator;
|
||||
|
||||
public function __construct(TranslatorInterface $translator)
|
||||
/**
|
||||
* @var SlugManager
|
||||
*/
|
||||
private $slugManager;
|
||||
|
||||
public function __construct(TranslatorInterface $translator, SlugManager $slugManager)
|
||||
{
|
||||
$this->translator = $translator;
|
||||
$this->slugManager = $slugManager;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,6 +64,12 @@ class FormatPostMentions
|
||||
$attributes['displayname'] = $this->translator->trans('core.lib.username.deleted_text');
|
||||
}
|
||||
|
||||
if ($post) {
|
||||
$attributes['discussionid'] = $this->slugManager
|
||||
->forResource(Discussion::class)
|
||||
->toSlug($post->discussion);
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
});
|
||||
}
|
||||
|
@@ -25,4 +25,11 @@ class UserPolicy extends AbstractPolicy
|
||||
return $this->deny();
|
||||
}
|
||||
}
|
||||
|
||||
public function uploadAvatar(User $actor, User $user)
|
||||
{
|
||||
if ($actor->suspended_until && $actor->suspended_until->isFuture()) {
|
||||
return $this->deny();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
BIN
extensions/suspend/tests/fixtures/avatar.png
vendored
Normal file
BIN
extensions/suspend/tests/fixtures/avatar.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Suspend\Tests\integration\api\users;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
|
||||
use Flarum\Testing\integration\TestCase;
|
||||
use Laminas\Diactoros\UploadedFile;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class UploadAvatarTest extends TestCase
|
||||
{
|
||||
use RetrievesAuthorizedUsers;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->extension('flarum-suspend');
|
||||
|
||||
$this->prepareDatabase([
|
||||
'users' => [
|
||||
['id' => 1, 'username' => 'Muralf', 'email' => 'muralf@machine.local', 'is_email_confirmed' => 1],
|
||||
$this->normalUser(),
|
||||
['id' => 3, 'username' => 'acme', 'email' => 'acme@machine.local', 'is_email_confirmed' => 1, 'suspended_until' => Carbon::now()->addDay(), 'suspend_message' => 'You have been suspended.', 'suspend_reason' => 'Suspended for acme reasons.'],
|
||||
['id' => 4, 'username' => 'acme4', 'email' => 'acme4@machine.local', 'is_email_confirmed' => 1],
|
||||
['id' => 5, 'username' => 'acme5', 'email' => 'acme5@machine.local', 'is_email_confirmed' => 1, 'suspended_until' => Carbon::now()->subDay(), 'suspend_message' => 'You have been suspended.', 'suspend_reason' => 'Suspended for acme reasons.'],
|
||||
],
|
||||
'groups' => [
|
||||
['id' => 5, 'name_singular' => 'can_edit_users', 'name_plural' => 'can_edit_users', 'is_hidden' => 0]
|
||||
],
|
||||
'group_user' => [
|
||||
['user_id' => 2, 'group_id' => 5]
|
||||
],
|
||||
'group_permission' => [
|
||||
['permission' => 'user.edit', 'group_id' => 5],
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider allowedToUploadAvatar
|
||||
* @test
|
||||
*/
|
||||
public function can_suspend_user_if_allowed(?int $authenticatedAs, int $targetUserId, string $message)
|
||||
{
|
||||
$response = $this->sendUploadAvatarRequest($authenticatedAs, $targetUserId);
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode(), $response->getBody()->getContents());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider unallowedToUploadAvatar
|
||||
* @test
|
||||
*/
|
||||
public function cannot_suspend_user_if_not_allowed(?int $authenticatedAs, int $targetUserId, string $message)
|
||||
{
|
||||
$response = $this->sendUploadAvatarRequest($authenticatedAs, $targetUserId);
|
||||
|
||||
$this->assertEquals(403, $response->getStatusCode(), $response->getBody()->getContents());
|
||||
}
|
||||
|
||||
public function allowedToUploadAvatar(): array
|
||||
{
|
||||
return [
|
||||
[1, 2, 'Admin can upload avatar for any user'],
|
||||
[2, 3, 'User with permission can upload avatar for suspended user'],
|
||||
[2, 2, 'User with permission can upload avatar for self'],
|
||||
[2, 4, 'User with permission can upload avatar for other user'],
|
||||
[1, 1, 'Admin can upload avatar for self'],
|
||||
[5, 5, 'Suspended user can upload avatar for self if suspension expired'],
|
||||
];
|
||||
}
|
||||
|
||||
public function unallowedToUploadAvatar(): array
|
||||
{
|
||||
return [
|
||||
[3, 3, 'Suspended user cannot upload avatar for self'],
|
||||
[3, 2, 'Suspended user cannot upload avatar for other user'],
|
||||
[4, 3, 'User without permission cannot upload avatar for suspended user'],
|
||||
[4, 2, 'User without permission cannot upload avatar for other user'],
|
||||
[5, 2, 'Suspended user cannot upload avatar for other user if suspension expired'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function sendUploadAvatarRequest(?int $authenticatedAs, int $targetUserId): ResponseInterface
|
||||
{
|
||||
return $this->send(
|
||||
$this->request('POST', "/api/users/$targetUserId/avatar", [
|
||||
'authenticatedAs' => $authenticatedAs,
|
||||
])->withHeader('Content-Type', 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW')->withUploadedFiles([
|
||||
'avatar' => new UploadedFile(__DIR__.'/../../../fixtures/avatar.png', 0, UPLOAD_ERR_OK, 'avatar.png', 'image/png')
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
@@ -47,19 +47,19 @@ class TagSerializer extends AbstractSerializer
|
||||
}
|
||||
|
||||
$attributes = [
|
||||
'name' => $tag->name,
|
||||
'description' => $tag->description,
|
||||
'slug' => $this->slugManager->forResource(Tag::class)->toSlug($tag),
|
||||
'color' => $tag->color,
|
||||
'backgroundUrl' => $tag->background_path,
|
||||
'backgroundMode' => $tag->background_mode,
|
||||
'icon' => $tag->icon,
|
||||
'discussionCount' => (int) $tag->discussion_count,
|
||||
'position' => $tag->position === null ? null : (int) $tag->position,
|
||||
'defaultSort' => $tag->default_sort,
|
||||
'isChild' => (bool) $tag->parent_id,
|
||||
'isHidden' => (bool) $tag->is_hidden,
|
||||
'lastPostedAt' => $this->formatDate($tag->last_posted_at),
|
||||
'name' => $tag->name,
|
||||
'description' => $tag->description,
|
||||
'slug' => $this->slugManager->forResource(Tag::class)->toSlug($tag),
|
||||
'color' => $tag->color,
|
||||
'backgroundUrl' => $tag->background_path,
|
||||
'backgroundMode' => $tag->background_mode,
|
||||
'icon' => $tag->icon,
|
||||
'discussionCount' => (int) $tag->discussion_count,
|
||||
'position' => $tag->position === null ? null : (int) $tag->position,
|
||||
'defaultSort' => $tag->default_sort,
|
||||
'isChild' => (bool) $tag->parent_id,
|
||||
'isHidden' => (bool) $tag->is_hidden,
|
||||
'lastPostedAt' => $this->formatDate($tag->last_posted_at),
|
||||
'canStartDiscussion' => $this->actor->can('startDiscussion', $tag),
|
||||
'canAddToDiscussion' => $this->actor->can('addToDiscussion', $tag)
|
||||
];
|
||||
|
@@ -27,7 +27,7 @@ trait RetrievesRepresentativeTags
|
||||
['id' => 11, 'name' => 'Secondary Restricted', 'slug' => 'secondary-restricted', 'position' => null, 'parent_id' => null, 'is_restricted' => true],
|
||||
['id' => 12, 'name' => 'Primary Restricted 2', 'slug' => 'primary-2-restricted', 'position' => 100, 'parent_id' => null, 'is_restricted' => true],
|
||||
['id' => 13, 'name' => 'Primary Restricted 2 Child 1', 'slug' => 'primary-2-restricted-child-1', 'position' => 101, 'parent_id' => 12],
|
||||
['id' => 14, 'name' => 'Primary Restricted 3', 'slug' => 'primary-3-restricted', 'position' => 102, 'parent_id' => null, 'is_restricted' => true],
|
||||
['id' => 14, 'name' => 'Primary Restricted 3', 'slug' => 'primary-3-restricted', 'position' => 102, 'parent_id' =>null, 'is_restricted' => true],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
1
framework/core/js/dist-typings/admin/compat.d.ts
generated
vendored
1
framework/core/js/dist-typings/admin/compat.d.ts
generated
vendored
@@ -122,6 +122,7 @@ declare const _default: {
|
||||
'components/TextEditorButton': typeof import("../common/components/TextEditorButton").default;
|
||||
'components/Tooltip': typeof import("../common/components/Tooltip").default;
|
||||
'components/EditUserModal': typeof import("../common/components/EditUserModal").default;
|
||||
'components/LabelValue': typeof import("../common/components/LabelValue").default;
|
||||
Model: typeof import("../common/Model").default;
|
||||
Application: typeof import("../common/Application").default;
|
||||
'helpers/fullTime': typeof import("../common/helpers/fullTime").default;
|
||||
|
2
framework/core/js/dist-typings/common/compat.d.ts
generated
vendored
2
framework/core/js/dist-typings/common/compat.d.ts
generated
vendored
@@ -86,6 +86,7 @@ import isObject from './utils/isObject';
|
||||
import AlertManagerState from './states/AlertManagerState';
|
||||
import ModalManagerState from './states/ModalManagerState';
|
||||
import PageState from './states/PageState';
|
||||
import LabelValue from './components/LabelValue';
|
||||
declare const _default: {
|
||||
extenders: {
|
||||
Model: typeof import("./extenders/Model").default;
|
||||
@@ -174,6 +175,7 @@ declare const _default: {
|
||||
'components/TextEditorButton': typeof TextEditorButton;
|
||||
'components/Tooltip': typeof Tooltip;
|
||||
'components/EditUserModal': typeof EditUserModal;
|
||||
'components/LabelValue': typeof LabelValue;
|
||||
Model: typeof Model;
|
||||
Application: typeof Application;
|
||||
'helpers/fullTime': typeof fullTime;
|
||||
|
3
framework/core/js/dist-typings/forum/compat.d.ts
generated
vendored
3
framework/core/js/dist-typings/forum/compat.d.ts
generated
vendored
@@ -71,6 +71,7 @@ import BasicEditorDriver from '../common/utils/BasicEditorDriver';
|
||||
import routes from './routes';
|
||||
import ForumApplication from './ForumApplication';
|
||||
import isSafariMobile from './utils/isSafariMobile';
|
||||
import AccessTokensList from './components/AccessTokensList';
|
||||
declare const _default: {
|
||||
extenders: {
|
||||
Model: typeof import("../common/extenders/Model").default;
|
||||
@@ -159,6 +160,7 @@ declare const _default: {
|
||||
'components/TextEditorButton': typeof import("../common/components/TextEditorButton").default;
|
||||
'components/Tooltip': typeof import("../common/components/Tooltip").default;
|
||||
'components/EditUserModal': typeof import("../common/components/EditUserModal").default;
|
||||
'components/LabelValue': typeof import("../common/components/LabelValue").default;
|
||||
Model: typeof import("../common/Model").default;
|
||||
Application: typeof import("../common/Application").default;
|
||||
'helpers/fullTime': typeof import("../common/helpers/fullTime").default;
|
||||
@@ -276,6 +278,7 @@ declare const _default: {
|
||||
'components/DiscussionListItem': typeof DiscussionListItem;
|
||||
'components/LoadingPost': typeof LoadingPost;
|
||||
'components/PostsUserPage': typeof PostsUserPage;
|
||||
'components/AccessTokensList': typeof AccessTokensList;
|
||||
'resolvers/DiscussionPageResolver': typeof DiscussionPageResolver;
|
||||
routes: typeof routes;
|
||||
ForumApplication: typeof ForumApplication;
|
||||
|
2
framework/core/js/dist/admin.js
generated
vendored
2
framework/core/js/dist/admin.js
generated
vendored
File diff suppressed because one or more lines are too long
2
framework/core/js/dist/admin.js.map
generated
vendored
2
framework/core/js/dist/admin.js.map
generated
vendored
File diff suppressed because one or more lines are too long
2
framework/core/js/dist/forum.js
generated
vendored
2
framework/core/js/dist/forum.js
generated
vendored
File diff suppressed because one or more lines are too long
2
framework/core/js/dist/forum.js.map
generated
vendored
2
framework/core/js/dist/forum.js.map
generated
vendored
File diff suppressed because one or more lines are too long
@@ -40,7 +40,7 @@ export default class StatusWidget extends DashboardWidget {
|
||||
[
|
||||
<span>
|
||||
<strong>{app.translator.trans('core.admin.dashboard.status.headers.scheduler-status')}</strong>{' '}
|
||||
<LinkButton href="https://docs.flarum.org/scheduler" external={true} target="_blank" icon="fas fa-info-circle" />
|
||||
<LinkButton href="https://discuss.flarum.org/d/24118" external={true} target="_blank" icon="fas fa-info-circle" />
|
||||
</span>,
|
||||
<br />,
|
||||
app.data.schedulerStatus,
|
||||
|
@@ -90,6 +90,7 @@ import isObject from './utils/isObject';
|
||||
import AlertManagerState from './states/AlertManagerState';
|
||||
import ModalManagerState from './states/ModalManagerState';
|
||||
import PageState from './states/PageState';
|
||||
import LabelValue from './components/LabelValue';
|
||||
|
||||
export default {
|
||||
extenders,
|
||||
@@ -167,6 +168,7 @@ export default {
|
||||
'components/TextEditorButton': TextEditorButton,
|
||||
'components/Tooltip': Tooltip,
|
||||
'components/EditUserModal': EditUserModal,
|
||||
'components/LabelValue': LabelValue,
|
||||
Model: Model,
|
||||
Application: Application,
|
||||
'helpers/fullTime': fullTime,
|
||||
|
@@ -75,6 +75,7 @@ import BasicEditorDriver from '../common/utils/BasicEditorDriver';
|
||||
import routes from './routes';
|
||||
import ForumApplication from './ForumApplication';
|
||||
import isSafariMobile from './utils/isSafariMobile';
|
||||
import AccessTokensList from './components/AccessTokensList';
|
||||
|
||||
export default Object.assign(compat, {
|
||||
'utils/PostControls': PostControls,
|
||||
@@ -150,6 +151,7 @@ export default Object.assign(compat, {
|
||||
'components/DiscussionListItem': DiscussionListItem,
|
||||
'components/LoadingPost': LoadingPost,
|
||||
'components/PostsUserPage': PostsUserPage,
|
||||
'components/AccessTokensList': AccessTokensList,
|
||||
'resolvers/DiscussionPageResolver': DiscussionPageResolver,
|
||||
routes: routes,
|
||||
ForumApplication: ForumApplication,
|
||||
|
@@ -46,7 +46,7 @@ class BasicDiscussionSerializer extends AbstractSerializer
|
||||
|
||||
return [
|
||||
'title' => $discussion->title,
|
||||
'slug' => $this->slugManager->forResource(Discussion::class)->toSlug($discussion),
|
||||
'slug' => $this->slugManager->forResource(Discussion::class)->toSlug($discussion),
|
||||
];
|
||||
}
|
||||
|
||||
|
@@ -53,8 +53,8 @@ class BasicPostSerializer extends AbstractSerializer
|
||||
}
|
||||
|
||||
$attributes = [
|
||||
'number' => (int) $post->number,
|
||||
'createdAt' => $this->formatDate($post->created_at),
|
||||
'number' => (int) $post->number,
|
||||
'createdAt' => $this->formatDate($post->created_at),
|
||||
'contentType' => $post->type
|
||||
];
|
||||
|
||||
|
@@ -45,10 +45,10 @@ class BasicUserSerializer extends AbstractSerializer
|
||||
}
|
||||
|
||||
return [
|
||||
'username' => $user->username,
|
||||
'username' => $user->username,
|
||||
'displayName' => $user->display_name,
|
||||
'avatarUrl' => $user->avatar_url,
|
||||
'slug' => $this->slugManager->forResource(User::class)->toSlug($user)
|
||||
'avatarUrl' => $user->avatar_url,
|
||||
'slug' => $this->slugManager->forResource(User::class)->toSlug($user)
|
||||
];
|
||||
}
|
||||
|
||||
|
@@ -20,13 +20,13 @@ class CurrentUserSerializer extends UserSerializer
|
||||
$attributes = parent::getDefaultAttributes($user);
|
||||
|
||||
$attributes += [
|
||||
'isEmailConfirmed' => (bool) $user->is_email_confirmed,
|
||||
'email' => $user->email,
|
||||
'markedAllAsReadAt' => $this->formatDate($user->marked_all_as_read_at),
|
||||
'unreadNotificationCount' => (int) $user->getUnreadNotificationCount(),
|
||||
'newNotificationCount' => (int) $user->getNewNotificationCount(),
|
||||
'preferences' => (array) $user->preferences,
|
||||
'isAdmin' => $user->isAdmin(),
|
||||
'isEmailConfirmed' => (bool) $user->is_email_confirmed,
|
||||
'email' => $user->email,
|
||||
'markedAllAsReadAt' => $this->formatDate($user->marked_all_as_read_at),
|
||||
'unreadNotificationCount' => (int) $user->getUnreadNotificationCount(),
|
||||
'newNotificationCount' => (int) $user->getNewNotificationCount(),
|
||||
'preferences' => (array) $user->preferences,
|
||||
'isAdmin' => $user->isAdmin(),
|
||||
];
|
||||
|
||||
return $attributes;
|
||||
|
@@ -19,15 +19,15 @@ class DiscussionSerializer extends BasicDiscussionSerializer
|
||||
protected function getDefaultAttributes($discussion)
|
||||
{
|
||||
$attributes = parent::getDefaultAttributes($discussion) + [
|
||||
'commentCount' => (int) $discussion->comment_count,
|
||||
'participantCount' => (int) $discussion->participant_count,
|
||||
'createdAt' => $this->formatDate($discussion->created_at),
|
||||
'lastPostedAt' => $this->formatDate($discussion->last_posted_at),
|
||||
'lastPostNumber' => (int) $discussion->last_post_number,
|
||||
'canReply' => $this->actor->can('reply', $discussion),
|
||||
'canRename' => $this->actor->can('rename', $discussion),
|
||||
'canDelete' => $this->actor->can('delete', $discussion),
|
||||
'canHide' => $this->actor->can('hide', $discussion)
|
||||
'commentCount' => (int) $discussion->comment_count,
|
||||
'participantCount' => (int) $discussion->participant_count,
|
||||
'createdAt' => $this->formatDate($discussion->created_at),
|
||||
'lastPostedAt' => $this->formatDate($discussion->last_posted_at),
|
||||
'lastPostNumber' => (int) $discussion->last_post_number,
|
||||
'canReply' => $this->actor->can('reply', $discussion),
|
||||
'canRename' => $this->actor->can('rename', $discussion),
|
||||
'canDelete' => $this->actor->can('delete', $discussion),
|
||||
'canHide' => $this->actor->can('hide', $discussion)
|
||||
];
|
||||
|
||||
if ($discussion->hidden_at) {
|
||||
|
@@ -89,7 +89,7 @@ class ForumSerializer extends AbstractSerializer
|
||||
'headerHtml' => $this->settings->get('custom_header'),
|
||||
'footerHtml' => $this->settings->get('custom_footer'),
|
||||
'allowSignUp' => (bool) $this->settings->get('allow_sign_up'),
|
||||
'defaultRoute' => $this->settings->get('default_route'),
|
||||
'defaultRoute' => $this->settings->get('default_route'),
|
||||
'canViewForum' => $this->actor->can('viewForum'),
|
||||
'canStartDiscussion' => $this->actor->can('startDiscussion'),
|
||||
'canSearchUsers' => $this->actor->can('searchUsers'),
|
||||
|
@@ -49,10 +49,10 @@ class GroupSerializer extends AbstractSerializer
|
||||
|
||||
return [
|
||||
'nameSingular' => $this->translateGroupName($group->name_singular),
|
||||
'namePlural' => $this->translateGroupName($group->name_plural),
|
||||
'color' => $group->color,
|
||||
'icon' => $group->icon,
|
||||
'isHidden' => $group->is_hidden
|
||||
'namePlural' => $this->translateGroupName($group->name_plural),
|
||||
'color' => $group->color,
|
||||
'icon' => $group->icon,
|
||||
'isHidden' => $group->is_hidden
|
||||
];
|
||||
}
|
||||
|
||||
|
@@ -43,9 +43,9 @@ class NotificationSerializer extends AbstractSerializer
|
||||
|
||||
return [
|
||||
'contentType' => $notification->type,
|
||||
'content' => $notification->data,
|
||||
'createdAt' => $this->formatDate($notification->created_at),
|
||||
'isRead' => (bool) $notification->read_at
|
||||
'content' => $notification->data,
|
||||
'createdAt' => $this->formatDate($notification->created_at),
|
||||
'isRead' => (bool) $notification->read_at
|
||||
];
|
||||
}
|
||||
|
||||
|
@@ -45,9 +45,9 @@ class PostSerializer extends BasicPostSerializer
|
||||
}
|
||||
|
||||
$attributes += [
|
||||
'canEdit' => $canEdit,
|
||||
'canEdit' => $canEdit,
|
||||
'canDelete' => $this->actor->can('delete', $post),
|
||||
'canHide' => $this->actor->can('hide', $post)
|
||||
'canHide' => $this->actor->can('hide', $post)
|
||||
];
|
||||
|
||||
return $attributes;
|
||||
|
@@ -20,13 +20,13 @@ class UserSerializer extends BasicUserSerializer
|
||||
$attributes = parent::getDefaultAttributes($user);
|
||||
|
||||
$attributes += [
|
||||
'joinTime' => $this->formatDate($user->joined_at),
|
||||
'discussionCount' => (int) $user->discussion_count,
|
||||
'commentCount' => (int) $user->comment_count,
|
||||
'canEdit' => $this->actor->can('edit', $user),
|
||||
'joinTime' => $this->formatDate($user->joined_at),
|
||||
'discussionCount' => (int) $user->discussion_count,
|
||||
'commentCount' => (int) $user->comment_count,
|
||||
'canEdit' => $this->actor->can('edit', $user),
|
||||
'canEditCredentials' => $this->actor->can('editCredentials', $user),
|
||||
'canEditGroups' => $this->actor->can('editGroups', $user),
|
||||
'canDelete' => $this->actor->can('delete', $user),
|
||||
'canEditGroups' => $this->actor->can('editGroups', $user),
|
||||
'canDelete' => $this->actor->can('delete', $user),
|
||||
];
|
||||
|
||||
if ($user->getPreference('discloseOnline') || $this->actor->can('viewLastSeenAt', $user)) {
|
||||
@@ -38,7 +38,7 @@ class UserSerializer extends BasicUserSerializer
|
||||
if ($attributes['canEditCredentials'] || $this->actor->id === $user->id) {
|
||||
$attributes += [
|
||||
'isEmailConfirmed' => (bool) $user->is_email_confirmed,
|
||||
'email' => $user->email
|
||||
'email' => $user->email
|
||||
];
|
||||
}
|
||||
|
||||
|
@@ -510,15 +510,15 @@ class Extension implements Arrayable
|
||||
public function toArray()
|
||||
{
|
||||
return (array) array_merge([
|
||||
'id' => $this->getId(),
|
||||
'version' => $this->getVersion(),
|
||||
'path' => $this->getPath(),
|
||||
'icon' => $this->getIcon(),
|
||||
'hasAssets' => $this->hasAssets(),
|
||||
'hasMigrations' => $this->hasMigrations(),
|
||||
'id' => $this->getId(),
|
||||
'version' => $this->getVersion(),
|
||||
'path' => $this->getPath(),
|
||||
'icon' => $this->getIcon(),
|
||||
'hasAssets' => $this->hasAssets(),
|
||||
'hasMigrations' => $this->hasMigrations(),
|
||||
'extensionDependencyIds' => $this->getExtensionDependencyIds(),
|
||||
'optionalDependencyIds' => $this->getOptionalDependencyIds(),
|
||||
'links' => $this->getLinks(),
|
||||
'optionalDependencyIds' => $this->getOptionalDependencyIds(),
|
||||
'links' => $this->getLinks(),
|
||||
], $this->composerJson);
|
||||
}
|
||||
|
||||
|
@@ -36,14 +36,14 @@ class FilesystemServiceProvider extends AbstractServiceProvider
|
||||
return [
|
||||
'flarum-assets' => function (Paths $paths, UrlGenerator $url) {
|
||||
return [
|
||||
'root' => "$paths->public/assets",
|
||||
'url' => $url->to('forum')->path('assets')
|
||||
'root' => "$paths->public/assets",
|
||||
'url' => $url->to('forum')->path('assets')
|
||||
];
|
||||
},
|
||||
'flarum-avatars' => function (Paths $paths, UrlGenerator $url) {
|
||||
return [
|
||||
'root' => "$paths->public/assets/avatars",
|
||||
'url' => $url->to('forum')->path('assets/avatars')
|
||||
'root' => "$paths->public/assets/avatars",
|
||||
'url' => $url->to('forum')->path('assets/avatars')
|
||||
];
|
||||
},
|
||||
];
|
||||
|
@@ -21,7 +21,7 @@ class Application
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const VERSION = '2.0-dev';
|
||||
const VERSION = '1.8.2';
|
||||
|
||||
/**
|
||||
* The IoC container for the Flarum application.
|
||||
@@ -336,22 +336,22 @@ class Application
|
||||
public function registerCoreContainerAliases()
|
||||
{
|
||||
$aliases = [
|
||||
'app' => [\Illuminate\Contracts\Container\Container::class, \Illuminate\Contracts\Foundation\Application::class, \Psr\Container\ContainerInterface::class],
|
||||
'blade.compiler' => [\Illuminate\View\Compilers\BladeCompiler::class],
|
||||
'cache' => [\Illuminate\Cache\CacheManager::class, \Illuminate\Contracts\Cache\Factory::class],
|
||||
'cache.store' => [\Illuminate\Cache\Repository::class, \Illuminate\Contracts\Cache\Repository::class],
|
||||
'config' => [\Illuminate\Config\Repository::class, \Illuminate\Contracts\Config\Repository::class],
|
||||
'db' => [\Illuminate\Database\DatabaseManager::class],
|
||||
'db.connection' => [\Illuminate\Database\Connection::class, \Illuminate\Database\ConnectionInterface::class],
|
||||
'events' => [\Illuminate\Events\Dispatcher::class, \Illuminate\Contracts\Events\Dispatcher::class],
|
||||
'files' => [\Illuminate\Filesystem\Filesystem::class],
|
||||
'filesystem' => [\Illuminate\Filesystem\FilesystemManager::class, \Illuminate\Contracts\Filesystem\Factory::class],
|
||||
'filesystem.disk' => [\Illuminate\Contracts\Filesystem\Filesystem::class],
|
||||
'filesystem.cloud' => [\Illuminate\Contracts\Filesystem\Cloud::class],
|
||||
'hash' => [\Illuminate\Contracts\Hashing\Hasher::class],
|
||||
'mailer' => [\Illuminate\Mail\Mailer::class, \Illuminate\Contracts\Mail\Mailer::class, \Illuminate\Contracts\Mail\MailQueue::class],
|
||||
'validator' => [\Illuminate\Validation\Factory::class, \Illuminate\Contracts\Validation\Factory::class],
|
||||
'view' => [\Illuminate\View\Factory::class, \Illuminate\Contracts\View\Factory::class],
|
||||
'app' => [\Illuminate\Contracts\Container\Container::class, \Illuminate\Contracts\Foundation\Application::class, \Psr\Container\ContainerInterface::class],
|
||||
'blade.compiler' => [\Illuminate\View\Compilers\BladeCompiler::class],
|
||||
'cache' => [\Illuminate\Cache\CacheManager::class, \Illuminate\Contracts\Cache\Factory::class],
|
||||
'cache.store' => [\Illuminate\Cache\Repository::class, \Illuminate\Contracts\Cache\Repository::class],
|
||||
'config' => [\Illuminate\Config\Repository::class, \Illuminate\Contracts\Config\Repository::class],
|
||||
'db' => [\Illuminate\Database\DatabaseManager::class],
|
||||
'db.connection' => [\Illuminate\Database\Connection::class, \Illuminate\Database\ConnectionInterface::class],
|
||||
'events' => [\Illuminate\Events\Dispatcher::class, \Illuminate\Contracts\Events\Dispatcher::class],
|
||||
'files' => [\Illuminate\Filesystem\Filesystem::class],
|
||||
'filesystem' => [\Illuminate\Filesystem\FilesystemManager::class, \Illuminate\Contracts\Filesystem\Factory::class],
|
||||
'filesystem.disk' => [\Illuminate\Contracts\Filesystem\Filesystem::class],
|
||||
'filesystem.cloud' => [\Illuminate\Contracts\Filesystem\Cloud::class],
|
||||
'hash' => [\Illuminate\Contracts\Hashing\Hasher::class],
|
||||
'mailer' => [\Illuminate\Mail\Mailer::class, \Illuminate\Contracts\Mail\Mailer::class, \Illuminate\Contracts\Mail\MailQueue::class],
|
||||
'validator' => [\Illuminate\Validation\Factory::class, \Illuminate\Contracts\Validation\Factory::class],
|
||||
'view' => [\Illuminate\View\Factory::class, \Illuminate\Contracts\View\Factory::class],
|
||||
];
|
||||
|
||||
foreach ($aliases as $key => $aliases) {
|
||||
|
@@ -136,19 +136,19 @@ class FrontendServiceProvider extends AbstractServiceProvider
|
||||
|
||||
$this->container->singleton('flarum.less.config', function (Container $container) {
|
||||
return [
|
||||
'config-primary-color' => [
|
||||
'config-primary-color' => [
|
||||
'key' => 'theme_primary_color',
|
||||
],
|
||||
'config-secondary-color' => [
|
||||
'key' => 'theme_secondary_color',
|
||||
],
|
||||
'config-dark-mode' => [
|
||||
'config-dark-mode' => [
|
||||
'key' => 'theme_dark_mode',
|
||||
'callback' => function ($value) {
|
||||
return $value ? 'true' : 'false';
|
||||
},
|
||||
],
|
||||
'config-colored-header' => [
|
||||
'config-colored-header' => [
|
||||
'key' => 'theme_colored_header',
|
||||
'callback' => function ($value) {
|
||||
return $value ? 'true' : 'false';
|
||||
|
@@ -37,17 +37,17 @@ class DatabaseConfig implements Arrayable
|
||||
public function toArray()
|
||||
{
|
||||
return [
|
||||
'driver' => $this->driver,
|
||||
'host' => $this->host,
|
||||
'port' => $this->port,
|
||||
'database' => $this->database,
|
||||
'username' => $this->username,
|
||||
'password' => $this->password,
|
||||
'charset' => 'utf8mb4',
|
||||
'driver' => $this->driver,
|
||||
'host' => $this->host,
|
||||
'port' => $this->port,
|
||||
'database' => $this->database,
|
||||
'username' => $this->username,
|
||||
'password' => $this->password,
|
||||
'charset' => 'utf8mb4',
|
||||
'collation' => 'utf8mb4_unicode_ci',
|
||||
'prefix' => $this->prefix,
|
||||
'strict' => false,
|
||||
'engine' => 'InnoDB',
|
||||
'prefix' => $this->prefix,
|
||||
'strict' => false,
|
||||
'engine' => 'InnoDB',
|
||||
'prefix_indexes' => true
|
||||
];
|
||||
}
|
||||
|
@@ -53,12 +53,12 @@ class StoreConfig implements ReversibleStep
|
||||
private function buildConfig()
|
||||
{
|
||||
return [
|
||||
'debug' => $this->debugMode,
|
||||
'debug' => $this->debugMode,
|
||||
'database' => $this->dbConfig->toArray(),
|
||||
'url' => (string) $this->baseUrl,
|
||||
'paths' => $this->getPathsConfig(),
|
||||
'headers' => [
|
||||
'poweredByHeader' => true,
|
||||
'url' => (string) $this->baseUrl,
|
||||
'paths' => $this->getPathsConfig(),
|
||||
'headers' => [
|
||||
'poweredByHeader' => true,
|
||||
'referrerPolicy' => 'same-origin',
|
||||
]
|
||||
];
|
||||
@@ -67,7 +67,7 @@ class StoreConfig implements ReversibleStep
|
||||
private function getPathsConfig()
|
||||
{
|
||||
return [
|
||||
'api' => 'api',
|
||||
'api' => 'api',
|
||||
'admin' => 'admin',
|
||||
];
|
||||
}
|
||||
|
@@ -24,40 +24,33 @@ interface BlueprintInterface
|
||||
*
|
||||
* @return User|null
|
||||
*/
|
||||
public function getFromUser(): ?User;
|
||||
public function getFromUser();
|
||||
|
||||
/**
|
||||
* Get the model that is the subject of this activity.
|
||||
*
|
||||
* @return AbstractModel|null
|
||||
*/
|
||||
public function getSubject(): ?AbstractModel;
|
||||
public function getSubject();
|
||||
|
||||
/**
|
||||
* Get the data to be stored in the notification.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getData(): mixed;
|
||||
public function getData();
|
||||
|
||||
/**
|
||||
* Get the serialized type of this activity.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getType(): string;
|
||||
public static function getType();
|
||||
|
||||
/**
|
||||
* Get the name of the model class for the subject of this activity.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getSubjectModel(): string;
|
||||
|
||||
/**
|
||||
* Whether the blueprint ignores that a user has not verified their email address.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ignoresUserVerification(): bool;
|
||||
public static function getSubjectModel();
|
||||
}
|
||||
|
@@ -9,7 +9,6 @@
|
||||
|
||||
namespace Flarum\Queue;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Debug\ExceptionHandler as ExceptionHandling;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Throwable;
|
||||
|
@@ -39,4 +39,15 @@ class UserPolicy extends AbstractPolicy
|
||||
return $this->allow();
|
||||
}
|
||||
}
|
||||
|
||||
public function uploadAvatar(User $actor, User $user)
|
||||
{
|
||||
if ($actor->id === $user->id) {
|
||||
return $this->allow();
|
||||
}
|
||||
|
||||
if ($actor->id !== $user->id) {
|
||||
return $actor->can('edit', $user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -68,9 +68,7 @@ class UploadAvatarHandler
|
||||
|
||||
$user = $this->users->findOrFail($command->userId);
|
||||
|
||||
if ($actor->id !== $user->id) {
|
||||
$actor->assertCan('edit', $user);
|
||||
}
|
||||
$actor->assertCan('uploadAvatar', $user);
|
||||
|
||||
$this->validator->assertValid(['avatar' => $command->file]);
|
||||
|
||||
|
@@ -186,7 +186,7 @@ class CreateTest extends TestCase
|
||||
'username' => 'test',
|
||||
'email' => 'test@machine.local',
|
||||
'is_email_confirmed' => 1,
|
||||
'avatar_url' => 'file://localhost/etc/passwd'
|
||||
'avatar_url' => 'file://localhost/etc/passwd'
|
||||
], []),
|
||||
'scheme' => 'file'
|
||||
];
|
||||
@@ -251,28 +251,28 @@ class CreateTest extends TestCase
|
||||
'username' => 'test',
|
||||
'email' => 'test@machine.local',
|
||||
'is_email_confirmed' => 1,
|
||||
'avatar_url' => 'https://127.0.0.1/image.png'
|
||||
'avatar_url' => 'https://127.0.0.1/image.png'
|
||||
], []);
|
||||
|
||||
$regTokens[] = RegistrationToken::generate('flarum', '1', [
|
||||
'username' => 'test',
|
||||
'email' => 'test@machine.local',
|
||||
'is_email_confirmed' => 1,
|
||||
'avatar_url' => 'https://192.168.0.1/image.png'
|
||||
'avatar_url' => 'https://192.168.0.1/image.png'
|
||||
], []);
|
||||
|
||||
$regTokens[] = RegistrationToken::generate('flarum', '1', [
|
||||
'username' => 'test',
|
||||
'email' => 'test@machine.local',
|
||||
'is_email_confirmed' => 1,
|
||||
'avatar_url' => '../image.png'
|
||||
'avatar_url' => '../image.png'
|
||||
], []);
|
||||
|
||||
$regTokens[] = RegistrationToken::generate('flarum', '1', [
|
||||
'username' => 'test',
|
||||
'email' => 'test@machine.local',
|
||||
'is_email_confirmed' => 1,
|
||||
'avatar_url' => 'image.png'
|
||||
'avatar_url' => 'image.png'
|
||||
], []);
|
||||
|
||||
// Test each reg token
|
||||
@@ -325,28 +325,28 @@ class CreateTest extends TestCase
|
||||
'username' => 'test1',
|
||||
'email' => 'test1@machine.local',
|
||||
'is_email_confirmed' => 1,
|
||||
'avatar_url' => 'https://raw.githubusercontent.com/flarum/framework/main/framework/core/tests/fixtures/assets/avatar.png'
|
||||
'avatar_url' => 'https://raw.githubusercontent.com/flarum/framework/main/framework/core/tests/fixtures/assets/avatar.png'
|
||||
], []);
|
||||
|
||||
$regTokens[] = RegistrationToken::generate('flarum', '2', [
|
||||
'username' => 'test2',
|
||||
'email' => 'test2@machine.local',
|
||||
'is_email_confirmed' => 1,
|
||||
'avatar_url' => 'https://raw.githubusercontent.com/flarum/framework/main/framework/core/tests/fixtures/assets/avatar.jpg'
|
||||
'avatar_url' => 'https://raw.githubusercontent.com/flarum/framework/main/framework/core/tests/fixtures/assets/avatar.jpg'
|
||||
], []);
|
||||
|
||||
$regTokens[] = RegistrationToken::generate('flarum', '3', [
|
||||
'username' => 'test3',
|
||||
'email' => 'test3@machine.local',
|
||||
'is_email_confirmed' => 1,
|
||||
'avatar_url' => 'https://raw.githubusercontent.com/flarum/framework/main/framework/core/tests/fixtures/assets/avatar.gif'
|
||||
'avatar_url' => 'https://raw.githubusercontent.com/flarum/framework/main/framework/core/tests/fixtures/assets/avatar.gif'
|
||||
], []);
|
||||
|
||||
$regTokens[] = RegistrationToken::generate('flarum', '4', [
|
||||
'username' => 'test4',
|
||||
'email' => 'test4@machine.local',
|
||||
'is_email_confirmed' => 1,
|
||||
'avatar_url' => 'http://raw.githubusercontent.com/flarum/framework/main/framework/core/tests/fixtures/assets/avatar.png'
|
||||
'avatar_url' => 'http://raw.githubusercontent.com/flarum/framework/main/framework/core/tests/fixtures/assets/avatar.png'
|
||||
], []);
|
||||
|
||||
/**
|
||||
|
@@ -45,7 +45,7 @@ class FilesystemTest extends TestCase
|
||||
$this->extend((new Extend\Filesystem)->disk('flarum-uploads', function (Paths $paths, UrlGenerator $url) {
|
||||
return [
|
||||
'root' => "$paths->public/assets/uploads",
|
||||
'url' => $url->to('forum')->path('assets/uploads')
|
||||
'url' => $url->to('forum')->path('assets/uploads')
|
||||
];
|
||||
}));
|
||||
|
||||
@@ -137,7 +137,7 @@ class UploadsDisk
|
||||
{
|
||||
return [
|
||||
'root' => "$paths->public/assets/uploads",
|
||||
'url' => $url->to('forum')->path('assets/uploads')
|
||||
'url' => $url->to('forum')->path('assets/uploads')
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -192,7 +192,6 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase
|
||||
protected function database(): ConnectionInterface
|
||||
{
|
||||
$this->app();
|
||||
|
||||
// Set in `BeginTransactionAndSetDatabase` extender.
|
||||
return $this->database;
|
||||
}
|
||||
|
Reference in New Issue
Block a user