{"id":19288189,"url":"https://github.com/openweb-nl/workshop-passwordless","last_synced_at":"2026-02-27T23:11:49.486Z","repository":{"id":259204459,"uuid":"876589823","full_name":"openweb-nl/workshop-passwordless","owner":"openweb-nl","description":null,"archived":false,"fork":false,"pushed_at":"2024-11-14T12:17:32.000Z","size":271,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-11-15T04:22:54.071Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/openweb-nl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-22T08:22:56.000Z","updated_at":"2024-11-14T12:17:35.000Z","dependencies_parsed_at":"2025-02-23T23:35:50.857Z","dependency_job_id":null,"html_url":"https://github.com/openweb-nl/workshop-passwordless","commit_stats":null,"previous_names":["openweb-nl/workshop-passwordless"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/openweb-nl/workshop-passwordless","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openweb-nl%2Fworkshop-passwordless","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openweb-nl%2Fworkshop-passwordless/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openweb-nl%2Fworkshop-passwordless/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openweb-nl%2Fworkshop-passwordless/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/openweb-nl","download_url":"https://codeload.github.com/openweb-nl/workshop-passwordless/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openweb-nl%2Fworkshop-passwordless/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29918973,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-27T19:37:42.220Z","status":"ssl_error","status_checked_at":"2026-02-27T19:37:41.463Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2024-11-09T22:08:20.306Z","updated_at":"2026-02-27T23:11:49.464Z","avatar_url":"https://github.com/openweb-nl.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Workshop PasswordLess\n___\n## Agenda\n- How to start\n- What do we build\n- Examples\n- Presentations\n---\n## How to start\nThis workshop can be done with any Javascript library so pick one and get ready to start.\nProbably most easy to start with a default setup.\n\n### For Angular:\nTo do the workshop with angular use following command:\n\n1. yarn install -g @angular/cli\n2. ng new [your name]\n3. Start project with ng serve\n\n### For React:\nTo do the workshop with react use following steps:\n\n1. yarn install -g npx\n2. npx create-react-app [your name] --template typescript\n3. Start project with: yarn start\n___\n## What do we build \nIn this workshop we will build an application for our user where they don't need to remember passwords to use our web/app. The key goal of this workshop is to think about how to make this friendly and secure for our users.\nSo before you make the deep-dive into the examples (or internet) think about the most important flows users use to interact with your application.\n\n- Account Register\n- Account Login\n- Account Recovery\n- Account Deletion\n\nHow hard/time-consuming are you going to make each step for the user? Is this the best/safest way to let your users interact with your application?\nFor example as a user I don't want to receive an email, sms and push notification for every login I need to do. But pressing the biometric to verify is not that intrusive. (Or can you make it even better?)\n\nAdvance things to think about:\n\n- Is a user his account safe if his email is hacked?\n- What if the user phone got stolen?\n\nThese cases are pretty hard and might be less troubling than the case itself for the user. But it's nice to see if you can find a way to block this. You might need to specify what kind of application you are to add more security. (e.g. bank or supermarket)\n___\n## Examples\nHere are some examples which you can use. \n\n### SMS one-time code\nReading an incoming sms from the browser. This will make it easy to get the code in your website.\n\n`\u003cinput type=\"text\" autocomplete=\"one-time-code\" inputmode=\"numeric\"\u003e`\n\nBut making it automatically is also possible with this:\n\n`navigator.credentials.get({ otp: {transport:['sms']} }).then(otp =\u003e input.value = otp.code);`\n\nSmall not is that the domain should be added to the sms so for example\n\n`123456 example code`\n\n`@openweb.nl #123456`\n\nOn Mac you can create your own website by adding an entry inside your etc/hosts file.\nThere should already be a `127.0.0.1 localhost` add something like `127.0.0.1 passwordless.workshop`\nThan inside your browser you can go to passwordless.workshop and use this as a domain inside the sms.\n(Note, you can send yourself a sms to test this, or ask someone to text you the message)\n\nMore information: \n- https://developer.mozilla.org/en-US/docs/Web/API/OTPCredential\n- https://dev.to/madsstoumann/using-a-single-input-for-one-time-code-352l\n\n### Password Credentials API\nThe credentials api from javascript gives you the option to store a username and password inside the browser.\nI know we want password-less but the password you place in the credential manager doesn't have to be a user password. We can also use it as a token refresher so the user doesn't have to remember anything but the browser can help retrieving it.\n\nCreating a Password Credential: \n\n`const pc = new PasswordCredential({id: \u003cstring\u003e, password: \u003cstring\u003e})`\n\n`await navigator.credentials.store(pc)`\n\nRetrieving this information can be done with 3 options:\n\n`const userCredentials = await navigator.credentials.get({password: true, mediation: \u003cSilent, Optional or Required\u003e});`\n\nWith the flag silent you will retrieve the information without any interaction needed from the user. Optional means the browser decides and Required means the user needs to approve the collection of the credentials.\nNote if you have multiple credentials stored for your website Silent will ask the user which account should be fetched.\n\nMore information: \n- https://developer.mozilla.org/en-US/docs/Web/API/Navigator/credentials\n\n### Passkey creation\nTo make this work properly you might need a password manager to do the heavy lifting al tough it should also work in web only.\n\nStart with creating a challenge code and configuration.\n![img.png](img.png)\n\nAfter you have the configuration you can execute it with:\n![img_1.png](img_1.png)\n\n`const resp = await navigator.credentials.create(createOBJ);`\n\nMore information:\n\n- https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/create\n- https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredentialCreationOptions\n\n## Presentations\nAt the end of the workshop it's nice to see a few demo's and talk about choices we made for `register`, `login`, `reset` and `delete` account.\nLet's see which person or persons made a friendly and secure application!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenweb-nl%2Fworkshop-passwordless","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenweb-nl%2Fworkshop-passwordless","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenweb-nl%2Fworkshop-passwordless/lists"}