fix for lint
This commit is contained in:
		
							parent
							
								
									01afdc410e
								
							
						
					
					
						commit
						8b7f5be878
					
				| 
						 | 
					@ -82,8 +82,7 @@ export default class Reversi {
 | 
				
			||||||
		//#endregion
 | 
							//#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// ゲームが始まった時点で片方の色の石しかないか、始まった時点で勝敗が決定するようなマップの場合がある
 | 
							// ゲームが始まった時点で片方の色の石しかないか、始まった時点で勝敗が決定するようなマップの場合がある
 | 
				
			||||||
		if (!this.canPutSomewhere(BLACK))
 | 
							if (!this.canPutSomewhere(BLACK)) this.turn = this.canPutSomewhere(WHITE) ? WHITE : null;
 | 
				
			||||||
			this.turn = this.canPutSomewhere(WHITE) ? WHITE : null;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
| 
						 | 
					@ -226,11 +225,12 @@ export default class Reversi {
 | 
				
			||||||
				// 座標が指し示す位置がボード外に出たとき
 | 
									// 座標が指し示す位置がボード外に出たとき
 | 
				
			||||||
				if (this.opts.loopedBoard && this.transformXyToPos(
 | 
									if (this.opts.loopedBoard && this.transformXyToPos(
 | 
				
			||||||
					(x = ((x % this.mapWidth) + this.mapWidth) % this.mapWidth),
 | 
										(x = ((x % this.mapWidth) + this.mapWidth) % this.mapWidth),
 | 
				
			||||||
					(y = ((y % this.mapHeight) + this.mapHeight) % this.mapHeight)) === initPos)
 | 
										(y = ((y % this.mapHeight) + this.mapHeight) % this.mapHeight)) === initPos) {
 | 
				
			||||||
						// 盤面の境界でループし、自分が石を置く位置に戻ってきたとき、挟めるようにしている (ref: Test4のマップ)
 | 
											// 盤面の境界でループし、自分が石を置く位置に戻ってきたとき、挟めるようにしている (ref: Test4のマップ)
 | 
				
			||||||
					return found;
 | 
										return found;
 | 
				
			||||||
				else if (x === -1 || y === -1 || x === this.mapWidth || y === this.mapHeight)
 | 
									} else if (x === -1 || y === -1 || x === this.mapWidth || y === this.mapHeight) {
 | 
				
			||||||
					return []; // 挟めないことが確定 (盤面外に到達)
 | 
										return []; // 挟めないことが確定 (盤面外に到達)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				const pos = this.transformXyToPos(x, y);
 | 
									const pos = this.transformXyToPos(x, y);
 | 
				
			||||||
				if (this.mapDataGet(pos) === 'null') return []; // 挟めないことが確定 (配置不可能なマスに到達)
 | 
									if (this.mapDataGet(pos) === 'null') return []; // 挟めないことが確定 (配置不可能なマスに到達)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,7 +54,7 @@ export async function populateEmoji(emojiName: string, noteUserHost: string | nu
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const queryOrNull = async () => (await Emojis.findOne({
 | 
						const queryOrNull = async () => (await Emojis.findOne({
 | 
				
			||||||
		name,
 | 
							name,
 | 
				
			||||||
		host
 | 
							host,
 | 
				
			||||||
	})) || null;
 | 
						})) || null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const emoji = await cache.fetch(`${name} ${host}`, queryOrNull);
 | 
						const emoji = await cache.fetch(`${name} ${host}`, queryOrNull);
 | 
				
			||||||
| 
						 | 
					@ -62,7 +62,7 @@ export async function populateEmoji(emojiName: string, noteUserHost: string | nu
 | 
				
			||||||
	if (emoji == null) return null;
 | 
						if (emoji == null) return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const isLocal = emoji.host == null;
 | 
						const isLocal = emoji.host == null;
 | 
				
			||||||
	const url = isLocal ? emoji.url : `${config.url}/proxy/image.png?${query({url: emoji.url})}`;
 | 
						const url = isLocal ? emoji.url : `${config.url}/proxy/image.png?${query({ url: emoji.url })}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return {
 | 
						return {
 | 
				
			||||||
		name: emojiName,
 | 
							name: emojiName,
 | 
				
			||||||
| 
						 | 
					@ -111,12 +111,12 @@ export async function prefetchEmojis(emojis: { name: string; host: string | null
 | 
				
			||||||
	for (const host of hosts) {
 | 
						for (const host of hosts) {
 | 
				
			||||||
		emojisQuery.push({
 | 
							emojisQuery.push({
 | 
				
			||||||
			name: In(notCachedEmojis.filter(e => e.host === host).map(e => e.name)),
 | 
								name: In(notCachedEmojis.filter(e => e.host === host).map(e => e.name)),
 | 
				
			||||||
			host: host
 | 
								host: host,
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	const _emojis = emojisQuery.length > 0 ? await Emojis.find({
 | 
						const _emojis = emojisQuery.length > 0 ? await Emojis.find({
 | 
				
			||||||
		where: emojisQuery,
 | 
							where: emojisQuery,
 | 
				
			||||||
		select: ['name', 'host', 'url']
 | 
							select: ['name', 'host', 'url'],
 | 
				
			||||||
	}) : [];
 | 
						}) : [];
 | 
				
			||||||
	for (const emoji of _emojis) {
 | 
						for (const emoji of _emojis) {
 | 
				
			||||||
		cache.set(`${emoji.name} ${emoji.host}`, emoji);
 | 
							cache.set(`${emoji.name} ${emoji.host}`, emoji);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,4 @@
 | 
				
			||||||
 | 
					/* eslint-disable key-spacing */
 | 
				
			||||||
import { emojiRegex } from './emoji-regex';
 | 
					import { emojiRegex } from './emoji-regex';
 | 
				
			||||||
import { fetchMeta } from './fetch-meta';
 | 
					import { fetchMeta } from './fetch-meta';
 | 
				
			||||||
import { Emojis } from '@/models/index';
 | 
					import { Emojis } from '@/models/index';
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,7 +19,7 @@ export function createSignedPost(args: { key: PrivateKey, url: string, body: str
 | 
				
			||||||
	const request: Request = {
 | 
						const request: Request = {
 | 
				
			||||||
		url: u.href,
 | 
							url: u.href,
 | 
				
			||||||
		method: 'POST',
 | 
							method: 'POST',
 | 
				
			||||||
		headers:  objectAssignWithLcKey({
 | 
							headers: objectAssignWithLcKey({
 | 
				
			||||||
			'Date': new Date().toUTCString(),
 | 
								'Date': new Date().toUTCString(),
 | 
				
			||||||
			'Host': u.hostname,
 | 
								'Host': u.hostname,
 | 
				
			||||||
			'Content-Type': 'application/activity+json',
 | 
								'Content-Type': 'application/activity+json',
 | 
				
			||||||
| 
						 | 
					@ -43,7 +43,7 @@ export function createSignedGet(args: { key: PrivateKey, url: string, additional
 | 
				
			||||||
	const request: Request = {
 | 
						const request: Request = {
 | 
				
			||||||
		url: u.href,
 | 
							url: u.href,
 | 
				
			||||||
		method: 'GET',
 | 
							method: 'GET',
 | 
				
			||||||
		headers:  objectAssignWithLcKey({
 | 
							headers: objectAssignWithLcKey({
 | 
				
			||||||
			'Accept': 'application/activity+json, application/ld+json',
 | 
								'Accept': 'application/activity+json, application/ld+json',
 | 
				
			||||||
			'Date': new Date().toUTCString(),
 | 
								'Date': new Date().toUTCString(),
 | 
				
			||||||
			'Host': new URL(args.url).hostname,
 | 
								'Host': new URL(args.url).hostname,
 | 
				
			||||||
| 
						 | 
					@ -66,7 +66,7 @@ function signToRequest(request: Request, key: PrivateKey, includeHeaders: string
 | 
				
			||||||
	const signatureHeader = `keyId="${key.keyId}",algorithm="rsa-sha256",headers="${includeHeaders.join(' ')}",signature="${signature}"`;
 | 
						const signatureHeader = `keyId="${key.keyId}",algorithm="rsa-sha256",headers="${includeHeaders.join(' ')}",signature="${signature}"`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	request.headers = objectAssignWithLcKey(request.headers, {
 | 
						request.headers = objectAssignWithLcKey(request.headers, {
 | 
				
			||||||
		Signature: signatureHeader
 | 
							Signature: signatureHeader,
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return {
 | 
						return {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
					@ -163,7 +163,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
 | 
				
			||||||
				uri: person.id,
 | 
									uri: person.id,
 | 
				
			||||||
				tags,
 | 
									tags,
 | 
				
			||||||
				isBot,
 | 
									isBot,
 | 
				
			||||||
				isCat: (person as any).isCat === true
 | 
									isCat: (person as any).isCat === true,
 | 
				
			||||||
			})) as IRemoteUser;
 | 
								})) as IRemoteUser;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			await transactionalEntityManager.save(new UserProfile({
 | 
								await transactionalEntityManager.save(new UserProfile({
 | 
				
			||||||
| 
						 | 
					@ -173,14 +173,14 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
 | 
				
			||||||
				fields,
 | 
									fields,
 | 
				
			||||||
				birthday: bday ? bday[0] : null,
 | 
									birthday: bday ? bday[0] : null,
 | 
				
			||||||
				location: person['vcard:Address'] || null,
 | 
									location: person['vcard:Address'] || null,
 | 
				
			||||||
				userHost: host
 | 
									userHost: host,
 | 
				
			||||||
			}));
 | 
								}));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (person.publicKey) {
 | 
								if (person.publicKey) {
 | 
				
			||||||
				await transactionalEntityManager.save(new UserPublickey({
 | 
									await transactionalEntityManager.save(new UserPublickey({
 | 
				
			||||||
					userId: user.id,
 | 
										userId: user.id,
 | 
				
			||||||
					keyId: person.publicKey.id,
 | 
										keyId: person.publicKey.id,
 | 
				
			||||||
					keyPem: person.publicKey.publicKeyPem
 | 
										keyPem: person.publicKey.publicKeyPem,
 | 
				
			||||||
				}));
 | 
									}));
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
| 
						 | 
					@ -189,7 +189,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
 | 
				
			||||||
		if (isDuplicateKeyValueError(e)) {
 | 
							if (isDuplicateKeyValueError(e)) {
 | 
				
			||||||
			// /users/@a => /users/:id のように入力がaliasなときにエラーになることがあるのを対応
 | 
								// /users/@a => /users/:id のように入力がaliasなときにエラーになることがあるのを対応
 | 
				
			||||||
			const u = await Users.findOne({
 | 
								const u = await Users.findOne({
 | 
				
			||||||
				uri: person.id
 | 
									uri: person.id,
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (u) {
 | 
								if (u) {
 | 
				
			||||||
| 
						 | 
					@ -218,11 +218,11 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
 | 
				
			||||||
	//#region アバターとヘッダー画像をフェッチ
 | 
						//#region アバターとヘッダー画像をフェッチ
 | 
				
			||||||
	const [avatar, banner] = await Promise.all([
 | 
						const [avatar, banner] = await Promise.all([
 | 
				
			||||||
		person.icon,
 | 
							person.icon,
 | 
				
			||||||
		person.image
 | 
							person.image,
 | 
				
			||||||
	].map(img =>
 | 
						].map(img =>
 | 
				
			||||||
		img == null
 | 
							img == null
 | 
				
			||||||
			? Promise.resolve(null)
 | 
								? Promise.resolve(null)
 | 
				
			||||||
			: resolveImage(user!, img).catch(() => null)
 | 
								: resolveImage(user!, img).catch(() => null),
 | 
				
			||||||
	));
 | 
						));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const avatarId = avatar ? avatar.id : null;
 | 
						const avatarId = avatar ? avatar.id : null;
 | 
				
			||||||
| 
						 | 
					@ -258,7 +258,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
 | 
				
			||||||
	const emojiNames = emojis.map(emoji => emoji.name);
 | 
						const emojiNames = emojis.map(emoji => emoji.name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	await Users.update(user!.id, {
 | 
						await Users.update(user!.id, {
 | 
				
			||||||
		emojis: emojiNames
 | 
							emojis: emojiNames,
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
	//#endregion
 | 
						//#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -301,11 +301,11 @@ export async function updatePerson(uri: string, resolver?: Resolver | null, hint
 | 
				
			||||||
	// アバターとヘッダー画像をフェッチ
 | 
						// アバターとヘッダー画像をフェッチ
 | 
				
			||||||
	const [avatar, banner] = await Promise.all([
 | 
						const [avatar, banner] = await Promise.all([
 | 
				
			||||||
		person.icon,
 | 
							person.icon,
 | 
				
			||||||
		person.image
 | 
							person.image,
 | 
				
			||||||
	].map(img =>
 | 
						].map(img =>
 | 
				
			||||||
		img == null
 | 
							img == null
 | 
				
			||||||
			? Promise.resolve(null)
 | 
								? Promise.resolve(null)
 | 
				
			||||||
			: resolveImage(exist, img).catch(() => null)
 | 
								: resolveImage(exist, img).catch(() => null),
 | 
				
			||||||
	));
 | 
						));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// カスタム絵文字取得
 | 
						// カスタム絵文字取得
 | 
				
			||||||
| 
						 | 
					@ -355,7 +355,7 @@ export async function updatePerson(uri: string, resolver?: Resolver | null, hint
 | 
				
			||||||
	if (person.publicKey) {
 | 
						if (person.publicKey) {
 | 
				
			||||||
		await UserPublickeys.update({ userId: exist.id }, {
 | 
							await UserPublickeys.update({ userId: exist.id }, {
 | 
				
			||||||
			keyId: person.publicKey.id,
 | 
								keyId: person.publicKey.id,
 | 
				
			||||||
			keyPem: person.publicKey.publicKeyPem
 | 
								keyPem: person.publicKey.publicKeyPem,
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -372,9 +372,9 @@ export async function updatePerson(uri: string, resolver?: Resolver | null, hint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 該当ユーザーが既にフォロワーになっていた場合はFollowingもアップデートする
 | 
						// 該当ユーザーが既にフォロワーになっていた場合はFollowingもアップデートする
 | 
				
			||||||
	await Followings.update({
 | 
						await Followings.update({
 | 
				
			||||||
		followerId: exist.id
 | 
							followerId: exist.id,
 | 
				
			||||||
	}, {
 | 
						}, {
 | 
				
			||||||
		followerSharedInbox: person.sharedInbox || (person.endpoints ? person.endpoints.sharedInbox : undefined)
 | 
							followerSharedInbox: person.sharedInbox || (person.endpoints ? person.endpoints.sharedInbox : undefined),
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	await updateFeatured(exist.id).catch(err => logger.error(err));
 | 
						await updateFeatured(exist.id).catch(err => logger.error(err));
 | 
				
			||||||
| 
						 | 
					@ -411,8 +411,9 @@ const services: {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const $discord = (id: string, name: string) => {
 | 
					const $discord = (id: string, name: string) => {
 | 
				
			||||||
	if (typeof name !== 'string')
 | 
						if (typeof name !== 'string') {
 | 
				
			||||||
		name = 'unknown#0000';
 | 
							name = 'unknown#0000';
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	const [username, discriminator] = name.split('#');
 | 
						const [username, discriminator] = name.split('#');
 | 
				
			||||||
	return { id, username, discriminator };
 | 
						return { id, username, discriminator };
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -420,13 +421,15 @@ const $discord = (id: string, name: string) => {
 | 
				
			||||||
function addService(target: { [x: string]: any }, source: IApPropertyValue) {
 | 
					function addService(target: { [x: string]: any }, source: IApPropertyValue) {
 | 
				
			||||||
	const service = services[source.name];
 | 
						const service = services[source.name];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (typeof source.value !== 'string')
 | 
						if (typeof source.value !== 'string') {
 | 
				
			||||||
		source.value = 'unknown';
 | 
							source.value = 'unknown';
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const [id, username] = source.value.split('@');
 | 
						const [id, username] = source.value.split('@');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (service)
 | 
						if (service) {
 | 
				
			||||||
		target[source.name.split(':')[2]] = service(id, username);
 | 
							target[source.name.split(':')[2]] = service(id, username);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function analyzeAttachments(attachments: IObject | IObject[] | undefined) {
 | 
					export function analyzeAttachments(attachments: IObject | IObject[] | undefined) {
 | 
				
			||||||
| 
						 | 
					@ -443,7 +446,7 @@ export function analyzeAttachments(attachments: IObject | IObject[] | undefined)
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				fields.push({
 | 
									fields.push({
 | 
				
			||||||
					name: attachment.name,
 | 
										name: attachment.name,
 | 
				
			||||||
					value: fromHtml(attachment.value)
 | 
										value: fromHtml(attachment.value),
 | 
				
			||||||
				});
 | 
									});
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -487,7 +490,7 @@ export async function updateFeatured(userId: User['id']) {
 | 
				
			||||||
				id: genId(new Date(Date.now() + td)),
 | 
									id: genId(new Date(Date.now() + td)),
 | 
				
			||||||
				createdAt: new Date(),
 | 
									createdAt: new Date(),
 | 
				
			||||||
				userId: user.id,
 | 
									userId: user.id,
 | 
				
			||||||
				noteId: note!.id
 | 
									noteId: note!.id,
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,7 @@ export default async function renderQuestion(user: { id: User['id'] }, note: Not
 | 
				
			||||||
		type: 'Question',
 | 
							type: 'Question',
 | 
				
			||||||
		id: `${config.url}/questions/${note.id}`,
 | 
							id: `${config.url}/questions/${note.id}`,
 | 
				
			||||||
		actor: `${config.url}/users/${user.id}`,
 | 
							actor: `${config.url}/users/${user.id}`,
 | 
				
			||||||
		content:  note.text || '',
 | 
							content: note.text || '',
 | 
				
			||||||
		[poll.multiple ? 'anyOf' : 'oneOf']: poll.choices.map((text, i) => ({
 | 
							[poll.multiple ? 'anyOf' : 'oneOf']: poll.choices.map((text, i) => ({
 | 
				
			||||||
			name: text,
 | 
								name: text,
 | 
				
			||||||
			_misskey_votes: poll.votes[i],
 | 
								_misskey_votes: poll.votes[i],
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,7 @@ const ECC_PRELUDE = Buffer.from([0x04]);
 | 
				
			||||||
const NULL_BYTE = Buffer.from([0]);
 | 
					const NULL_BYTE = Buffer.from([0]);
 | 
				
			||||||
const PEM_PRELUDE = Buffer.from(
 | 
					const PEM_PRELUDE = Buffer.from(
 | 
				
			||||||
	'3059301306072a8648ce3d020106082a8648ce3d030107034200',
 | 
						'3059301306072a8648ce3d020106082a8648ce3d030107034200',
 | 
				
			||||||
	'hex'
 | 
						'hex',
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Android Safetynet attestations are signed with this cert:
 | 
					// Android Safetynet attestations are signed with this cert:
 | 
				
			||||||
| 
						 | 
					@ -68,7 +68,7 @@ function verifyCertificateChain(certificates: string[]) {
 | 
				
			||||||
		const signatureHex = certificate.getSignatureValueHex();
 | 
							const signatureHex = certificate.getSignatureValueHex();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Verify against CA
 | 
							// Verify against CA
 | 
				
			||||||
		const Signature = new jsrsasign.KJUR.crypto.Signature({alg: algorithm});
 | 
							const Signature = new jsrsasign.KJUR.crypto.Signature({ alg: algorithm });
 | 
				
			||||||
		Signature.init(CACert);
 | 
							Signature.init(CACert);
 | 
				
			||||||
		Signature.updateHex(certStruct);
 | 
							Signature.updateHex(certStruct);
 | 
				
			||||||
		valid = valid && !!Signature.verify(signatureHex); // true if CA signed the certificate
 | 
							valid = valid && !!Signature.verify(signatureHex); // true if CA signed the certificate
 | 
				
			||||||
| 
						 | 
					@ -134,7 +134,7 @@ export function verifyLogin({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const verificationData = Buffer.concat(
 | 
						const verificationData = Buffer.concat(
 | 
				
			||||||
		[authenticatorData, hash(clientDataJSON)],
 | 
							[authenticatorData, hash(clientDataJSON)],
 | 
				
			||||||
		32 + authenticatorData.length
 | 
							32 + authenticatorData.length,
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return crypto
 | 
						return crypto
 | 
				
			||||||
| 
						 | 
					@ -145,7 +145,7 @@ export function verifyLogin({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const procedures = {
 | 
					export const procedures = {
 | 
				
			||||||
	none: {
 | 
						none: {
 | 
				
			||||||
		verify({publicKey}: {publicKey: Map<number, Buffer>}) {
 | 
							verify({ publicKey }: {publicKey: Map<number, Buffer>}) {
 | 
				
			||||||
			const negTwo = publicKey.get(-2);
 | 
								const negTwo = publicKey.get(-2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (!negTwo || negTwo.length != 32) {
 | 
								if (!negTwo || negTwo.length != 32) {
 | 
				
			||||||
| 
						 | 
					@ -158,14 +158,14 @@ export const procedures = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			const publicKeyU2F = Buffer.concat(
 | 
								const publicKeyU2F = Buffer.concat(
 | 
				
			||||||
				[ECC_PRELUDE, negTwo, negThree],
 | 
									[ECC_PRELUDE, negTwo, negThree],
 | 
				
			||||||
				1 + 32 + 32
 | 
									1 + 32 + 32,
 | 
				
			||||||
			);
 | 
								);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return {
 | 
								return {
 | 
				
			||||||
				publicKey: publicKeyU2F,
 | 
									publicKey: publicKeyU2F,
 | 
				
			||||||
				valid: true
 | 
									valid: true,
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
		}
 | 
							},
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	'android-key': {
 | 
						'android-key': {
 | 
				
			||||||
		verify({
 | 
							verify({
 | 
				
			||||||
| 
						 | 
					@ -174,7 +174,7 @@ export const procedures = {
 | 
				
			||||||
			clientDataHash,
 | 
								clientDataHash,
 | 
				
			||||||
			publicKey,
 | 
								publicKey,
 | 
				
			||||||
			rpIdHash,
 | 
								rpIdHash,
 | 
				
			||||||
			credentialId
 | 
								credentialId,
 | 
				
			||||||
		}: {
 | 
							}: {
 | 
				
			||||||
			attStmt: any,
 | 
								attStmt: any,
 | 
				
			||||||
			authenticatorData: Buffer,
 | 
								authenticatorData: Buffer,
 | 
				
			||||||
| 
						 | 
					@ -189,7 +189,7 @@ export const procedures = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			const verificationData = Buffer.concat([
 | 
								const verificationData = Buffer.concat([
 | 
				
			||||||
				authenticatorData,
 | 
									authenticatorData,
 | 
				
			||||||
				clientDataHash
 | 
									clientDataHash,
 | 
				
			||||||
			]);
 | 
								]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			const attCert: Buffer = attStmt.x5c[0];
 | 
								const attCert: Buffer = attStmt.x5c[0];
 | 
				
			||||||
| 
						 | 
					@ -206,7 +206,7 @@ export const procedures = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			const publicKeyData = Buffer.concat(
 | 
								const publicKeyData = Buffer.concat(
 | 
				
			||||||
				[ECC_PRELUDE, negTwo, negThree],
 | 
									[ECC_PRELUDE, negTwo, negThree],
 | 
				
			||||||
				1 + 32 + 32
 | 
									1 + 32 + 32,
 | 
				
			||||||
			);
 | 
								);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (!attCert.equals(publicKeyData)) {
 | 
								if (!attCert.equals(publicKeyData)) {
 | 
				
			||||||
| 
						 | 
					@ -222,9 +222,9 @@ export const procedures = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return {
 | 
								return {
 | 
				
			||||||
				valid: isValid,
 | 
									valid: isValid,
 | 
				
			||||||
				publicKey: publicKeyData
 | 
									publicKey: publicKeyData,
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
		}
 | 
							},
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	// what a stupid attestation
 | 
						// what a stupid attestation
 | 
				
			||||||
	'android-safetynet': {
 | 
						'android-safetynet': {
 | 
				
			||||||
| 
						 | 
					@ -234,7 +234,7 @@ export const procedures = {
 | 
				
			||||||
			clientDataHash,
 | 
								clientDataHash,
 | 
				
			||||||
			publicKey,
 | 
								publicKey,
 | 
				
			||||||
			rpIdHash,
 | 
								rpIdHash,
 | 
				
			||||||
			credentialId
 | 
								credentialId,
 | 
				
			||||||
		}: {
 | 
							}: {
 | 
				
			||||||
			attStmt: any,
 | 
								attStmt: any,
 | 
				
			||||||
			authenticatorData: Buffer,
 | 
								authenticatorData: Buffer,
 | 
				
			||||||
| 
						 | 
					@ -244,14 +244,14 @@ export const procedures = {
 | 
				
			||||||
			credentialId: Buffer,
 | 
								credentialId: Buffer,
 | 
				
			||||||
		}) {
 | 
							}) {
 | 
				
			||||||
			const verificationData = hash(
 | 
								const verificationData = hash(
 | 
				
			||||||
				Buffer.concat([authenticatorData, clientDataHash])
 | 
									Buffer.concat([authenticatorData, clientDataHash]),
 | 
				
			||||||
			);
 | 
								);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			const jwsParts = attStmt.response.toString('utf-8').split('.');
 | 
								const jwsParts = attStmt.response.toString('utf-8').split('.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			const header = JSON.parse(base64URLDecode(jwsParts[0]).toString('utf-8'));
 | 
								const header = JSON.parse(base64URLDecode(jwsParts[0]).toString('utf-8'));
 | 
				
			||||||
			const response = JSON.parse(
 | 
								const response = JSON.parse(
 | 
				
			||||||
				base64URLDecode(jwsParts[1]).toString('utf-8')
 | 
									base64URLDecode(jwsParts[1]).toString('utf-8'),
 | 
				
			||||||
			);
 | 
								);
 | 
				
			||||||
			const signature = jwsParts[2];
 | 
								const signature = jwsParts[2];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -273,7 +273,7 @@ export const procedures = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			const signatureBase = Buffer.from(
 | 
								const signatureBase = Buffer.from(
 | 
				
			||||||
				jwsParts[0] + '.' + jwsParts[1],
 | 
									jwsParts[0] + '.' + jwsParts[1],
 | 
				
			||||||
				'utf-8'
 | 
									'utf-8',
 | 
				
			||||||
			);
 | 
								);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			const valid = crypto
 | 
								const valid = crypto
 | 
				
			||||||
| 
						 | 
					@ -293,13 +293,13 @@ export const procedures = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			const publicKeyData = Buffer.concat(
 | 
								const publicKeyData = Buffer.concat(
 | 
				
			||||||
				[ECC_PRELUDE, negTwo, negThree],
 | 
									[ECC_PRELUDE, negTwo, negThree],
 | 
				
			||||||
				1 + 32 + 32
 | 
									1 + 32 + 32,
 | 
				
			||||||
			);
 | 
								);
 | 
				
			||||||
			return {
 | 
								return {
 | 
				
			||||||
				valid,
 | 
									valid,
 | 
				
			||||||
				publicKey: publicKeyData
 | 
									publicKey: publicKeyData,
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
		}
 | 
							},
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	packed: {
 | 
						packed: {
 | 
				
			||||||
		verify({
 | 
							verify({
 | 
				
			||||||
| 
						 | 
					@ -308,7 +308,7 @@ export const procedures = {
 | 
				
			||||||
			clientDataHash,
 | 
								clientDataHash,
 | 
				
			||||||
			publicKey,
 | 
								publicKey,
 | 
				
			||||||
			rpIdHash,
 | 
								rpIdHash,
 | 
				
			||||||
			credentialId
 | 
								credentialId,
 | 
				
			||||||
		}: {
 | 
							}: {
 | 
				
			||||||
			attStmt: any,
 | 
								attStmt: any,
 | 
				
			||||||
			authenticatorData: Buffer,
 | 
								authenticatorData: Buffer,
 | 
				
			||||||
| 
						 | 
					@ -319,7 +319,7 @@ export const procedures = {
 | 
				
			||||||
		}) {
 | 
							}) {
 | 
				
			||||||
			const verificationData = Buffer.concat([
 | 
								const verificationData = Buffer.concat([
 | 
				
			||||||
				authenticatorData,
 | 
									authenticatorData,
 | 
				
			||||||
				clientDataHash
 | 
									clientDataHash,
 | 
				
			||||||
			]);
 | 
								]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (attStmt.x5c) {
 | 
								if (attStmt.x5c) {
 | 
				
			||||||
| 
						 | 
					@ -342,12 +342,12 @@ export const procedures = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				const publicKeyData = Buffer.concat(
 | 
									const publicKeyData = Buffer.concat(
 | 
				
			||||||
					[ECC_PRELUDE, negTwo, negThree],
 | 
										[ECC_PRELUDE, negTwo, negThree],
 | 
				
			||||||
					1 + 32 + 32
 | 
										1 + 32 + 32,
 | 
				
			||||||
				);
 | 
									);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				return {
 | 
									return {
 | 
				
			||||||
					valid: validSignature,
 | 
										valid: validSignature,
 | 
				
			||||||
					publicKey: publicKeyData
 | 
										publicKey: publicKeyData,
 | 
				
			||||||
				};
 | 
									};
 | 
				
			||||||
			} else if (attStmt.ecdaaKeyId) {
 | 
								} else if (attStmt.ecdaaKeyId) {
 | 
				
			||||||
				// https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-ecdaa-algorithm-v2.0-id-20180227.html#ecdaa-verify-operation
 | 
									// https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-ecdaa-algorithm-v2.0-id-20180227.html#ecdaa-verify-operation
 | 
				
			||||||
| 
						 | 
					@ -357,7 +357,7 @@ export const procedures = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				throw new Error('self attestation is not supported');
 | 
									throw new Error('self attestation is not supported');
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							},
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	'fido-u2f': {
 | 
						'fido-u2f': {
 | 
				
			||||||
| 
						 | 
					@ -367,7 +367,7 @@ export const procedures = {
 | 
				
			||||||
			clientDataHash,
 | 
								clientDataHash,
 | 
				
			||||||
			publicKey,
 | 
								publicKey,
 | 
				
			||||||
			rpIdHash,
 | 
								rpIdHash,
 | 
				
			||||||
			credentialId
 | 
								credentialId,
 | 
				
			||||||
		}: {
 | 
							}: {
 | 
				
			||||||
			attStmt: any,
 | 
								attStmt: any,
 | 
				
			||||||
			authenticatorData: Buffer,
 | 
								authenticatorData: Buffer,
 | 
				
			||||||
| 
						 | 
					@ -397,7 +397,7 @@ export const procedures = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			const publicKeyU2F = Buffer.concat(
 | 
								const publicKeyU2F = Buffer.concat(
 | 
				
			||||||
				[ECC_PRELUDE, negTwo, negThree],
 | 
									[ECC_PRELUDE, negTwo, negThree],
 | 
				
			||||||
				1 + 32 + 32
 | 
									1 + 32 + 32,
 | 
				
			||||||
			);
 | 
								);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			const verificationData = Buffer.concat([
 | 
								const verificationData = Buffer.concat([
 | 
				
			||||||
| 
						 | 
					@ -405,7 +405,7 @@ export const procedures = {
 | 
				
			||||||
				rpIdHash,
 | 
									rpIdHash,
 | 
				
			||||||
				clientDataHash,
 | 
									clientDataHash,
 | 
				
			||||||
				credentialId,
 | 
									credentialId,
 | 
				
			||||||
				publicKeyU2F
 | 
									publicKeyU2F,
 | 
				
			||||||
			]);
 | 
								]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			const validSignature = crypto
 | 
								const validSignature = crypto
 | 
				
			||||||
| 
						 | 
					@ -415,8 +415,8 @@ export const procedures = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return {
 | 
								return {
 | 
				
			||||||
				valid: validSignature,
 | 
									valid: validSignature,
 | 
				
			||||||
				publicKey: publicKeyU2F
 | 
									publicKey: publicKeyU2F,
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
		}
 | 
							},
 | 
				
			||||||
	}
 | 
						},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -244,8 +244,9 @@ export default define(meta, async (ps, user) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ps.poll) {
 | 
						if (ps.poll) {
 | 
				
			||||||
		if (typeof ps.poll.expiresAt === 'number') {
 | 
							if (typeof ps.poll.expiresAt === 'number') {
 | 
				
			||||||
			if (ps.poll.expiresAt < Date.now())
 | 
								if (ps.poll.expiresAt < Date.now()) {
 | 
				
			||||||
				throw new ApiError(meta.errors.cannotCreateAlreadyExpiredPoll);
 | 
									throw new ApiError(meta.errors.cannotCreateAlreadyExpiredPoll);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		} else if (typeof ps.poll.expiredAfter === 'number') {
 | 
							} else if (typeof ps.poll.expiredAfter === 'number') {
 | 
				
			||||||
			ps.poll.expiresAt = Date.now() + ps.poll.expiredAfter;
 | 
								ps.poll.expiresAt = Date.now() + ps.poll.expiredAfter;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -112,8 +112,9 @@ export default define(meta, async (ps, user) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (exist.length) {
 | 
						if (exist.length) {
 | 
				
			||||||
		if (poll.multiple) {
 | 
							if (poll.multiple) {
 | 
				
			||||||
			if (exist.some(x => x.choice == ps.choice))
 | 
								if (exist.some(x => x.choice == ps.choice)) {
 | 
				
			||||||
				throw new ApiError(meta.errors.alreadyVoted);
 | 
									throw new ApiError(meta.errors.alreadyVoted);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			throw new ApiError(meta.errors.alreadyVoted);
 | 
								throw new ApiError(meta.errors.alreadyVoted);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,7 +42,7 @@ router.get('/disconnect/github', async ctx => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const user = await Users.findOneOrFail({
 | 
						const user = await Users.findOneOrFail({
 | 
				
			||||||
		host: null,
 | 
							host: null,
 | 
				
			||||||
		token: userToken
 | 
							token: userToken,
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const profile = await UserProfiles.findOneOrFail(user.id);
 | 
						const profile = await UserProfiles.findOneOrFail(user.id);
 | 
				
			||||||
| 
						 | 
					@ -58,7 +58,7 @@ router.get('/disconnect/github', async ctx => {
 | 
				
			||||||
	// Publish i updated event
 | 
						// Publish i updated event
 | 
				
			||||||
	publishMainStream(user.id, 'meUpdated', await Users.pack(user, user, {
 | 
						publishMainStream(user.id, 'meUpdated', await Users.pack(user, user, {
 | 
				
			||||||
		detail: true,
 | 
							detail: true,
 | 
				
			||||||
		includeSecrets: true
 | 
							includeSecrets: true,
 | 
				
			||||||
	}));
 | 
						}));
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -209,12 +209,13 @@ router.get('/gh/cb', async ctx => {
 | 
				
			||||||
				code,
 | 
									code,
 | 
				
			||||||
				{ redirect_uri },
 | 
									{ redirect_uri },
 | 
				
			||||||
				(err, accessToken, refresh, result) => {
 | 
									(err, accessToken, refresh, result) => {
 | 
				
			||||||
					if (err)
 | 
										if (err) {
 | 
				
			||||||
						rej(err);
 | 
											rej(err);
 | 
				
			||||||
					else if (result.error)
 | 
										} else if (result.error) {
 | 
				
			||||||
						rej(result.error);
 | 
											rej(result.error);
 | 
				
			||||||
					else
 | 
										} else {
 | 
				
			||||||
						res({ accessToken });
 | 
											res({ accessToken });
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
				}));
 | 
									}));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const { login, id } = await getJson('https://api.github.com/user', 'application/vnd.github.v3+json', 10 * 1000, {
 | 
							const { login, id } = await getJson('https://api.github.com/user', 'application/vnd.github.v3+json', 10 * 1000, {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,8 +41,8 @@ router.get('/.well-known/host-meta', async ctx => {
 | 
				
			||||||
	ctx.set('Content-Type', xrd);
 | 
						ctx.set('Content-Type', xrd);
 | 
				
			||||||
	ctx.body = XRD({ element: 'Link', attributes: {
 | 
						ctx.body = XRD({ element: 'Link', attributes: {
 | 
				
			||||||
		type: xrd,
 | 
							type: xrd,
 | 
				
			||||||
		template: `${config.url}${webFingerPath}?resource={uri}`
 | 
							template: `${config.url}${webFingerPath}?resource={uri}`,
 | 
				
			||||||
	}});
 | 
						} });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
router.get('/.well-known/host-meta.json', async ctx => {
 | 
					router.get('/.well-known/host-meta.json', async ctx => {
 | 
				
			||||||
| 
						 | 
					@ -51,8 +51,8 @@ router.get('/.well-known/host-meta.json', async ctx => {
 | 
				
			||||||
		links: [{
 | 
							links: [{
 | 
				
			||||||
			rel: 'lrdd',
 | 
								rel: 'lrdd',
 | 
				
			||||||
			type: jrd,
 | 
								type: jrd,
 | 
				
			||||||
			template: `${config.url}${webFingerPath}?resource={uri}`
 | 
								template: `${config.url}${webFingerPath}?resource={uri}`,
 | 
				
			||||||
		}]
 | 
							}],
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue