deny anonymous image upload

This commit is contained in:
Vyrtsev Mikhail
2019-04-20 18:54:21 +03:00
parent 1dd97d42a1
commit 34772fa1b6
5 changed files with 65 additions and 26 deletions
+5 -3
View File
@@ -13,6 +13,7 @@ import debounce from '@app/utils/debounce';
import copy from '@app/common/copy';
import { Theme, BlockTTL, Comment as CommentType, PostInfo, User, CommentMode, Image } from '@app/common/types';
import { extractErrorMessageFromResponse, FetcherError } from '@app/utils/errorUtils';
import { isUserAnonymous } from '@app/utils/isUserAnonymous';
import { Input } from '@app/components/input';
import { AvatarIcon } from '@app/components/avatar-icon';
@@ -315,7 +316,7 @@ export class Comment extends Component<Props, State> {
* Defines whether current client is logged in via `Anonymous provider`
*/
isAnonymous(): boolean {
return this.props.user! && this.props.user!.id.substr(0, 10) === 'anonymous_';
return isUserAnonymous(this.props.user);
}
/**
@@ -369,6 +370,7 @@ export class Comment extends Component<Props, State> {
const isUpvotingDisabled = upvotingDisabledReason !== null;
const editable = props.repliesCount === 0 && state.editDeadline;
const scoreSignEnabled = !StaticStore.config.positive_score;
const uploadImageHandler = this.isAnonymous() ? undefined : this.props.uploadImage;
/**
* CommentType adapted for rendering
@@ -676,7 +678,7 @@ export class Comment extends Component<Props, State> {
onCancel={this.toggleReplying}
getPreview={this.props.getPreview!}
autofocus={true}
uploadImage={this.props.uploadImage!}
uploadImage={uploadImageHandler}
/>
)}
@@ -691,7 +693,7 @@ export class Comment extends Component<Props, State> {
getPreview={this.props.getPreview!}
errorMessage={state.editDeadline === null ? 'Editing time has expired.' : undefined}
autofocus={true}
uploadImage={this.props.uploadImage!}
uploadImage={uploadImageHandler}
/>
)}
</article>
+12 -11
View File
@@ -38,7 +38,7 @@ interface Props {
getPreview(text: string): Promise<string>;
/** action on cancel. optional as root input has no cancel option */
onCancel?: () => void;
uploadImage: (image: File) => Promise<Image>;
uploadImage?: (image: File) => Promise<Image>;
}
interface State {
@@ -194,6 +194,7 @@ export class Input extends Component<Props, State> {
}
onDragOver(e: DragEvent) {
if (!this.props.uploadImage) return;
if (StaticStore.config.max_image_size === 0) return;
if (!this.textAreaRef) return;
if (!e.dataTransfer) return;
@@ -204,6 +205,7 @@ export class Input extends Component<Props, State> {
}
onDrop(e: DragEvent) {
if (!this.props.uploadImage) return;
if (StaticStore.config.max_image_size === 0) return;
if (!e.dataTransfer) return;
@@ -217,20 +219,19 @@ export class Input extends Component<Props, State> {
/** wrapper with error handling for props.uploadImage */
uploadImage(file: File): Promise<Image | Error> {
return this.props
.uploadImage(file)
.catch(
(e: ApiError | string) =>
new Error(
typeof e === 'string'
? `${file.name} upload failed with "${e}"`
: `${file.name} upload failed with "${e.error}"`
)
);
return this.props.uploadImage!(file).catch(
(e: ApiError | string) =>
new Error(
typeof e === 'string'
? `${file.name} upload failed with "${e}"`
: `${file.name} upload failed with "${e.error}"`
)
);
}
/** performs upload process */
async uploadImages(files: File[]) {
if (!this.props.uploadImage) return;
if (!this.textAreaRef) return;
/** Human readable image size limit, i.e 5MB */
+10 -1
View File
@@ -49,6 +49,7 @@ import { Input } from '@app/components/input';
import Preloader from '@app/components/preloader';
import { Thread } from '@app/components/thread';
import { uploadImage } from '@app/common/api';
import { isUserAnonymous } from '@app/utils/isUserAnonymous';
interface Props {
user: User | null;
@@ -192,6 +193,13 @@ export class Root extends Component<Props, State> {
});
}
/**
* Defines whether current client is logged in via `Anonymous provider`
*/
isAnonymous(): boolean {
return isUserAnonymous(this.props.user);
}
render(props: RenderableProps<Props>, { isLoaded, isCommentsListLoading, commentsShown }: State) {
if (!isLoaded) {
return (
@@ -205,6 +213,7 @@ export class Root extends Component<Props, State> {
const isGuest = !props.user;
const isCommentsDisabled = !!props.info.read_only;
const imageUploadHandler = this.isAnonymous() ? undefined : this.props.uploadImage;
return (
<div id={NODE_ID}>
@@ -235,7 +244,7 @@ export class Root extends Component<Props, State> {
userId={this.props.user!.id}
onSubmit={(text, title) => this.props.addComment(text, title)}
getPreview={this.props.getPreview}
uploadImage={this.props.uploadImage}
uploadImage={imageUploadHandler}
/>
)}
+8
View File
@@ -0,0 +1,8 @@
import { User } from '@app/common/types';
/**
* Defines whether current client is logged in via `Anonymous provider`
*/
export function isUserAnonymous(user?: User | null): boolean {
return user! && user!.id.substr(0, 10) === 'anonymous_';
}
+30 -11
View File
@@ -4854,7 +4854,8 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"aproba": {
"version": "1.2.0",
@@ -4875,12 +4876,14 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -4895,17 +4898,20 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"core-util-is": {
"version": "1.0.2",
@@ -5022,7 +5028,8 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"ini": {
"version": "1.3.5",
@@ -5034,6 +5041,7 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -5048,6 +5056,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -5055,12 +5064,14 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -5079,6 +5090,7 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -5159,7 +5171,8 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
@@ -5171,6 +5184,7 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@@ -5256,7 +5270,8 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -5292,6 +5307,7 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -5311,6 +5327,7 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -5354,12 +5371,14 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
"dev": true
"dev": true,
"optional": true
}
}
},