Another attempt to fix the cors issue

This commit is contained in:
Gordon Pedersen 2023-10-17 11:44:14 +11:00
parent cf71ed823e
commit 4c244e9108
4 changed files with 41 additions and 26 deletions

View file

@ -1,4 +1,4 @@
import { authorized, verify } from "./request"
import { authorized, defaultHeaders, verify } from "./request"
import outbox from "./outbox"
import inbox from "./inbox"
import ACTOR from "../actor"
@ -34,15 +34,15 @@ export function reqIsActivityPub(req:Request) {
const postOutbox = async (req:Request):Promise<Response> => {
console.log("PostOutbox")
if(!authorized(req)) return new Response('', { status: 401 })
if(!authorized(req)) return new Response('', { status: 401, headers: defaultHeaders(req) })
const bodyText = await req.text()
const body = JSON.parse(bodyText)
// ensure that the verified actor matches the actor in the request body
if (ACTOR.id !== body.actor) return new Response("", { status: 401 })
if (ACTOR.id !== body.actor) return new Response("", { status: 401, headers: defaultHeaders(req) })
return await outbox(body, db)
return await outbox(body, req, db)
}
const postInbox = async (req:Request):Promise<Response> => {
@ -56,15 +56,15 @@ const postInbox = async (req:Request):Promise<Response> => {
// verify the signed HTTP request
from = await verify(req, bodyText);
} catch (err) {
return new Response("", { status: 401 })
return new Response("", { status: 401, headers: defaultHeaders(req) })
}
const body = JSON.parse(bodyText)
// ensure that the verified actor matches the actor in the request body
if (from !== body.actor) return new Response("", { status: 401 })
if (from !== body.actor) return new Response("", { status: 401, headers: defaultHeaders(req) })
return await inbox(body, db)
return await inbox(body, req, db)
}
const getOutbox = async (req:Request):Promise<Response> => {
@ -82,7 +82,7 @@ const getOutbox = async (req:Request):Promise<Response> => {
...post,
actor: ACTOR.id
})).sort( (a,b) => new Date(b.published).getTime() - new Date(a.published).getTime())
}, { headers: { "Content-Type": "application/activity+json"} })
}, { status:200, headers: defaultHeaders(req) })
}
const getFollowers = async (req:Request):Promise<Response> => {
@ -98,7 +98,7 @@ const getFollowers = async (req:Request):Promise<Response> => {
type: "OrderedCollection",
totalItems: followers?.length,
first: `${ACTOR.followers}?page=1`,
})
}, { status:200, headers: defaultHeaders(req) })
else return Response.json({
"@context": "https://www.w3.org/ns/activitystreams",
id: `${ACTOR.followers}?page=${page}`,
@ -106,7 +106,7 @@ const getFollowers = async (req:Request):Promise<Response> => {
partOf: ACTOR.followers,
totalItems: followers?.length,
orderedItems: followers?.map(follower => follower?.id)
})
}, { status:200, headers: defaultHeaders(req) })
}
const getFollowing = async (req:Request):Promise<Response> => {
@ -122,7 +122,7 @@ const getFollowing = async (req:Request):Promise<Response> => {
type: "OrderedCollection",
totalItems: following?.length,
first: `${ACTOR.following}?page=1`,
})
}, { status:200, headers: defaultHeaders(req) })
else return Response.json({
"@context": "https://www.w3.org/ns/activitystreams",
id: `${ACTOR.following}?page=${page}`,
@ -130,25 +130,25 @@ const getFollowing = async (req:Request):Promise<Response> => {
partOf: ACTOR.following,
totalItems: following?.length,
orderedItems: following?.map(follow => follow.id)
})
}, { status:200, headers: defaultHeaders(req) })
}
const getActor = async (req:Request):Promise<Response> => {
console.log("GetActor")
if(reqIsActivityPub(req)) return Response.json(ACTOR, { headers: { "Content-Type": "application/activity+json"}})
else return Response.json(db.listPosts())
if(reqIsActivityPub(req)) return Response.json(ACTOR, { status:200, headers: defaultHeaders(req) })
else return Response.json(db.listPosts(), { status:200, headers: defaultHeaders(req) })
}
const getPost = async (req:Request, id:string):Promise<Response> => {
console.log("GetPost", id)
if(reqIsActivityPub(req)) return Response.json((db.getOutboxActivity(id))?.object, { headers: { "Content-Type": "application/activity+json"}})
else return Response.json(db.getPost(id))
if(reqIsActivityPub(req)) return Response.json((db.getOutboxActivity(id))?.object, { status:200, headers: defaultHeaders(req) })
else return Response.json(db.getPost(id), { status:200, headers: defaultHeaders(req) })
}
const getOutboxActivity = async (req:Request, id:string):Promise<Response> => {
console.log("GetOutboxActivity", id)
return Response.json((db.getOutboxActivity(id)), { headers: { "Content-Type": "application/activity+json"}})
return Response.json((db.getOutboxActivity(id)), { status:200, headers: defaultHeaders(req) })
}

