Skip to main content

Session Lifecycle

This page explains how Mimeeq authentication sessions are established, maintained, and terminated — and what that means for pricing, features, and your integration code.

Sign-In Flow

Mimeeq supports two ways to sign users in: the built-in mmq-auth UI component and the programmatic signIn() method. They follow different validation paths.

┌─────────────────────────────────────────────────────────────────────┐
│ Sign-In Flow │
│ │
│ User submits credentials │
│ │ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ Credential check │── Fail ──► AuthError │
│ │ (email + password) │ (NotAuthorizedException, │
│ └────────┬────────────┘ UserNotFoundException, etc.) │
│ │ Pass │
│ ▼ │
│ ┌────────────────────┐ ┌────────────────────────────┐ │
│ │ mmq-auth component │ │ signIn() programmatic │ │
│ │ │ │ │ │
│ │ ► Runs customer │ │ ► Returns UserData │ │
│ │ access check │ │ ► NO customer access check │ │
│ │ ► User must be │ │ ► Caller responsible for │ │
│ │ Admin, or │ │ any access enforcement │ │
│ │ Partner for this│ │ │ │
│ │ customer │ └─────────────┬──────────────┘ │
│ └────────┬───────────┘ │ │
│ │ │ │
│ ┌─────┴─────┐ │ │
│ │ │ │ │
│ Access? No access │ │
│ │ │ │ │
│ │ Session terminated │ │
│ │ NoAccess error shown │ │
│ │ mimeeq-user-signed-out │ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ mimeeq-user-signed-in Session active │
│ Session active │
└─────────────────────────────────────────────────────────────────────┘

Using the mmq-auth Component

When a user signs in through the mmq-auth component, two checks happen in sequence:

  1. Credential verification — the email and password are validated. If incorrect, an AuthError is returned with the appropriate error code.

  2. Customer access check — if credentials are valid, the user's account is checked for access to the current customer context. The user must belong to the customer as an admin or partner. If they don't have access, the session is immediately terminated and a NoAccess error state is shown in the UI.

If both checks pass, mimeeq-user-signed-in is dispatched and the session is active.

Using mimeeqAuth.authorization.signIn() Programmatically

The programmatic signIn() method performs credential verification but does not run the customer access check. It returns a UserData object on success or an AuthError on failure.

const result = await mimeeqAuth.authorization.signIn(email, password, customerId);

if (result && 'name' in result) {
// AuthError — check result.name for the error code
console.error(result.name, result.message);
} else {
// UserData — session is active
console.log('Signed in:', result.email);
}

The optional customerId parameter provides context during authentication. If you need to enforce customer-scoped access when using programmatic sign-in, you are responsible for implementing that check after signIn() returns.

Rate Limiting

To protect against brute-force attacks, sign-in attempts are rate limited. After repeated consecutive failed attempts, further sign-in requests are blocked temporarily. The user receives a LimitExceededException error during the lockout period and must wait before trying again. There is no way to bypass this from the client side.

Password Recovery

The forgot password flow always returns a generic success response regardless of whether the email address exists in the system. This is intentional — Mimeeq does not disclose whether a given email is registered.

Token Lifecycle

Mimeeq sessions are maintained by two tokens:

TokenLifetimePurpose
Access token1 hourAuthenticates requests made by the embed
Refresh token3 monthsObtains new access tokens silently
  Sign In


Access Token (1h) ◄──── Refresh ◄──── Refresh Token (3 months)
│ ▲
│ expires │ automatic
│ │ (≤60s before expiry)
▼ │
Token refresh ──────────────┘

│ Refresh token expired?

├── No ──► New access token, session continues

└── Yes ──► Session expired, user must sign in again

Token refresh is handled automatically — you do not need to manage it. The getToken() and getUserData() methods always fetch a fresh token when the refresh token is valid. The embed's request layer also proactively refreshes tokens that are close to expiry (within 60 seconds) before making requests.

In practice, a user who signs in once will remain authenticated for up to 3 months without any interaction required. After the refresh token expires, the next request requiring authentication will fail and the user will need to sign in again.

Session Expiry and Pricing Fallback

When a session expires or a user signs out while a configurator is already loaded, the impact depends on what type of data the embed needs. Resources that were loaded at startup are cached and remain available. Live data that requires authentication falls back to the unauthenticated state.

  Authenticated Session Active

│ Product loaded:
│ ► 3D models, meshes, scenes ──── cached ✓
│ ► Materials, images ──────────── cached ✓
│ ► Rules (standard + modular) ─── cached ✓
│ ► Embed template config ──────── cached ✓
│ ► Custom fields, custom UI ───── cached ✓
│ ► Customer / template data ───── cached ✓


Session Expires / Sign Out

│ Still works:
│ ► Option selection, configuration changes
│ ► 3D scene interaction (rotate, zoom)
│ ► History (undo/redo)

│ Falls back:
│ ► Pricing → reverts to public pricing
│ ► Company-specific price lists → lost
│ ► Currency / VAT from company → reverts to public defaults
│ ► Restricted products → no longer accessible on reload
│ ► Favourites / saved scenes → read-only until re-auth
│ ► Basket (if login-required) → add-to-cart disabled
│ ► File downloads (if restricted) → unavailable
│ ► 3D export (if restricted + enabled on product) → button hidden

