@@ -9,6 +9,7 @@ import { getTypeId, lookupObject } from "@fedify/vocab";
99import {
1010 assert ,
1111 assertEquals ,
12+ assertExists ,
1213 assertFalse ,
1314 assertInstanceOf ,
1415 assertNotEquals ,
@@ -299,8 +300,19 @@ test({
299300 new URL ( "https://example.com/nodeinfo/2.1" ) ,
300301 ) ;
301302
303+ assertThrows (
304+ ( ) =>
305+ createFederation < number > ( {
306+ kv : new MemoryKvStore ( ) ,
307+ } ) . setActorDispatcher ( "/users/{identifier}" , ( ) => null )
308+ . mapActorAlias ( "/actor/{id}" as `/${string } `, "instance" ) ,
309+ RouterError ,
310+ "Path for actor alias must have no variables." ,
311+ ) ;
312+
302313 federation
303314 . setActorDispatcher ( "/users/{identifier}" , ( ) => new vocab . Person ( { } ) )
315+ . mapActorAlias ( "/bot" , "bot" )
304316 . setKeyPairsDispatcher ( ( ) => [
305317 {
306318 privateKey : rsaPrivateKey2 ,
@@ -317,11 +329,19 @@ test({
317329 ctx . getActorUri ( "handle" ) ,
318330 new URL ( "https://example.com/users/handle" ) ,
319331 ) ;
332+ assertEquals (
333+ ctx . getActorUri ( "bot" ) ,
334+ new URL ( "https://example.com/bot" ) ,
335+ ) ;
320336 assertEquals ( ctx . parseUri ( new URL ( "https://example.com/" ) ) , null ) ;
321337 assertEquals (
322338 ctx . parseUri ( new URL ( "https://example.com/users/handle" ) ) ,
323339 { type : "actor" , identifier : "handle" } ,
324340 ) ;
341+ assertEquals (
342+ ctx . parseUri ( new URL ( "https://example.com/bot" ) ) ,
343+ { type : "actor" , identifier : "bot" } ,
344+ ) ;
325345 assertEquals ( ctx . parseUri ( null ) , null ) ;
326346 assertEquals (
327347 await ctx . getActorKeyPairs ( "handle" ) ,
@@ -1132,6 +1152,7 @@ test("Federation.fetch()", async (t) => {
11321152 } ) ;
11331153 } ,
11341154 )
1155+ . mapActorAlias ( "/bot" , "bot" )
11351156 . setKeyPairsDispatcher ( ( ) => {
11361157 return [
11371158 { privateKey : rsaPrivateKey2 , publicKey : rsaPublicKey2 . publicKey ! } ,
@@ -1170,6 +1191,50 @@ test("Federation.fetch()", async (t) => {
11701191 assertEquals ( response . status , 406 ) ;
11711192 } ) ;
11721193
1194+ await t . step ( "GET actor alias" , async ( ) => {
1195+ const { federation, dispatches } = createTestContext ( ) ;
1196+
1197+ const response = await federation . fetch (
1198+ new Request ( "https://example.com/bot" , {
1199+ method : "GET" ,
1200+ headers : {
1201+ "Accept" : "application/activity+json" ,
1202+ } ,
1203+ } ) ,
1204+ { contextData : undefined } ,
1205+ ) ;
1206+
1207+ assertEquals ( dispatches , [ "bot" ] ) ;
1208+ assertEquals ( response . status , 200 ) ;
1209+ const body = await response . json ( ) as Record < string , unknown > ;
1210+ assertEquals ( body . id , "https://example.com/bot" ) ;
1211+ assertEquals ( body . preferredUsername , "bot" ) ;
1212+ } ) ;
1213+
1214+ await t . step ( "WebFinger for actor alias" , async ( ) => {
1215+ const { federation } = createTestContext ( ) ;
1216+
1217+ const response = await federation . fetch (
1218+ new Request (
1219+ "https://example.com/.well-known/webfinger?resource=acct:bot@example.com" ,
1220+ ) ,
1221+ { contextData : undefined } ,
1222+ ) ;
1223+
1224+ assertEquals ( response . status , 200 ) ;
1225+ const body = await response . json ( ) as Record < string , unknown > ;
1226+ assertEquals ( body . subject , "acct:bot@example.com" ) ;
1227+ assertExists ( body . links ) ;
1228+ assert ( Array . isArray ( body . links ) ) ;
1229+ const selfLink = ( body . links as Record < string , unknown > [ ] ) . find ( ( l ) =>
1230+ l . rel === "self"
1231+ ) ;
1232+ assertExists ( selfLink ) ;
1233+ assertEquals ( selfLink . href , "https://example.com/bot" ) ;
1234+ assertExists ( body . aliases ) ;
1235+ assert ( ( body . aliases as string [ ] ) . includes ( "https://example.com/bot" ) ) ;
1236+ } ) ;
1237+
11731238 await t . step ( "POST with application/json" , async ( ) => {
11741239 const { federation, inbox } = createTestContext ( ) ;
11751240
0 commit comments