View file

@ -1,10 +1,10 @@
import outbox from "./outbox"
import { idsFromValue, send } from "./request"
import { defaultHeaders, idsFromValue, send } from "./request"
import ACTOR from "../actor"
import ActivityPubDB from "./db"
let db:ActivityPubDB
export default async function inbox(activity:any, database:ActivityPubDB) {
export default async function inbox(activity:any, req:Request, database:ActivityPubDB) {
db = database
const date = new Date()
// get the main recipients ([...new Set()] is to dedupe)
@ -22,16 +22,16 @@ export default async function inbox(activity:any, database:ActivityPubDB) {
// TODO: process the activity and update local data
switch(activity.type) {
case "Follow": follow(activity, activity_id); break;
case "Follow": follow(activity, activity_id, req); break;
case "Accept": accept(activity); break;
case "Reject": reject(activity); break;
case "Undo": undo(activity); break;
}
return new Response("", { status: 204 })
return new Response("", { status:204, headers: defaultHeaders(req) })
}
const follow = async (activity:any, activity_id:string) => {
const follow = async (activity:any, activity_id:string, req:Request) => {
// someone is following me
// save this follower locally
db.createFollower(activity_id, activity.actor, activity.published || new Date().toISOString())
@ -42,7 +42,7 @@ const follow = async (activity:any, activity_id:string) => {
actor: ACTOR.id,
to: [activity.actor],
object: activity,
}, db);
}, req, db);
}
const undo = async (activity:any) => {

View file

@ -1,10 +1,10 @@
import { fetchObject, idsFromValue, send } from "./request"
import { defaultHeaders, fetchObject, idsFromValue, send } from "./request"
import ACTOR from "../actor"
import ActivityPubDB, { Activity } from "./db"
let db:ActivityPubDB
export default async function outbox(activity:any, database:ActivityPubDB):Promise<Response> {
export default async function outbox(activity:any, req:Request, database:ActivityPubDB):Promise<Response> {
db = database
const date = new Date()
const activity_id = `${date.getTime().toString(32)}`
@ -60,7 +60,7 @@ export default async function outbox(activity:any, database:ActivityPubDB):Promi
else if (to) send(to, activity)
})
return new Response("", { status: 201, headers: { location: activity.id } })
return new Response("", { status: 201, headers: { ...defaultHeaders(req), location: activity.id } })
}
async function outboxSideEffect(activity_id:string, activity:Activity) {

View file

@ -10,6 +10,21 @@ export function idsFromValue(value:any):string[] {
return []
}
export function defaultHeaders(req:Request) {
const headers:any = {
'Access-Control-Allow-Origin': req.headers.get('Origin') || '*',
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, DELETE',
'Access-Control-Max-Age': '86400',
'Access-Control-Allow-Credentials': true,
'Content-Type': 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'
}
let h
if (h = req.headers.get('Access-Control-Request-Headers'))
headers['Access-Control-Allow-Headers'] = 'Accept, Content-Type, Authorization, Signature, Digest, Date, Host'
return headers
}
// this function adds / modifies the appropriate headers for signing a request, then calls fetch
export function signedFetch(url: string | URL | Request, init?: FetchRequestInit): Promise<Response>
{