{"id":22509824,"url":"https://github.com/mattduffy/webfinger","last_synced_at":"2025-03-28T00:24:53.038Z","repository":{"id":81652074,"uuid":"585365939","full_name":"mattduffy/webfinger","owner":"mattduffy","description":"Webfinger (rfc 7033) server for node.js apps","archived":false,"fork":false,"pushed_at":"2023-12-30T05:15:40.000Z","size":144,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-02T02:23:38.790Z","etag":null,"topics":["acct-uri","host-meta","rfc-6415","rfc-7033","rfc-7565","webfinger"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mattduffy.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2023-01-05T01:37:22.000Z","updated_at":"2023-01-05T01:43:57.000Z","dependencies_parsed_at":null,"dependency_job_id":"9ea33308-32ed-4464-a3a2-ac51622e9501","html_url":"https://github.com/mattduffy/webfinger","commit_stats":{"total_commits":27,"total_committers":1,"mean_commits":27.0,"dds":0.0,"last_synced_commit":"b6c1b75fa8dbbfe7c4fbf10de9b5fd7872a5b9be"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattduffy%2Fwebfinger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattduffy%2Fwebfinger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattduffy%2Fwebfinger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattduffy%2Fwebfinger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mattduffy","download_url":"https://codeload.github.com/mattduffy/webfinger/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245945787,"owners_count":20698312,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["acct-uri","host-meta","rfc-6415","rfc-7033","rfc-7565","webfinger"],"created_at":"2024-12-07T01:33:26.805Z","updated_at":"2025-03-28T00:24:53.015Z","avatar_url":"https://github.com/mattduffy.png","language":"JavaScript","readme":"## Webfinger Middleware for Koa\n\nThis package for Node.js exports a middleware function for Koa applications that provides a Webfinger ([RFC 7033](https://www.rfc-editor.org/rfc/rfc7033#page-14)) URL, ```/.well-known/webfinger?resource={uri}```.  The default use for this package is to supply a Mastodon-compatible webfinger acct: query, which can lookup user accounts on the local server or a remote server, if the hostname portion of the acct: param differs.\n\n### Using Webfinger\n\n```bash\nnpm install --save @mattduffy/webfinger\n```\n\n```javascript\nimport { wellknownWebfinger } from '@mattduffy/webfinger'\n// add to exisiting koa app instance\nconst options = {\n  // TODO\n  // mongodb = \u003cmongodbClient|null\u003e,\n  // redis = \u003credisClient|null\u003e,\n  // hostname = example.org,\n}\napp.use(wellknownWebfinger(options, app))\n```\n\nTo lookup a user's profile on the website https://social.example.org, sending an HTTP GET request to the URL:\n```javascript\nhttps://social.example.org/.well-known/webfinger?resource=acct:@user123@social.example.org\n```\ncould return the following output (if user123 exists):\n```\nHTTP/1.1 200 OK\nContent-Length: 683\nContent-Type: application/json; charset=utf-8\nAccess-Control-Allow-Origin: *\nAccess-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept\nAccess-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS\nVary: Origin\n\n{\n  subject: \"acct:user123@social.example.org\",\n  aliases: [\n    \"http://social.example.org/@user123\",\n    \"http://social.example.org/user/user123\"\n  ],\n  links: [\n    {\n      rel: \"http://webfinger.net/rel/profile-page\",\n      type: \"text/html; charset=utf-8\",\n      href: \"http://social.example.org/@user123\"\n    },\n    {\n      rel: \"http://webfinger.net/rel/avatar\",\n      type: \"image\",\n      href: \"http://192.168.1.252:3333/i/accounts/avatars/missing.png\"\n    },\n    {\n      rel: \"self\",\n      type: \"application/activity+json\",\n      href: \"http://social.example.org/user/user123\"\n    },\n    {\n      rel: \"http://ostatus.org/schema/1.0/subscribe\",\n      template: \"http://social.example.org/authorize_interaction?uri={uri}\"\n    }\n  ]\n}\n```\nIf the ```resource``` query parameter is missing or malformed, the server will return \n```\nHTTP/1.1 400 Bad Request\nContent-Type: text/plain; charset=utf-8\nAccess-Control-Allow-Origin: *\nAccess-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept\nAccess-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS\nVary: Origin\n\nBad request\n```\n\nIf there is on user account found, the server will return \n```\nHTTP/1.1 404 Not Found\nContent-Type: text/plain; charset=utf-8\nAccess-Control-Allow-Origin: *\nAccess-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept\nAccess-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS\nVary: Origin\n\nuser123 not found\n```\n\n\n### Webfinger \nIt is possible to directly import the Webfinger class that is used by the middleware function, to manually make webfinger queries.  Once an instance has been created, use the ```finger()``` method to make the query.  This is an **Async/Await** method.\n```javascript\nimport { Webfinger } from '@mattduffy/webfinger'\nconst options = {\n  // fill in the required options needed to make queries...\n}\nconst web = new Webfinger(options)\nconst user1 = await web.finger()\n```\n\n### Host-Meta\nHost-Meta does not seem to really be much of a thing anymore.  Mastodon might be the main consumer of host-meta queries, but even then, I don't think it is completely required.  In order to provide a Mastodon-compatible version of Webfinger, this package also includes a Koa appliation middlware function that is able to return either ```xrd+xml``` or ```jrd+json``` responses.\n```javascript\nimport { wellknownHostmeta } from '@mattduffy/webfinger'\napp.use(wellknownHostmeta({}, app))\n```\nAn HTTP GET request to ```https://social.example.org/.well-known/host-meta``` will return the following output:\n```javascript\nHTTP/1.1 200 OK\nAccess-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept\nAccess-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS\nAccess-Control-Allow-Origin: *\nVary: Origin\n\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cXRD xmlns=\"http://docs.oasis-open.org/ns/xri/xrd-1.0\"\u003e\n  \u003cLink rel=\"lrdd\" template=\"https:///social.example.org/.well-known/webfinger?resource={uri}\"/\u003e\n\u003c/XRD\u003e\n```\nBut, really, nobody should be using XML at this point, so the better option is to request JSON output:\n```https://social.example.org/.well-known/host-meta.json```\n```javascript\nHTTP/1.1 200 OK\nAccess-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept\nAccess-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS\nAccess-Control-Allow-Origin: *\nContent-Type: application/json; charset=utf-8\nVary: Origin\n\n{\n    \"links\": [\n        {\n            \"rel\": \"lrdd\",\n            \"template\": \"https:///social.example.org/.well-known/webfinger?resource={uri}\"\n        }\n    ]\n}\n```\n\n### Get\nThe Webfinger class uses a separatly exported function called ```get()```.  This is an **Async/Await** function wrapping the native Node http or https classes.\n```javascript\nimport { get } from '@mattduffy/webfinger'\nconst url = 'https://social.example.org/.well-known/webfinger?resource=acct:@user123@mastodon.social'\nconst user = await get(url)\n```\nOutput from the ```get()``` function is an object literal in the form:\n```javascript\n{\n  content: {...},\n  headers: {...},\n  statusCode: \u003cHTTP Code\u003e,\n  statusMessage: \u003cHTTP Status Message\u003e,\n }\n ```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmattduffy%2Fwebfinger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmattduffy%2Fwebfinger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmattduffy%2Fwebfinger/lists"}