diff options
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/api/endpoints/drive/files/create.ts | 10 | ||||
| -rw-r--r-- | src/server/api/endpoints/i/2fa/password-less.ts | 21 | ||||
| -rw-r--r-- | src/server/api/endpoints/i/update.ts | 27 | ||||
| -rw-r--r-- | src/server/api/endpoints/page-push.ts | 49 | ||||
| -rw-r--r-- | src/server/api/endpoints/pages/create.ts | 6 | ||||
| -rw-r--r-- | src/server/api/endpoints/pages/update.ts | 5 | ||||
| -rw-r--r-- | src/server/api/private/signin.ts | 37 |
7 files changed, 143 insertions, 12 deletions
diff --git a/src/server/api/endpoints/drive/files/create.ts b/src/server/api/endpoints/drive/files/create.ts index 664a2b87b2..61055c5d18 100644 --- a/src/server/api/endpoints/drive/files/create.ts +++ b/src/server/api/endpoints/drive/files/create.ts @@ -35,6 +35,14 @@ export const meta = { } }, + name: { + validator: $.optional.nullable.str, + default: null as any, + desc: { + 'ja-JP': 'ファイル名(拡張子があるなら含めて)' + } + }, + isSensitive: { validator: $.optional.either($.bool, $.str), default: false, @@ -72,7 +80,7 @@ export const meta = { export default define(meta, async (ps, user, app, file, cleanup) => { // Get 'name' parameter - let name = file.originalname; + let name = ps.name || file.originalname; if (name !== undefined && name !== null) { name = name.trim(); if (name.length === 0) { diff --git a/src/server/api/endpoints/i/2fa/password-less.ts b/src/server/api/endpoints/i/2fa/password-less.ts new file mode 100644 index 0000000000..19e75ca1c5 --- /dev/null +++ b/src/server/api/endpoints/i/2fa/password-less.ts @@ -0,0 +1,21 @@ +import $ from 'cafy'; +import define from '../../../define'; +import { UserProfiles } from '../../../../../models'; + +export const meta = { + requireCredential: true, + + secure: true, + + params: { + value: { + validator: $.boolean + } + } +}; + +export default define(meta, async (ps, user) => { + await UserProfiles.update(user.id, { + usePasswordLessLogin: ps.value + }); +}); diff --git a/src/server/api/endpoints/i/update.ts b/src/server/api/endpoints/i/update.ts index 10521d12d8..a454cdb940 100644 --- a/src/server/api/endpoints/i/update.ts +++ b/src/server/api/endpoints/i/update.ts @@ -10,7 +10,7 @@ import extractHashtags from '../../../../misc/extract-hashtags'; import * as langmap from 'langmap'; import { updateHashtag } from '../../../../services/update-hashtag'; import { ApiError } from '../../error'; -import { Users, DriveFiles, UserProfiles } from '../../../../models'; +import { Users, DriveFiles, UserProfiles, Pages } from '../../../../models'; import { User } from '../../../../models/entities/user'; import { UserProfile } from '../../../../models/entities/user-profile'; import { ensure } from '../../../../prelude/ensure'; @@ -125,6 +125,13 @@ export const meta = { 'ja-JP': 'アップロードするメディアをデフォルトで「閲覧注意」として設定するか' } }, + + pinnedPageId: { + validator: $.optional.nullable.type(ID), + desc: { + 'ja-JP': 'ピン留めするページID' + } + } }, errors: { @@ -150,7 +157,13 @@ export const meta = { message: 'The file specified as a banner is not an image.', code: 'BANNER_NOT_AN_IMAGE', id: '75aedb19-2afd-4e6d-87fc-67941256fa60' - } + }, + + noSuchPage: { + message: 'No such page.', + code: 'NO_SUCH_PAGE', + id: '8e01b590-7eb9-431b-a239-860e086c408e' + }, } }; @@ -203,6 +216,16 @@ export default define(meta, async (ps, user, app) => { } } + if (ps.pinnedPageId) { + const page = await Pages.findOne(ps.pinnedPageId); + + if (page == null || page.userId !== user.id) throw new ApiError(meta.errors.noSuchPage); + + profileUpdates.pinnedPageId = page.id; + } else if (ps.pinnedPageId === null) { + profileUpdates.pinnedPageId = null; + } + //#region emojis/tags let emojis = [] as string[]; diff --git a/src/server/api/endpoints/page-push.ts b/src/server/api/endpoints/page-push.ts new file mode 100644 index 0000000000..f5e1a4d1eb --- /dev/null +++ b/src/server/api/endpoints/page-push.ts @@ -0,0 +1,49 @@ +import $ from 'cafy'; +import define from '../define'; +import { ID } from '../../../misc/cafy-id'; +import { publishMainStream } from '../../../services/stream'; +import { Users, Pages } from '../../../models'; +import { ApiError } from '../error'; + +export const meta = { + requireCredential: true, + secure: true, + + params: { + pageId: { + validator: $.type(ID) + }, + + event: { + validator: $.str + }, + + var: { + validator: $.optional.nullable.any + } + }, + + errors: { + noSuchPage: { + message: 'No such page.', + code: 'NO_SUCH_PAGE', + id: '4a13ad31-6729-46b4-b9af-e86b265c2e74' + } + } +}; + +export default define(meta, async (ps, user) => { + const page = await Pages.findOne(ps.pageId); + if (page == null) { + throw new ApiError(meta.errors.noSuchPage); + } + + publishMainStream(user.id, 'pageEvent', { + pageId: ps.pageId, + event: ps.event, + var: ps.var, + user: await Users.pack(user, page.userId, { + detail: true + }) + }); +}); diff --git a/src/server/api/endpoints/pages/create.ts b/src/server/api/endpoints/pages/create.ts index ffe0d38ea6..a49a5d37b8 100644 --- a/src/server/api/endpoints/pages/create.ts +++ b/src/server/api/endpoints/pages/create.ts @@ -57,6 +57,11 @@ export const meta = { validator: $.optional.bool, default: false }, + + hideTitleWhenPinned: { + validator: $.optional.bool, + default: false + }, }, res: { @@ -100,6 +105,7 @@ export default define(meta, async (ps, user) => { userId: user.id, visibility: 'public', alignCenter: ps.alignCenter, + hideTitleWhenPinned: ps.hideTitleWhenPinned, font: ps.font })); diff --git a/src/server/api/endpoints/pages/update.ts b/src/server/api/endpoints/pages/update.ts index 8ee34fc3ba..9daf5e9cae 100644 --- a/src/server/api/endpoints/pages/update.ts +++ b/src/server/api/endpoints/pages/update.ts @@ -61,6 +61,10 @@ export const meta = { alignCenter: { validator: $.optional.bool, }, + + hideTitleWhenPinned: { + validator: $.optional.bool, + }, }, errors: { @@ -113,6 +117,7 @@ export default define(meta, async (ps, user) => { content: ps.content, variables: ps.variables, alignCenter: ps.alignCenter === undefined ? page.alignCenter : ps.alignCenter, + hideTitleWhenPinned: ps.hideTitleWhenPinned === undefined ? page.hideTitleWhenPinned : ps.hideTitleWhenPinned, font: ps.font === undefined ? page.font : ps.font, eyeCatchingImageId: ps.eyeCatchingImageId === null ? null diff --git a/src/server/api/private/signin.ts b/src/server/api/private/signin.ts index bc9346d088..eb267aa604 100644 --- a/src/server/api/private/signin.ts +++ b/src/server/api/private/signin.ts @@ -72,19 +72,25 @@ export default async (ctx: Koa.BaseContext) => { } } - if (!same) { - await fail(403, { - error: 'incorrect password' - }); - return; - } - if (!profile.twoFactorEnabled) { - signin(ctx, user); + if (same) { + signin(ctx, user); + } else { + await fail(403, { + error: 'incorrect password' + }); + } return; } if (token) { + if (!same) { + await fail(403, { + error: 'incorrect password' + }); + return; + } + const verified = (speakeasy as any).totp.verify({ secret: profile.twoFactorSecret, encoding: 'base32', @@ -101,6 +107,13 @@ export default async (ctx: Koa.BaseContext) => { return; } } else if (body.credentialId) { + if (!same && !profile.usePasswordLessLogin) { + await fail(403, { + error: 'incorrect password' + }); + return; + } + const clientDataJSON = Buffer.from(body.clientDataJSON, 'hex'); const clientData = JSON.parse(clientDataJSON.toString('utf-8')); const challenge = await AttestationChallenges.findOne({ @@ -163,6 +176,13 @@ export default async (ctx: Koa.BaseContext) => { return; } } else { + if (!same && !profile.usePasswordLessLogin) { + await fail(403, { + error: 'incorrect password' + }); + return; + } + const keys = await UserSecurityKeys.find({ userId: user.id }); @@ -201,5 +221,4 @@ export default async (ctx: Koa.BaseContext) => { } await fail(); - return; }; |