Skip to main content
Mostafa Effati

About this platform

A working notebook for engineering practice

This is Mostafa Effati’s personal engineering platform: a place to turn hands-on work into clear writing, structured learning, and useful digital products.

Student collaborator

  • Ms Zahra Ehsani

    Former student · platform contributor

    Ms Zahra Ehsani worked on parts of this platform during her studies and brought thoughtful, practical contributions to its development. I'm glad to recognize her work here.

What you will find

  • Long-form articles, books, tutorials, and practical snippets.
  • Courses and guided learning paths built around real engineering work.
  • Case studies, open-source work, experiments, and product releases.

Built deliberately

  • A bilingual Persian and English experience with native RTL support.
  • Theme-aware, keyboard-friendly interfaces with a focused visual language.
  • Content and product changes developed as one versioned system.

The platform is continuously evolving. Some sections are complete products; others are active experiments that improve as the underlying work develops.

Authentication Convergence

OTP, email password, and OAuth should verify differently — then share one user-provisioning and session-establishment path in the identity domain.
Mostafa Effati3 min readsoftware-architecture

Many Auth Methods, One Session Path

Product teams accumulate login methods: phone OTP, email password, Google, maybe Apple later. Each method wants its own controller, its own “create user” copy-paste, its own session quirks.

That is how you get three slightly different definitions of “logged in.”

The architectural rule in this identity BC is simple:

What stays method-specific

MethodVerification concern
Phone OTPShort-lived code in cache, rate limits, contact search token
Email + passwordStrength rules, scrypt verify, lockout counters
OAuth providerID token / JWKS, audience, issuer; never store provider access tokens you do not need
Password resetOpaque reset session in cache; always-safe responses (no email enumeration)

Those concerns belong in command handlers and adapters — not in the session aggregate.

What must be shared

After verification succeeds:

  1. Provision — create user account + contact when this is a first-time identity (or link OAuth to an existing verified email contact)
  2. Establish session — create user account session + refresh family on the current device session
  3. Publish events — registered vs authentication successful / failed

Returning users skip create and still hit the same establish path. New OAuth subjects may link instead of create when a verified email contact already exists.

Layering that keeps secrets out of the UI

ConcernBelongs in
Login screens, OAuth redirect UXFrontend
Provider client secretsNever in the browser
Credential verify, hashing, JWKSIdentity service
Session + refresh issuanceIdentity service
Account linking rulesIdentity service

The frontend forwards proof (OTP code, password, ID token). Identity decides who you are and returns session tokens. Cookies and edge refresh are a delivery concern — not a second source of truth.

Extending without schema thrash

OAuth providers are an adapter registry: new provider = new verifier + enum value. Contact types already live as an aggregate, so email vs phone is not a column war.

Password credentials hang off the email contact (1:1), with failed-attempt and lockout fields. OAuth identities hang off the account with HMAC’d provider subject search tokens — raw subjects are not query keys in the clear.

Why convergence matters

Without a shared establish path you eventually get:

  • OTP users with different session TTL than password users
  • OAuth “login” that forgets device binding
  • Reset flows that never invalidate sessions you thought you revoked

With convergence, every successful authentication means the same thing: a user account session on a known device, with a refresh family, and domain events the rest of the platform can trust.

Next

People and accounts are not the whole world. Organizations, employees, and location are first-class in the same bounded context.

Continue with Organizations and Location.

Related documents

Command menu

↑ ↓to move · Enter to select · Esc to close
Navigation
Actions

Press Esc to close · ⌘K to toggle