{"id":21980594,"url":"https://github.com/stormpath/stormpath-spring-boot-invite-example","last_synced_at":"2025-10-14T23:13:57.082Z","repository":{"id":66357050,"uuid":"49928692","full_name":"stormpath/stormpath-spring-boot-invite-example","owner":"stormpath","description":null,"archived":false,"fork":false,"pushed_at":"2017-03-06T16:31:35.000Z","size":585,"stargazers_count":5,"open_issues_count":1,"forks_count":1,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-06-06T20:11:22.679Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","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/stormpath.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,"zenodo":null}},"created_at":"2016-01-19T05:27:38.000Z","updated_at":"2024-11-02T13:02:24.000Z","dependencies_parsed_at":"2023-02-22T03:30:15.523Z","dependency_job_id":null,"html_url":"https://github.com/stormpath/stormpath-spring-boot-invite-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/stormpath/stormpath-spring-boot-invite-example","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stormpath%2Fstormpath-spring-boot-invite-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stormpath%2Fstormpath-spring-boot-invite-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stormpath%2Fstormpath-spring-boot-invite-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stormpath%2Fstormpath-spring-boot-invite-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stormpath","download_url":"https://codeload.github.com/stormpath/stormpath-spring-boot-invite-example/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stormpath%2Fstormpath-spring-boot-invite-example/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279023013,"owners_count":26087393,"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","status":"online","status_checked_at":"2025-10-14T02:00:06.444Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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-29T17:12:14.130Z","updated_at":"2025-10-14T23:13:57.077Z","avatar_url":"https://github.com/stormpath.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Spring Boot Invite Example\n\nThere are times when you want to invite users to your application. This repo walks you through doing just that with a\nSpring Boot Application.\n\n**Note**: It is assumed that you are familiar with the basics of working with Stormpath. \nCheck out our [Product Guide](https://docs.stormpath.com/rest/product-guide/latest/) for more information.\n\n### Setup\n\nThis example uses an approach that involves two Directories:\n\n* One used for invited Accounts; We'll call it: `InviteExample - Invites`\n* One used for active, registered accounts; We'll call it: `InviteExample - Main`\n\n`InviteExample - Main` will be the `Default Account Location` for the Application.\n\nHere's the invitation flow:\n\n* Hit an endpoint in your Spring Boot application to invite a user.\n* The invited user receives an email with a link. The link hits another endpoint in your Spring Boot application and\n  passes in the verification token.\n* When the link is clicked, your Spring Boot application verifies that token. This has the side effect of transitioning\n  the account in the `InviteExample - Invites` Directory from `unverified` to `enabled`\n* After the token is verified, the invited user is redirected to `/register`\n* Since the `InviteExample - Main` Directory is the Default Account Location for the Spring Boot application, when the\n  user registers, their Account will be in this Directory.\n* Note: If Email Verification is enabled on the `InviteExample - Main` Directory, the user will receive another email\n  when they register to verify their account.\n\nThis is what it looks like in the Application definition:\n\n![application](application.png)\n\nWe'll alter some defaults in the `InviteExample - Invites` Directory:\n\n* Enable the `Verification Email` Workflow\n* Customize the `Link Base URL`\n* Customize the verification email template\n\nWe will point the `Link Base URL` to *your* Spring Boot application as shown below. For the purposes of this example,\n`http://localhost:8080/emailVerificationTokens`.\n\nThe purpose of customizing the verification email, is that it will be sent to invited users when they are invited.\n\n![verification workflow](verification1.png)\n\n![verification workflow 2](verification2.png)\n\n### The Code\n\nThe key to this approach is that the `InviteController` is configured with the `inviteDirectory`.\n\n```\n@Value(\"#{ @environment['stormpath.invite.directory.href'] }\")\nString inviteDirectoryHref;\n\n@PostConstruct\nvoid postConstruct() {\n    inviteDirectory = client.getResource(inviteDirectoryHref, Directory.class);\n}\n```\n\nInvited Accounts are created in this Directory. This is shown in the `invite` method below.\n\n```\n@RequestMapping(\"/invite\")\npublic String invite(\n    @RequestParam String email, @RequestParam String givenName, @RequestParam String surName, Model model\n) {\n    Account account = client.instantiate(Account.class);\n\n    account\n        .setEmail(email)\n        .setGivenName(givenName)\n        .setSurname(surName)\n        .setPassword(\"A0\" + UUID.randomUUID().toString());\n\n    inviteDirectory.createAccount(account);\n\n    model.addAttribute(\"email\", email);\n\n    return \"invite_confirm\";\n}\n```\n\n*Note*: It would not be very efficient to invite people in bulk this way. The method above could easily be replaced with\na method that receives and parses a CSV file or some other formatted file for bulk processing.\n\nLine 13 above is the key - `inviteDirectory.createAccount(account)`. It creates the Account in the \n`InviteExample - Invites` Directory.\n\nHere's the secret sauce: Because of the enabled Email Verification Workflow on the Directory, the user will receive the \ninvite email template at the specified email address.\n\nA random password is set on the Account. It is not intended that the user will ever login using this account. The \n`A0` is prepended to conform to the default password rules for Stormpath Directories.\n\nBrowsing to `/invite` endpoint like so: \n`http://localhost:8080/invite?email=micah%2Buser1%40stormpath.com\u0026givenName=Micah\u0026surName=Silverman` \nwould cause `micah+user1@stormpath.com` to be invited.\n\n*Note*: For this example, make sure you url encode the email address you pass in.\n\nWhen the user clicks on the link in the email, it hits your Spring Boot application:\n\n```\n@RequestMapping(\"/emailVerificationTokens\")\npublic String verify(@RequestParam String sptoken) {\n    client.verifyAccountEmail(sptoken);\n\n    // if we are here, the account is verified, proceed with registration\n\n    return \"redirect:/register\";\n}\n```\n\nCalling `client.verifyAccountEmail(sptoken)` transitions that Account from `unverified` to `enabled` in the \n`InviteExample - Invites` Directory. The last line redirects the user to `/register`. The Account they create when\nthey register will be in the `InviteExample - Main` Directory.\n\nOne of the benefits of this approach is that you can easily tell which of the invited users have not \"accepted\" the \ninvitation by which Accounts in the `InviteExample - Invites` Directory are still `unverified`.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstormpath%2Fstormpath-spring-boot-invite-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstormpath%2Fstormpath-spring-boot-invite-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstormpath%2Fstormpath-spring-boot-invite-example/lists"}