└──► User signs in again → full authenticated state restored

Pricing Fallback in Detail

The most significant consequence of session expiry is the pricing transition. While authenticated, the configurator may be showing company-specific pricing — potentially in a different currency, with different VAT rules, and from a different price list than what public visitors see.

Once the session is no longer valid, all pricing requests fall back to public pricing. This means:

  • The price list resolves from the embed template's Public Price List Group instead of the company assignment
  • Currency may change (e.g., from EUR back to USD)
  • VAT display may change (e.g., from inclusive to exclusive)
  • Price type reverts to whatever is set on the public group

This transition happens silently — the configurator continues to display prices, but they are now public prices. The pricing.prices observer will emit the new values as they update.

tip

If your integration relies on authenticated pricing, listen for mimeeq-user-signed-out and prompt the user to sign back in rather than letting them continue with public pricing silently.

document.addEventListener('mimeeq-user-signed-out', () => {
// Authenticated pricing is no longer active
showReauthPrompt('Your session has expired. Sign in to see your pricing.');
});

What About Already-Loaded Products?

A product that has already been loaded and rendered will continue to work interactively after session expiry. Option selection, 3D manipulation, and configuration history all operate on cached data and do not require ongoing authentication.

However, if the user navigates to a different product or reloads the page, products with Restricted or Private privacy will no longer load. The embed will render nothing — no error, just an empty space.

Authentication Events

Listen for these events to keep your application's state synchronized with the authentication state:

EventPayloadWhen it fires
mimeeq-auth-loadedAuth library is initialized and ready to use
mimeeq-user-signed-in{ firstName, lastName, email }Session successfully established
mimeeq-user-signed-outSession terminated (explicit sign-out or NoAccess enforcement)
mimeeq-login-successLoginSuccessEventPayloadLogin UI completed successfully
mimeeq-logout-successLogout UI completed

Waiting for the Auth Library

The auth library loads asynchronously. Wait for mimeeq-auth-loaded before calling any mimeeqAuth methods:

document.addEventListener('mimeeq-auth-loaded', () => {
// Safe to use mimeeqAuth methods
mimeeqAuth.authorization.getUserData().then((user) => {
if (user && !('name' in user)) {
updateUI('authenticated', user);
} else {
updateUI('anonymous');
}
});
});

Tracking Auth State Changes

// Respond to sign-in
document.addEventListener('mimeeq-user-signed-in', (event) => {
const { firstName, lastName, email } = event.detail;
showUserGreeting(firstName);
enableAuthenticatedFeatures();
});

// Respond to sign-out or session expiry
document.addEventListener('mimeeq-user-signed-out', () => {
clearUserGreeting();
disableAuthenticatedFeatures();
});
note

mimeeq-user-signed-in fires even in the NoAccess path — when a user's credentials are valid but they don't have access to the current customer, the sign-in event fires briefly before mimeeq-user-signed-out follows immediately. If you are using these events to drive application state, treat mimeeq-user-signed-out as the authoritative signal for the final session state.

Authentication Errors

Sign-in and session methods return an AuthError object when something goes wrong. The presence of a name field on the result distinguishes errors from success:

const result = await mimeeqAuth.authorization.signIn(email, password);

if (result && 'name' in result) {
// result is an AuthError
switch (result.name) {
case 'NotAuthorizedException':
showError('Incorrect email or password.');
break;
case 'LimitExceededException':
showError('Too many attempts. Please wait and try again.');
break;
case 'UserNotConfirmedException':
showError('Please verify your email address first.');
break;
default:
showError(result.message);
}
} else {
// result is UserData — sign-in succeeded
}

Error Codes

CodeWhen it occurs
NotAuthorizedExceptionIncorrect email or password
UserNotFoundExceptionNo account exists for this email
UserNotConfirmedExceptionAccount exists but email verification has not been completed
UserAlreadyAuthenticatedExceptionA sign-in was attempted while a session is already active
NoAccessCredentials were valid but the user has no access to the current customer
LimitExceededExceptionToo many failed sign-in attempts — the account is temporarily locked
CodeMismatchExceptionThe verification code provided during password reset is incorrect or expired
NetworkErrorA connectivity issue prevented the request from completing
emptyUsernameEmail field was empty
emptyPasswordPassword field was empty
emptyCodeVerification code field was empty during password reset

Checking Session State

You can check whether a user is currently signed in at any time:

// Get current user data (returns UserData or null)
const user = await mimeeqAuth.authorization.getUserData();

if (user && !('name' in user)) {
console.log('Signed in as:', user.email);
} else {
console.log('No active session');
}

// Get the current access token (for custom API calls)
const token = await mimeeqAuth.authorization.getToken();

Both getUserData() and getToken() automatically refresh the access token if needed. They return fresh data as long as the refresh token is still valid.

Sign-Out

Signing out terminates the session and clears all tokens:

const result = await mimeeqAuth.authorization.signOut();

if (result === true) {
// Session terminated successfully
window.location.reload(); // Reset application state
}
tip

Reloading the page after sign-out ensures the application state is completely reset — cached authenticated data is cleared and the configurator reinitializes in the unauthenticated context.

Next Steps