{"id":19099736,"url":"https://github.com/bitwarden/passwordless-server","last_synced_at":"2025-04-05T10:07:55.511Z","repository":{"id":114263075,"uuid":"588244907","full_name":"bitwarden/passwordless-server","owner":"bitwarden","description":"Bitwarden Passwordless.dev infrastructure/backend (API, database, Docker, etc).","archived":false,"fork":false,"pushed_at":"2025-03-28T08:32:24.000Z","size":9688,"stargazers_count":95,"open_issues_count":4,"forks_count":30,"subscribers_count":18,"default_branch":"main","last_synced_at":"2025-03-28T09:19:43.293Z","etag":null,"topics":["api","aspnet","aspnetcore","bitwarden","csharp","dotnet","dotnet-core","sql"],"latest_commit_sha":null,"homepage":"https://bitwarden.com/","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bitwarden.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-12T17:06:43.000Z","updated_at":"2025-03-28T08:32:28.000Z","dependencies_parsed_at":"2023-10-12T19:34:23.409Z","dependency_job_id":"46a54cb4-0f5c-45da-9bb3-268dd9b0c31d","html_url":"https://github.com/bitwarden/passwordless-server","commit_stats":{"total_commits":695,"total_committers":16,"mean_commits":43.4375,"dds":"0.49640287769784175","last_synced_commit":"3fe5d8da946fcfa5164667123ec39e51f7173465"},"previous_names":["bitwarden/passwordless-server"],"tags_count":48,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwarden%2Fpasswordless-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwarden%2Fpasswordless-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwarden%2Fpasswordless-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitwarden%2Fpasswordless-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bitwarden","download_url":"https://codeload.github.com/bitwarden/passwordless-server/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247318744,"owners_count":20919484,"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":["api","aspnet","aspnetcore","bitwarden","csharp","dotnet","dotnet-core","sql"],"created_at":"2024-11-09T03:52:14.278Z","updated_at":"2025-04-05T10:07:55.494Z","avatar_url":"https://github.com/bitwarden.png","language":"C#","readme":"# Bitwarden Passwordless.dev Server\n\n[![Build](https://img.shields.io/github/actions/workflow/status/bitwarden/passwordless-server/main.yml?branch=main)](https://github.com/bitwarden/passwordless-server/actions)\n[![Coverage](https://img.shields.io/codecov/c/github/bitwarden/passwordless-server/main)](https://codecov.io/gh/bitwarden/passwordless-server)\n[![Release](https://img.shields.io/github/release/bitwarden/passwordless-server.svg)](https://github.com/bitwarden/passwordless-server/releases)\n\nBitwarden Passwordless.dev is a software toolkit that helps developers build FIDO2 WebAuthn passkeys features for seamless authentication flows.\n\nUsing Passwordless.dev means there's no need to read extensive W3C specification documentation, determine what cryptography to implement, or worry about managing stored public keys. The team behind Bitwarden will take care of that for you.\n\nThe `passwordless-server` project contains the APIs, database, and other core infrastructure items needed for the backend of all passwordless clients.\n\n## Demo\n\nYou can try a demo web app, powered by Passwordless.dev over at [demo.passwordless.dev](https://demo.passwordless.dev). You can also watch the video below:\n\n[Demo Video](https://github.com/bitwarden/passwordless-server/assets/1935960/71dbaeeb-d7f6-47c4-b2cf-4fd7a6951e32)\n\n## Using Passwordless.dev\n\n### Create an application\n\nTo get started using Passwordless.dev:\n\n1. [Sign up](https://admin.passwordless.dev/signup/) for a free account here.\n2. [Create an application](https://docs.passwordless.dev/guide/get-started.html#create-an-application) in the admin console.\n3. Install the Passwordless.dev [JavaScript Client library](https://github.com/passwordless/passwordless-client-js).\n4. Start building registration and signin flows for your application. Refer to the [Passwordless.dev documentation](https://docs.passwordless.dev) for help.\n\n### Wire up your backend\n\nYou can use Passwordless in conjunction with a variety of different backend platforms — see the [documentation](https://docs.passwordless.dev/guide/backend) for more info. Below is an example of a backend integration using ASP.NET Core and the [Passwordless SDK for .NET](https://github.com/bitwarden/passwordless-dotnet):\n\n```csharp\n// Add Passwordless to your service container\nservices.AddPasswordlessSdk(options =\u003e\n{\n    options.ApiSecret = \"your_api_secret\";\n});\n\n// ...\n\n// Define the /register endpoint\napp.MapGet(\"/register\", async (IPasswordlessClient passwordless, string alias) =\u003e\n{\n    // Get existing user ID from session or create a new user in your database\n    var userId = Guid.NewGuid().ToString();\n    \n    // Provide the userid and an alias to link to this user\n    var payload = new RegisterOptions(userId, alias)\n    {\n        // Optional: Link this user ID to an alias (e.g. email)\n        Aliases = [alias]\n    };\n    \n    try\n    {\n        var tokenRegistration = await passwordless.CreateRegisterTokenAsync(payload);\n    \n        // Return this token to the frontend\n        return Ok(tokenRegistration);\n    }\n    catch (PasswordlessApiException e)\n    {\n        return new JsonResult(e.Details)\n        {\n            StatusCode = (int?)e.StatusCode,\n        };\n    }\n});\n\n// Define the /signin endpoint\napp.MapGet(\"/signin\", async (IPasswordlessClient passwordless, string token) =\u003e\n{\n    try\n    {\n        var verifiedUser = await passwordless.VerifyTokenAsync(token);\n\n        // Sign the user in, set a cookie, etc\n        return Ok(verifiedUser);\n    }\n    catch (PasswordlessApiException e)\n    {\n        return new JsonResult(e.Details)\n        {\n            StatusCode = (int?)e.StatusCode\n        };\n    }\n});\n```\n\n### Wire up your frontend\n\nFinish setting up your registration and signin flows by using the [Passwordless Client](https://github.com/bitwarden/passwordless-client-js) on your frontend. We also provide first-party integrations for several frontend frameworks as well — see the [documentation](https://docs.passwordless.dev/guide/frontend) for more info. Below is a simple example using vanilla JavaScript:\n\n**Install**:\n\n```console\n$ npm install @passwordlessdev/passwordless-client\n```\n\n**Registration endpoint**:\n\n```js\nimport Passwordless from '@passwordlessdev/passwordless-client';\n\n// Instantiate a passwordless client using your API public key.\nconst p = new Passwordless.Client({\n    apiKey: \"myapplication:public:4364b1a49a404b38b843fe3697b803c8\"\n});\n\n// Fetch the registration token from the backend.\nconst backendUrl = \"https://localhost:8002\";\nconst registerToken = await fetch(backendUrl + \"/register?userId\" + userId).then(r =\u003e r.json());\n\n// Register the token with the end-user's device.\nconst { token, error } = await p.register(registerToken);\n```\n\n**Signin endpoint**:\n\n```js\nimport Passwordless from '@passwordlessdev/passwordless-client';\n\n// Instantiate a passwordless client using your API public key.\nconst p = new Passwordless.Client({\n  apiKey: 'myapplication:public:4364b1a49a404b38b843fe3697b803c8'\n});\n\n// Generate an authentication token for the user.\n\n// Option 1: Enable browsers to suggest passkeys for any input that has autofill=\"webauthn\" (only works with discoverable passkeys).\nconst { token, error } = await p.signinWithAutofill();\n\n// Option 2: Enables browsers to suggest passkeys by opening a UI prompt (only works with discoverable passkeys).\nconst { token, error } = await p.signinWithDiscoverable();\n\n// Option 3: Use an alias specified by the user.\nconst email = 'pjfry@passwordless.dev';\nconst { token, error } = await p.signinWithAlias(email);\n\n// Option 4: Use a userId if already known, for example if the user is re-authenticating.\nconst userId = '107fb578-9559-4540-a0e2-f82ad78852f7';\nconst { token, error } = await p.signinWithId(userId);\n\nif (error) {\n  console.error(error);\n  // { errorCode: \"unknown_credential\", \"title\": \"That credential is not registered with this website\", \"details\": \"...\"}\n}\n\n// Call your backend to verify the token.\nconst backendUrl = 'https://localhost:8002'; // Your backend\nconst verifiedUser = await fetch(backendUrl + '/signin?token=' + token).then((r) =\u003e r.json());\nif (verifiedUser.success === true) {\n  // If successful, proceed!\n  // verifiedUser.userId = \"107fb578-9559-4540-a0e2-f82ad78852f7\";\n}\n```\n\n## Contribute to Passwordless.dev\n\nWe welcome code contributions! Please commit any pull requests against the `main` branch. All changes require tests that prove the intended behavior. Please note that large code changes and units of work are less likely to be merged because of the review burden. \n\nSecurity audits and feedback are welcome. Please open an issue or email us privately if the report is sensitive in nature. You can read our security policy in the [SECURITY.md](SECURITY.md) file. We also run a program on HackerOne.\n\nNo grant of any rights in the trademarks, service marks, or logos of Bitwarden is made (except as may be necessary to comply with the notice requirements as applicable), and use of any Bitwarden trademarks must comply with Bitwarden Trademark Guidelines.\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md)\n\n## Self-hosting\n\nSee the [self-hosting directory](self-host) for instructions on how to self-host Passwordless.dev.\n\n## Need support?\n\nIf you need support from the Passwordless.dev team, send us a message at support@passwordless.dev.\n","funding_links":[],"categories":["api","sql"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitwarden%2Fpasswordless-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbitwarden%2Fpasswordless-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitwarden%2Fpasswordless-server/lists"}