Merge pull request #11 from cloudflare/be-lint-no-unsafe-returns

enable be no-unsafe-return eslint rule also apply some related refactoring to make the code more DRY
pull/14/head
Sven Sauleau 2023-01-04 16:44:25 +00:00 zatwierdzone przez GitHub
commit 371fa7e02f
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
15 zmienionych plików z 74 dodań i 102 usunięć

Wyświetl plik

@ -13,6 +13,7 @@ module.exports = {
root: true, root: true,
rules: { rules: {
'no-var': 'error', 'no-var': 'error',
'@typescript-eslint/no-unsafe-return': 'error',
/* /*
Note: the following rules have been set to off so that linting Note: the following rules have been set to off so that linting
can pass with the current code, but we need to gradually can pass with the current code, but we need to gradually
@ -29,7 +30,6 @@ module.exports = {
'@typescript-eslint/require-await': 'off', '@typescript-eslint/require-await': 'off',
'@typescript-eslint/restrict-template-expressions': 'off', '@typescript-eslint/restrict-template-expressions': 'off',
'@typescript-eslint/no-misused-promises': 'off', '@typescript-eslint/no-misused-promises': 'off',
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-unnecessary-type-assertion': 'off', '@typescript-eslint/no-unnecessary-type-assertion': 'off',
'no-console': 'off', 'no-console': 'off',
'@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/no-explicit-any': 'off',

Wyświetl plik

@ -78,7 +78,7 @@ export function getPayload(jwt: string): JWTPayload {
} }
const [, payload] = parts const [, payload] = parts
const payloadObj = JSON.parse(textDecoder.decode(base64URLDecode(payload))) const payloadObj: JWTPayload = JSON.parse(textDecoder.decode(base64URLDecode(payload)))
return payloadObj return payloadObj
} }

Wyświetl plik

@ -61,7 +61,7 @@ export async function handle(
} }
if (activity.object instanceof URL) { if (activity.object instanceof URL) {
// This is used for testing only. // This is used for testing only.
return activity.object return activity.object as URL
} }
if (url === null) { if (url === null) {
throw new Error('unknown value: ' + JSON.stringify(activity.object)) throw new Error('unknown value: ' + JSON.stringify(activity.object))
@ -85,7 +85,7 @@ export async function handle(
} }
if (activity.actor instanceof URL) { if (activity.actor instanceof URL) {
// This is used for testing only. // This is used for testing only.
return activity.actor return activity.actor as URL
} }
if (url === null) { if (url === null) {
throw new Error('unknown value: ' + JSON.stringify(activity.actor)) throw new Error('unknown value: ' + JSON.stringify(activity.actor))

Wyświetl plik

@ -233,5 +233,5 @@ export function personFromRow(row: any): Person {
// It's very possible that properties override the values set above. // It's very possible that properties override the values set above.
// Almost guaranteed for remote user. // Almost guaranteed for remote user.
...JSON.parse(row.properties), ...JSON.parse(row.properties),
} } as Person
} }

Wyświetl plik

@ -56,7 +56,7 @@ export async function createObject(
mastodonId: row.mastodon_id, mastodonId: row.mastodon_id,
published: new Date(row.cdate).toISOString(), published: new Date(row.cdate).toISOString(),
originalActorId: row.original_actor_id, originalActorId: row.original_actor_id,
} } as Object
} }
export async function get<T>(url: URL): Promise<T> { export async function get<T>(url: URL): Promise<T> {
@ -114,7 +114,7 @@ export async function cacheObject(
mastodonId: row.mastodon_id, mastodonId: row.mastodon_id,
originalActorId: row.original_actor_id, originalActorId: row.original_actor_id,
originalObjectId: row.original_object_id, originalObjectId: row.original_object_id,
} } as Object
} }
} }
@ -168,5 +168,5 @@ WHERE objects.${key}=?
mastodonId: result.mastodon_id, mastodonId: result.mastodon_id,
originalActorId: result.original_actor_id, originalActorId: result.original_actor_id,
originalObjectId: result.original_object_id, originalObjectId: result.original_object_id,
} } as Object
} }

Wyświetl plik

@ -51,7 +51,7 @@ export async function generateVAPIDKeys(db: D1Database) {
} }
export async function get(db: D1Database, name: string): Promise<string> { export async function get(db: D1Database, name: string): Promise<string> {
const row: any = await db.prepare('SELECT value FROM instance_config WHERE key = ?').bind(name).first() const row: { value: string } = await db.prepare('SELECT value FROM instance_config WHERE key = ?').bind(name).first()
if (!row) { if (!row) {
throw new Error(`configuration not found: ${name}`) throw new Error(`configuration not found: ${name}`)
} }

Wyświetl plik

@ -1,4 +1,5 @@
import type { Actor } from 'wildebeest/backend/src/activitypub/actors' import type { Actor } from 'wildebeest/backend/src/activitypub/actors'
import { getResultsField } from './utils'
const STATE_PENDING = 'pending' const STATE_PENDING = 'pending'
const STATE_ACCEPTED = 'accepted' const STATE_ACCEPTED = 'accepted'
@ -8,9 +9,9 @@ export async function addFollowing(db: D1Database, actor: Actor, target: Actor,
const id = crypto.randomUUID() const id = crypto.randomUUID()
const query = ` const query = `
INSERT INTO actor_following (id, actor_id, target_actor_id, state, target_actor_acct) INSERT INTO actor_following (id, actor_id, target_actor_id, state, target_actor_acct)
VALUES (?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?)
` `
const out = await db const out = await db
.prepare(query) .prepare(query)
@ -27,8 +28,8 @@ export async function acceptFollowing(db: D1Database, actor: Actor, target: Acto
const id = crypto.randomUUID() const id = crypto.randomUUID()
const query = ` const query = `
UPDATE actor_following SET state=? WHERE actor_id=? AND target_actor_id=? AND state=? UPDATE actor_following SET state=? WHERE actor_id=? AND target_actor_id=? AND state=?
` `
const out = await db const out = await db
.prepare(query) .prepare(query)
@ -41,8 +42,8 @@ export async function acceptFollowing(db: D1Database, actor: Actor, target: Acto
export async function removeFollowing(db: D1Database, actor: Actor, target: Actor) { export async function removeFollowing(db: D1Database, actor: Actor, target: Actor) {
const query = ` const query = `
DELETE FROM actor_following WHERE actor_id=? AND target_actor_id=? DELETE FROM actor_following WHERE actor_id=? AND target_actor_id=?
` `
const out = await db.prepare(query).bind(actor.id.toString(), target.id.toString()).run() const out = await db.prepare(query).bind(actor.id.toString(), target.id.toString()).run()
if (!out.success) { if (!out.success) {
@ -50,70 +51,41 @@ export async function removeFollowing(db: D1Database, actor: Actor, target: Acto
} }
} }
export async function getFollowingAcct(db: D1Database, actor: Actor): Promise<Array<string>> { export function getFollowingAcct(db: D1Database, actor: Actor): Promise<Array<string>> {
const query = ` const query = `
SELECT target_actor_acct FROM actor_following WHERE actor_id=? AND state=? SELECT target_actor_acct FROM actor_following WHERE actor_id=? AND state=?
` `
const statement = db.prepare(query).bind(actor.id.toString(), STATE_ACCEPTED)
const out: any = await db.prepare(query).bind(actor.id.toString(), STATE_ACCEPTED).all() return getResultsField(statement, 'target_actor_acct')
if (!out.success) {
throw new Error('SQL error: ' + out.error)
}
if (out.results !== null) {
return out.results.map((x: any) => x.target_actor_acct)
} else {
return []
}
} }
export async function getFollowingRequestedAcct(db: D1Database, actor: Actor): Promise<Array<string>> { export function getFollowingRequestedAcct(db: D1Database, actor: Actor): Promise<Array<string>> {
const query = ` const query = `
SELECT target_actor_acct FROM actor_following WHERE actor_id=? AND state=? SELECT target_actor_acct FROM actor_following WHERE actor_id=? AND state=?
` `
const out: any = await db.prepare(query).bind(actor.id.toString(), STATE_PENDING).all() const statement = db.prepare(query).bind(actor.id.toString(), STATE_PENDING)
if (!out.success) {
throw new Error('SQL error: ' + out.error)
}
if (out.results !== null) { return getResultsField(statement, 'target_actor_acct')
return out.results.map((x: any) => x.target_actor_acct)
} else {
return []
}
} }
export async function getFollowingId(db: D1Database, actor: Actor): Promise<Array<string>> { export function getFollowingId(db: D1Database, actor: Actor): Promise<Array<string>> {
const query = ` const query = `
SELECT target_actor_id FROM actor_following WHERE actor_id=? AND state=? SELECT target_actor_id FROM actor_following WHERE actor_id=? AND state=?
` `
const out: any = await db.prepare(query).bind(actor.id.toString(), STATE_ACCEPTED).all() const statement = db.prepare(query).bind(actor.id.toString(), STATE_ACCEPTED)
if (!out.success) {
throw new Error('SQL error: ' + out.error)
}
if (out.results !== null) { return getResultsField(statement, 'target_actor_id')
return out.results.map((x: any) => x.target_actor_id)
} else {
return []
}
} }
export async function getFollowers(db: D1Database, actor: Actor): Promise<Array<string>> { export function getFollowers(db: D1Database, actor: Actor): Promise<Array<string>> {
const query = ` const query = `
SELECT actor_id FROM actor_following WHERE target_actor_id=? AND state=? SELECT actor_id FROM actor_following WHERE target_actor_id=? AND state=?
` `
const out: any = await db.prepare(query).bind(actor.id.toString(), STATE_ACCEPTED).all() const statement = db.prepare(query).bind(actor.id.toString(), STATE_ACCEPTED)
if (!out.success) {
throw new Error('SQL error: ' + out.error)
}
if (out.results !== null) { return getResultsField(statement, 'actor_id')
return out.results.map((x: any) => x.actor_id)
} else {
return []
}
} }

Wyświetl plik

@ -1,32 +1,27 @@
import type { Object } from 'wildebeest/backend/src/activitypub/objects' import type { Object } from 'wildebeest/backend/src/activitypub/objects'
import type { Actor } from 'wildebeest/backend/src/activitypub/actors' import type { Actor } from 'wildebeest/backend/src/activitypub/actors'
import { getResultsField } from './utils'
export async function insertLike(db: D1Database, actor: Actor, obj: Object) { export async function insertLike(db: D1Database, actor: Actor, obj: Object) {
const id = crypto.randomUUID() const id = crypto.randomUUID()
const query = ` const query = `
INSERT INTO actor_favourites (id, actor_id, object_id) INSERT INTO actor_favourites (id, actor_id, object_id)
VALUES (?, ?, ?) VALUES (?, ?, ?)
` `
const out = await db.prepare(query).bind(id, actor.id.toString(), obj.id.toString()).run() const out = await db.prepare(query).bind(id, actor.id.toString(), obj.id.toString()).run()
if (!out.success) { if (!out.success) {
throw new Error('SQL error: ' + out.error) throw new Error('SQL error: ' + out.error)
} }
} }
export async function getLikes(db: D1Database, obj: Object): Promise<Array<string>> { export function getLikes(db: D1Database, obj: Object): Promise<Array<string>> {
const query = ` const query = `
SELECT actor_id FROM actor_favourites WHERE object_id=? SELECT actor_id FROM actor_favourites WHERE object_id=?
` `
const out: any = await db.prepare(query).bind(obj.id.toString()).all() const statement = db.prepare(query).bind(obj.id.toString())
if (!out.success) {
throw new Error('SQL error: ' + out.error)
}
if (out.results !== null) { return getResultsField(statement, 'actor_id')
return out.results.map((x: any) => x.actor_id)
} else {
return []
}
} }

Wyświetl plik

@ -26,7 +26,7 @@ export async function createNotification(
VALUES (?, ?, ?, ?) VALUES (?, ?, ?, ?)
RETURNING id RETURNING id
` `
const row: any = await db const row: { id: string } = await db
.prepare(query) .prepare(query)
.bind(type, actor.id.toString(), fromActor.id.toString(), obj.id.toString()) .bind(type, actor.id.toString(), fromActor.id.toString(), obj.id.toString())
.first() .first()
@ -41,7 +41,7 @@ export async function insertFollowNotification(db: D1Database, actor: Actor, fro
VALUES (?, ?, ?) VALUES (?, ?, ?)
RETURNING id RETURNING id
` `
const row: any = await db.prepare(query).bind(type, actor.id.toString(), fromActor.id.toString()).first() const row: { id: string } = await db.prepare(query).bind(type, actor.id.toString(), fromActor.id.toString()).first()
return row.id return row.id
} }

Wyświetl plik

@ -2,33 +2,28 @@
import type { Object } from 'wildebeest/backend/src/activitypub/objects' import type { Object } from 'wildebeest/backend/src/activitypub/objects'
import type { Actor } from 'wildebeest/backend/src/activitypub/actors' import type { Actor } from 'wildebeest/backend/src/activitypub/actors'
import { getResultsField } from './utils'
export async function insertReblog(db: D1Database, actor: Actor, obj: Object) { export async function insertReblog(db: D1Database, actor: Actor, obj: Object) {
const id = crypto.randomUUID() const id = crypto.randomUUID()
const query = ` const query = `
INSERT INTO actor_reblogs (id, actor_id, object_id) INSERT INTO actor_reblogs (id, actor_id, object_id)
VALUES (?, ?, ?) VALUES (?, ?, ?)
` `
const out = await db.prepare(query).bind(id, actor.id.toString(), obj.id.toString()).run() const out = await db.prepare(query).bind(id, actor.id.toString(), obj.id.toString()).run()
if (!out.success) { if (!out.success) {
throw new Error('SQL error: ' + out.error) throw new Error('SQL error: ' + out.error)
} }
} }
export async function getReblogs(db: D1Database, obj: Object): Promise<Array<string>> { export function getReblogs(db: D1Database, obj: Object): Promise<Array<string>> {
const query = ` const query = `
SELECT actor_id FROM actor_reblogs WHERE object_id=? SELECT actor_id FROM actor_reblogs WHERE object_id=?
` `
const out: any = await db.prepare(query).bind(obj.id.toString()).all() const statement = db.prepare(query).bind(obj.id.toString())
if (!out.success) {
throw new Error('SQL error: ' + out.error)
}
if (out.results !== null) { return getResultsField(statement, 'actor_id')
return out.results.map((x: any) => x.actor_id)
} else {
return []
}
} }

Wyświetl plik

@ -129,7 +129,7 @@ export async function getVAPIDKeys(db: D1Database): Promise<JWK> {
if (!row) { if (!row) {
throw new Error('missing VAPID keys') throw new Error('missing VAPID keys')
} }
const value = JSON.parse(row.value) const value: JWK = JSON.parse(row.value)
return value return value
} }

Wyświetl plik

@ -0,0 +1,9 @@
export async function getResultsField(statement: D1PreparedStatement, fieldName: string): Promise<Array<string>> {
const out: D1Result<Record<string, string>> = await statement.all()
if (!out.success) {
throw new Error('SQL error: ' + out.error)
}
return (out.results ?? []).map((x) => x[fieldName])
}

Wyświetl plik

@ -31,7 +31,7 @@ export class InvalidAlgorithmError extends HttpSignatureError {
* @returns {[string, string]} * @returns {[string, string]}
*/ */
export function validateAlgorithm(algorithm: string, publicKeyType?: string): [string, string] { export function validateAlgorithm(algorithm: string, publicKeyType?: string): [string, string] {
var alg = algorithm.toLowerCase().split('-') const alg = algorithm.toLowerCase().split('-')
if (alg[0] === 'hs2019') { if (alg[0] === 'hs2019') {
return publicKeyType !== undefined ? validateAlgorithm(publicKeyType + '-sha256') : ['hs2019', 'sha256'] return publicKeyType !== undefined ? validateAlgorithm(publicKeyType + '-sha256') : ['hs2019', 'sha256']

Wyświetl plik

@ -157,7 +157,8 @@ const DEC = {
'-': '+', '-': '+',
_: '/', _: '/',
'.': '=', '.': '=',
} } as const
type KeyOfDEC = keyof typeof DEC
export function urlsafeBase64Decode(v: string) { export function urlsafeBase64Decode(v: string) {
return atob(v.replace(/[-_.]/g, (m: string) => (DEC as any)[m])) return atob(v.replace(/[-_.]/g, (m: string) => DEC[m as KeyOfDEC]))
} }

Wyświetl plik

@ -13,7 +13,7 @@ const kv_cache: any = {
async put() {}, async put() {},
} }
const waitUntil = async (p: Promise<any>) => await p const waitUntil = async (p: Promise<void>) => await p
describe('ActivityPub', () => { describe('ActivityPub', () => {
test('send Note to non existant user', async () => { test('send Note to non existant user', async () => {