Skip to content
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
414e003
Update main.tf
DataDrivenMD Feb 9, 2023
f3a5574
yolo
DataDrivenMD Feb 9, 2023
c443959
Applying user handle patch
DataDrivenMD Feb 10, 2023
b6b93b7
Allow TF to overwrite wildebeest CNAME
DataDrivenMD Feb 10, 2023
6d0a2da
Merge remote-tracking branch 'upstream/main'
DataDrivenMD Feb 10, 2023
9b90066
Merge branch 'cloudflare:main' into main
DataDrivenMD Feb 10, 2023
e07b1ed
Merge pull request #1 from Distal-Labs/fix-missing-apps-verify_creden…
DataDrivenMD Feb 11, 2023
3409a3e
Define MastodonInstance types
DataDrivenMD Feb 11, 2023
629ce0c
Return Mastodon-compliant instance info
DataDrivenMD Feb 11, 2023
14c3289
Merge remote-tracking branch 'upstream/main' into fix-incompatible-in…
DataDrivenMD Feb 11, 2023
ec9aba6
Merge pull request #2 from Distal-Labs/fix-incompatible-instance-endp…
DataDrivenMD Feb 11, 2023
b83e79a
Merge branch 'fix-missing-apps-verify_credentials-endpoint'
DataDrivenMD Feb 11, 2023
749429c
Merge branch 'cloudflare:main' into main
DataDrivenMD Feb 13, 2023
d71599c
Change Default Images to Official Mastodon Avatar
DataDrivenMD Feb 13, 2023
60802a4
Merge pull request #3 from Distal-Labs/fix-use-official-default-avatar
DataDrivenMD Feb 13, 2023
bfbbd05
Merge remote-tracking branch 'upstream/main'
DataDrivenMD Feb 24, 2023
ddf04ef
Merge remote-tracking branch 'upstream/main'
DataDrivenMD Feb 25, 2023
ef45841
Merge branch 'cloudflare:main' into main
DataDrivenMD Mar 1, 2023
2887e3a
Merge branch 'cloudflare:main' into main
DataDrivenMD Mar 1, 2023
8fb9b9b
Tiny refactor of existing Mastodon instance tests
DataDrivenMD Mar 2, 2023
2e30352
/api/v1/instance endpoint + getAdmins() test
DataDrivenMD Mar 2, 2023
0f2d29b
Adding test for instance v1 statistics
DataDrivenMD Mar 2, 2023
199b267
Merge remote-tracking branch 'upstream/main'
DataDrivenMD Mar 2, 2023
9a94e00
Linting
DataDrivenMD Mar 2, 2023
4ef9d98
More linting
DataDrivenMD Mar 2, 2023
0776114
Merge branch 'main' into api/v1/instance
DataDrivenMD Mar 2, 2023
1a38165
Revert "Merge branch 'main' into api/v1/instance"
DataDrivenMD Mar 2, 2023
52a4eab
Merge branch 'cloudflare:main' into api/v1/instance
DataDrivenMD Mar 3, 2023
d78558e
fix frontend ...spread vs. ...rest destructuring
DataDrivenMD Mar 4, 2023
6121294
Add TODO for array concatenation using ... operator
DataDrivenMD Mar 4, 2023
fe500ff
fix ...cors() destructuring
DataDrivenMD Mar 4, 2023
40e9a27
Fix remaining ...rest destructuring
DataDrivenMD Mar 4, 2023
29527b7
Fix reblog business logic + tests
DataDrivenMD Mar 6, 2023
9e6296f
Fixed several bugs
DataDrivenMD Mar 6, 2023
05c9931
Merge remote-tracking branch 'upstream/main' into fix-spread-and-rest…
DataDrivenMD Mar 6, 2023
af4f8a8
Merge branch 'upstream/main' into api/v1/instance
DataDrivenMD Mar 6, 2023
baa28d5
Merge remote-tracking branch 'upstream/main' into api/v1/instance
DataDrivenMD Mar 6, 2023
ea5f3fa
Pass e2e tests
DataDrivenMD Mar 7, 2023
3283c55
Making requested changes
DataDrivenMD Mar 7, 2023
4a698bd
Merge remote-tracking branch 'upstream/main' into api/v1/instance
DataDrivenMD Mar 7, 2023
85b0ac4
Merge remote-tracking branch 'upstream/main' into fix-spread-and-rest…
DataDrivenMD Mar 7, 2023
925eef2
Merge branch 'api/v1/instance' into fix-spread-and-rest-based-binding
DataDrivenMD Mar 7, 2023
1d571d6
Revert "Merge branch 'api/v1/instance' into fix-spread-and-rest-based…
DataDrivenMD Mar 7, 2023
b7b8651
Revert "Merge remote-tracking branch 'upstream/main' into fix-spread-…
DataDrivenMD Mar 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions backend/src/activitypub/activities/handle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ export async function handle(
let target = PUBLIC_GROUP

if (Array.isArray(activity.to) && activity.to.length > 0) {
// TODO: Double-check that this is working as intended
// because this syntax will silently fail if `recipients` or `activity.to` are multi-dimensional arrays
// ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#sect1
recipients = [...recipients, ...activity.to]

if (activity.to.length !== 1) {
Expand All @@ -151,6 +154,9 @@ export async function handle(
target = activity.to[0]
}
if (Array.isArray(activity.cc) && activity.cc.length > 0) {
// TODO: Double-check that this is working as intended
// because this syntax will silently fail if `recipients` or `activity.cc` are multi-dimensional arrays
// ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#sect1
recipients = [...recipients, ...activity.cc]
}

Expand Down
3 changes: 2 additions & 1 deletion backend/src/activitypub/actors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,11 +295,11 @@ export function personFromRow(row: any): Person {
}
}

// prettier-ignore
return {
// Hidden values
[emailSymbol]: row.email,

...properties,
name,
icon,
image,
Expand All @@ -311,5 +311,6 @@ export function personFromRow(row: any): Person {
published: new Date(row.cdate).toISOString(),

url: new URL('@' + preferredUsername, 'https://' + domain),
...properties
} as unknown as Person
}
16 changes: 12 additions & 4 deletions backend/src/activitypub/objects/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,15 @@ export async function createObject<Type extends APObject>(
.bind(apId, type, JSON.stringify(sanitizedProperties), originalActorId.toString(), local ? 1 : 0, uuid)
.first()

// prettier-ignore
return {
...sanitizedProperties,
type,
id: new URL(row.id),
published: new Date(row.cdate).toISOString(),

[mastodonIdSymbol]: row.mastodon_id,
[originalActorIdSymbol]: row.original_actor_id,
...sanitizedProperties
} as Type
}

Expand Down Expand Up @@ -129,16 +130,19 @@ export async function cacheObject(

{
const properties = JSON.parse(row.properties)

// prettier-ignore

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's unnecessary to set const properties = JSON.parse(row.properties) because row.properties === sanitizedProperties

const object = {
published: new Date(row.cdate).toISOString(),
...properties,

type: row.type,
id: new URL(row.id),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's unnecessary to set type: row.type and id: new URL(row.id), because row.properties === sanitizedProperties. So, the expansion ...sanitizedProperties should suffice

[mastodonIdSymbol]: row.mastodon_id,
[originalActorIdSymbol]: row.original_actor_id,
[originalObjectIdSymbol]: row.original_object_id,

...properties
} as APObject

return { object, created: true }
Expand Down Expand Up @@ -208,16 +212,17 @@ export async function getObjectBy(db: Database, key: ObjectByKey, value: string)
const result: any = results[0]
const properties = JSON.parse(result.properties)

// prettier-ignore
return {
published: new Date(result.cdate).toISOString(),
...properties,

type: result.type,
id: new URL(result.id),

[mastodonIdSymbol]: result.mastodon_id,
[originalActorIdSymbol]: result.original_actor_id,
[originalObjectIdSymbol]: result.original_object_id,
...properties
} as APObject
}

Expand All @@ -231,9 +236,12 @@ export async function sanitizeObjectProperties(properties: unknown): Promise<APO
if (!isAPObject(properties)) {
throw new Error('Invalid object properties. Expected an object but got ' + JSON.stringify(properties))
}

// prettier-ignore
const sanitized: APObject = {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTE: Manually setting the type to APObject here is technically invalid because not all of the objects that are passed to the method have id, type, and url properties. As none of these properties are accessed in this method, the type-checking doesn't fail within the method. This explains why, despite not having an id or type property, we throw an error during mocking when we "overwrite" these properties by calling the ...properties operation during variable assignment

...properties,
...properties
}

if ('content' in properties) {
sanitized.content = await sanitizeContent(properties.content as string)
}
Expand Down
6 changes: 4 additions & 2 deletions backend/src/activitypub/objects/note.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export async function createPublicNote(
): Promise<Note> {
const actorId = new URL(actor.id)

// prettier-ignore
const properties = {
attributedTo: actorId,
content,
Expand All @@ -46,7 +47,7 @@ export async function createPublicNote(

attachment: attachments,
inReplyTo: null,
...extraProperties,
...extraProperties
}

return (await objects.createObject(domain, db, NOTE, properties, actorId, true)) as Note
Expand All @@ -63,6 +64,7 @@ export async function createDirectNote(
): Promise<Note> {
const actorId = new URL(actor.id)

// prettier-ignore
const properties = {
attributedTo: actorId,
content,
Expand All @@ -77,7 +79,7 @@ export async function createDirectNote(
tag: [],
attachment,

...extraProperties,
...extraProperties
}

return (await objects.createObject(domain, db, NOTE, properties, actorId, true)) as Note
Expand Down
3 changes: 3 additions & 0 deletions backend/src/database/neon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ export class PreparedStatement {
}

bind(...values: any[]): PreparedStatement {
// TODO: Double-check that this is working as intended
// because this syntax will silently fail if `this.values` or `values` are multi-dimensional arrays
// ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#sect1
return new PreparedStatement(this.env, this.query, [...this.values, ...values], this.client)
}

Expand Down
7 changes: 5 additions & 2 deletions backend/src/errors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@ type ErrorResponse = {
error_description?: string
}

// prettier-ignore
const headers = {
...cors(),
'content-type': 'application/json; charset=utf-8',
...cors()
} as const

function generateErrorResponse(error: string, status: number, errorDescription?: string): Response {
// prettier-ignore
const res: ErrorResponse = {
error: `${error}. If the problem persists please contact your instance administrator.`,
...(errorDescription ? { error_description: errorDescription } : {}),
...(errorDescription ? { error_description: errorDescription } : {})
}

return new Response(JSON.stringify(res), { headers, status })
}

Expand Down
5 changes: 2 additions & 3 deletions backend/src/mastodon/idempotency.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,14 @@ export async function hasKey(db: Database, key: string): Promise<APObject | null
const result = results[0]
const properties = JSON.parse(result.properties)

// prettier-ignore
return {
published: new Date(result.cdate).toISOString(),
...properties,

type: result.type,
id: new URL(result.id),

[mastodonIdSymbol]: result.mastodon_id,
[originalActorIdSymbol]: result.original_actor_id,
[originalObjectIdSymbol]: result.original_object_id,
...properties
} as APObject
}
3 changes: 2 additions & 1 deletion backend/src/mastodon/status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,10 @@ export async function toMastodonStatusFromRow(domain: string, db: Database, row:
const account = await loadExternalMastodonAccount(acct, author)

// Restore reblogged status
// prettier-ignore
status.reblog = {
...status,
account,
...status
}
}

Expand Down
3 changes: 2 additions & 1 deletion backend/src/middleware/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ async function loadContextData(db: Database, clientId: string, email: string, ct

export async function main(context: EventContext<Env, any, any>) {
if (context.request.method === 'OPTIONS') {
// prettier-ignore
const headers = {
...cors(),
'content-type': 'application/json',
...cors()
}
return new Response('', { headers })
}
Expand Down
5 changes: 4 additions & 1 deletion backend/src/utils/http-signing-cavage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,14 @@ export async function generateDigestHeader(body: string): Promise<string> {

export async function sign(request: Request, opts: SignOptions): Promise<void> {
const signingComponents: Component[] = opts.components ?? defaultSigningComponents

// prettier-ignore
const signingParams: Parameters = {
...opts.parameters,
keyid: opts.keyId,
alg: opts.signer.alg,
...opts.parameters
}

const signatureInputString = buildSignatureInputString(signingComponents, signingParams)
const dataToSign = buildSignedData(request, signingComponents, signingParams)
const signature = await opts.signer(dataToSign)
Expand Down
2 changes: 1 addition & 1 deletion frontend/mock-db/run.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ async function main() {
define: ['jest:{}'],
}
const workerPath = resolve(__dirname, './worker.ts')
const worker = await unstable_dev(workerPath, { ...options, experimental: { disableExperimentalWarning: true } })
const worker = await unstable_dev(workerPath, { experimental: { disableExperimentalWarning: true }, ...options })
await worker.fetch()
await worker.stop()
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/MediaGallery.tsx/Image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default component$<Props>(({ mediaAttachment, onOpenImagesModal$ }) => {
<img
class="object-cover w-full h-full rounded cursor-pointer"
style={{
...(objectFit && { 'object-position': `${objectFit.x}% ${objectFit.y}%` }),
...(objectFit && { 'object-position': `${objectFit.x}% ${objectFit.y}%` })
}}
src={mediaAttachment.preview_url || mediaAttachment.url}
onClick$={() => onOpenImagesModal$(mediaAttachment.id)}
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/components/StatusesPanel/StatusesPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ export const StatusesPanel = component$(({ initialStatuses, fetchMoreStatuses: f
const newStatuses = await fetchMoreStatusesFn(statuses.value.length)
fetchingMoreStatuses.value = false
noMoreStatusesAvailable.value = newStatuses.length === 0
// TODO: Double-check that this is working as intended
// because this syntax will silently fail with multi-dimensional arrays
// ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#sect1
statuses.value = [...statuses.value, ...newStatuses]
})

Expand Down
3 changes: 2 additions & 1 deletion frontend/src/dummyData/accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ export const rafael = generateDummyAccount({
avatar_static: getAvatarUrl(309),
})

// prettier-ignore
function generateDummyAccount(
details: Pick<Account, 'username' | 'acct' | 'display_name' | 'avatar' | 'avatar_static'>
): Account {
return {
...details,
id: `${Math.round(Math.random() * 9999999)}`.padStart(7, '0'),
locked: false,
bot: false,
Expand Down Expand Up @@ -88,6 +88,7 @@ function generateDummyAccount(
verified_at: null,
},
],
...details
}
}

Expand Down
5 changes: 3 additions & 2 deletions frontend/src/dummyData/statuses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,13 @@ const mastodonRawStatuses: MastodonStatus[] = [
}),
]

// prettier-ignore
export const statuses: MastodonStatus[] = mastodonRawStatuses.map((rawStatus) => ({
...rawStatus,
media_attachments: rawStatus.media_attachments.map((mediaAttachment) => ({
...mediaAttachment,
type: getStandardMediaType(mediaAttachment.type),
...mediaAttachment
})),
...rawStatus
}))

export const replies: MastodonStatus[] = [
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/entry.ssr.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import Root from './root'
export default function (opts: RenderToStreamOptions) {
return renderToStream(<Root />, {
manifest,
...opts,
// Use container attributes to set attributes on the html tag.
containerAttributes: {
lang: 'en-us',
...opts.containerAttributes,
...opts.containerAttributes
},
...opts
})
}
3 changes: 2 additions & 1 deletion frontend/src/routes/(frontend)/[accountId]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,13 @@ export default component$(() => {
const location = useLocation()
const currentPath = location.pathname.replace(/\/$/, '')

// prettier-ignore
const fields = [
{
name: 'Joined',
value: formatDateTime(pageDetails.account.created_at, false),
},
...pageDetails.account.fields,
...pageDetails.account.fields
]

const stats = [
Expand Down
3 changes: 2 additions & 1 deletion functions/.well-known/nodeinfo.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import type { Env } from 'wildebeest/backend/src/types/env'
import { cors } from 'wildebeest/backend/src/utils/cors'

// prettier-ignore
const headers = {
...cors(),
'content-type': 'application/json',
'cache-control': 'max-age=259200, public',
...cors()
}

export const onRequest: PagesFunction<Env, any> = async ({ env }) => {
Expand Down
7 changes: 4 additions & 3 deletions functions/ap/o/[id].ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ export const onRequest: PagesFunction<Env, any> = async ({ params, request, env
return handleRequest(domain, await getDatabase(env), params.id as string)
}

// prettier-ignore
const headers = {
...cors(),
'content-type': 'application/activity+json; charset=utf-8',
...cors()
}

export async function handleRequest(domain: string, db: Database, id: string): Promise<Response> {
Expand All @@ -19,6 +20,7 @@ export async function handleRequest(domain: string, db: Database, id: string): P
return new Response('', { status: 404 })
}

// prettier-ignore
const res = {
// TODO: should this be part of the object?
'@context': [
Expand All @@ -33,8 +35,7 @@ export async function handleRequest(domain: string, db: Database, id: string): P
votersCount: 'toot:votersCount',
},
],

...obj,
...obj
}

return new Response(JSON.stringify(res), { status: 200, headers })
Expand Down
Loading