Skip to content

Auth: core building blocks — token generation, repositories, clock#45

Open
RandyJDean wants to merge 1 commit into
07-09-auth_add_magic-link_session_migrations_and_runtime_datasourcefrom
07-09-auth_core_building_blocks_token_generation_repositories_clock
Open

Auth: core building blocks — token generation, repositories, clock#45
RandyJDean wants to merge 1 commit into
07-09-auth_add_magic-link_session_migrations_and_runtime_datasourcefrom
07-09-auth_core_building_blocks_token_generation_repositories_clock

Conversation

@RandyJDean

Copy link
Copy Markdown
Contributor
  • TokenGenerator mints 256-bit base64url tokens and stores only SHA-256
    hex digests
  • JdbcClient repositories (first runtime DB access in the repo):
    magic_link_tokens CRUD with an atomic consume, and the auth domain's
    minimal view of members incl. race-safe shell insert
  • Injectable UTC Clock so expiry logic is testable

Co-Authored-By: Claude Fable 5 noreply@anthropic.com

- TokenGenerator mints 256-bit base64url tokens and stores only SHA-256
  hex digests
- JdbcClient repositories (first runtime DB access in the repo):
  magic_link_tokens CRUD with an atomic consume, and the auth domain's
  minimal view of members incl. race-safe shell insert
- Injectable UTC Clock so expiry logic is testable

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

RandyJDean commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

@sonarqubecloud

sonarqubecloud Bot commented Jul 9, 2026

Copy link
Copy Markdown

@RandyJDean RandyJDean marked this pull request as ready for review July 10, 2026 18:47
@RandyJDean RandyJDean requested a review from a team as a code owner July 10, 2026 18:47
@graphite-app graphite-app Bot requested review from Arshadul-Monir and arklian July 10, 2026 18:47
@graphite-app

graphite-app Bot commented Jul 10, 2026

Copy link
Copy Markdown

Graphite Automations

"Request reviewers once CI passes" took an action on this PR • (07/10/26)

2 reviewers were added to this PR based on Henry Chen's automation.


/** Invalidates every outstanding link for an email; called before issuing a new one. */
public void deleteByEmail(final String email) {
jdbc.sql("DELETE FROM magic_link_tokens WHERE email = :email")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NTS: double check what library we standardize on for SQL

.update();
}

public void insert(final UUID id, final String email, final String tokenHash, final Instant expiresAt) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to have a more descriptive name than just insert. insertMagicLinkToken?

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/** Provides the single injectable {@link Clock} so services never call {@code Instant.now()} directly. */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?

*/
@Repository
@RequiredArgsConstructor
public class MemberAccountRepository {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know that this is required to get things working, but this stuff should be in Allison's domain/work.

.param("tokenHash", tokenHash)
.param("now", now.atOffset(ZoneOffset.UTC))
.query(String.class)
.optional();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a note that this will show the same behavior for emails that don't exist and emails that have already consumed a token (empty return value). this is probably fine as long as we don't just always assume these functions' return values to be not existent emails

* concurrent insert of the same email; callers re-select afterwards.
*/
public void insertShell(final UUID id, final String email) {
jdbc.sql("INSERT INTO members (id, email) VALUES (:id, :email) ON CONFLICT (email) DO NOTHING")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we have some kind of way to detect whether or not this succeeded? if an email conflict happens it will fail silently. we should throw some kind of exception here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants