core: add avatar validation

This commit is contained in:
undefined committed 2023-01-29 11:06:16 +08:00
1 parent 5f995f97ad
commit 149c3671f7
2 files changed
+19 -5

No files matched your search

+5 -3
View File
@@ -10,7 +10,7 @@ import {
UserNotFoundError, ValidationError, VerifyPasswordError, UserNotFoundError, ValidationError, VerifyPasswordError,
} from '../error'; } from '../error';
import { DomainDoc, MessageDoc, Setting } from '../interface'; import { DomainDoc, MessageDoc, Setting } from '../interface';
import avatar from '../lib/avatar'; import avatar, { validate } from '../lib/avatar';
import * as mail from '../lib/mail'; import * as mail from '../lib/mail';
import * as useragent from '../lib/useragent'; import * as useragent from '../lib/useragent';
import { verifyTFA } from '../lib/verifyTFA'; import { verifyTFA } from '../lib/verifyTFA';
@@ -373,8 +373,10 @@ class HomeSettingsHandler extends Handler {
class HomeAvatarHandler extends Handler { class HomeAvatarHandler extends Handler {
@param('avatar', Types.String, true) @param('avatar', Types.String, true)
async post(domainId: string, input: string) { async post(domainId: string, input: string) {
if (input) await user.setById(this.user._id, { avatar: input }); if (input) {
else if (this.request.files.file) { if (!validate(input)) throw new ValidationError('avatar');
await user.setById(this.user._id, { avatar: input });
} else if (this.request.files.file) {
const file = this.request.files.file; const file = this.request.files.file;
if (file.size > 8 * 1024 * 1024) throw new ValidationError('file'); if (file.size > 8 * 1024 * 1024) throw new ValidationError('file');
const ext = path.extname(file.originalFilename); const ext = path.extname(file.originalFilename);
+14 -2
View File
@@ -1,3 +1,4 @@
import { Types } from '../service/decorators';
import { md5 } from '../utils'; import { md5 } from '../utils';
type AvatarProvider = (src: string, size: number) => string; type AvatarProvider = (src: string, size: number) => string;
@@ -13,13 +14,24 @@ export const providers: Record<string, AvatarProvider> = {
function avatar(src: string, size = 64, fallback = '') { function avatar(src: string, size = 64, fallback = '') {
src ||= fallback; src ||= fallback;
let index = src.indexOf(':'); let index = src.indexOf(':');
if (index === -1) src = fallback; if (index === -1 && fallback) {
src = fallback;
index = src.indexOf(':'); index = src.indexOf(':');
}
if (index === -1) return providers.gravatar('', size); if (index === -1) return providers.gravatar('', size);
const [provider, str] = [src.substr(0, index), src.substr(index + 1, src.length)]; const [provider, str] = [src.substring(0, index), src.substring(index + 1, src.length)];
if (!providers[provider] || !str) return providers.gravatar('', size); if (!providers[provider] || !str) return providers.gravatar('', size);
return providers[provider](str, size); return providers[provider](str, size);
} }
export function validate(input: string) {
if (!input) return true;
if (input.startsWith('url:')) return true;
if (input.startsWith('github:')) return /^[a-zA-Z0-9-]+$/.test(input.substring(7, input.length));
if (input.startsWith('qq:')) return /^[1-9]\d{4,}$/.test(input.substring(3));
if (input.startsWith('gravatar:')) return Types.Email[1](input.substring(9));
return false;
}
export default avatar; export default avatar;
global.Hydro.lib.avatar = avatar; global.Hydro.lib.avatar = avatar;