MCPcopy
hub / github.com/mainmatter/ember-simple-auth

github.com/mainmatter/ember-simple-auth @v8.3.1 sqlite

repository ↗ · DeepWiki ↗ · release v8.3.1 ↗
346 symbols 808 edges 127 files 41 documented · 12%
README

Ember Simple Auth API docs

CI

Discord

  • Ember Simple Auth supports all Ember.js versions starting with 3.28.
  • Doesn't support IE11
  • Node >=16 is required
  • Supports Embroider see our ember-try scenario and test app for guidance.

[!NOTE] Ember Simple Auth was written and is maintained by Mainmatter and contributors. We offer consulting, training, and team augmentation for Ember.js – check out our website to learn more!

Ember Simple Auth

Logo

Ember Simple Auth is a lightweight library for implementing authentication/ authorization with Ember.js applications. It has minimal requirements with respect to application structure, routes etc. With its pluggable strategies it can support all kinds of authentication and authorization mechanisms.

Table of Contents

Basic Information

Usage

Core Feature Guides

Other Guides

Other Resources

What does it do?

  • it maintains a client side session and synchronizes its state across multiple tabs/windows of the application
  • it authenticates the session against the application's own server, external providers like Facebook etc.
  • it is easily customizable and extensible

How does it work?

Ember Simple Auth consists of 3 main building blocks - the session, a session store and authenticators.

The session service is the main interface to the library. It provides methods for authenticating and invalidating the session as well as for setting and reading session data.

The session store persists the session state so that it survives a page reload. It also synchronizes the session state across multiple tabs or windows of the application so that e.g. a logout in one tab or window also results in a logout in all other tabs or windows of the application.

Authenticators authenticate the session. An application can leverage multiple authenticators to support multiple ways of authentication such as sending credentials to the application's own backend server, Facebook, github etc.

Example App

Ember Simple Auth comes with a test app that implements a complete auth solution including authentication against the application's own server as well as Facebook, authorization of Ember Data requests and error handling. Check out that test app for reference. To start it, run

git clone https://github.com/mainmatter/ember-simple-auth.git
cd ember-simple-auth/packages/test-app
pnpm install && ember serve

and go to http://localhost:4200.

Installation

Installing the library is as easy as:

ember install ember-simple-auth

Upgrading from a pre-3.0 release?

The 3.0 release of ember-simple-auth removes previously deprecated code, introducing some breaking changes, but thankfully there is an v3 upgrade guide.

Upgrading to 4.0 release?

The 4.1 release introduced a session#setup that fixes build issues for typescript and embroider users, due to ESA using initializers. Consult with the guide in order to fix them as well as prepare yourself for v5 release which will make it required. v4 upgrade guide.

Upgrading to 7.0 release?

The 7.0 release introduces a breaking change, it no longer automatically provides a session service and a default session-store. You have explicitly import these files instead. Additional semi-breaking change is how classes provided by us are extended. Please see the guide v7 upgrade guide.

Walkthrough

Once the library is installed, import a session service and a session-store inside your application__.

Add app/services/session.js or app/services/session.ts

import Service from 'ember-simple-auth/services/session';

export default class SessionService extends Service {}

Add app/session-stores/application.js or app/session-stores/application.ts

import AdaptiveStore from 'ember-simple-auth/session-stores/adaptive';

export default class SessionStore extends AdaptiveStore {}

Optional Generic Data argument.

import Service from 'ember-simple-auth/services/session';

type Data = {
  authenticated: {
    // Any data your authenticators return
    id: string;
  }
}

export default class SessionService extends Service<Data> {}

then the session service can be injected wherever needed in the application. In order to display login/logout buttons depending on the current session state, inject the service into the respective controller or component and query its isAuthenticated property in the template:

// app/controllers/application.js
import Controller from '@ember/controller';
import { service } from '@ember/service';

export default class ApplicationController extends Controller {
  @service session;

  …
}
{{!-- app/templates/application.hbs --}}



  …
  {{#if this.session.isAuthenticated}}
    <a {{on "click" this.invalidateSession}}>Logout</a>
  {{else}}
    {{#link-to 'login'}}Login{{/link-to}}
  {{/if}}






  {{outlet}}



In the invalidateSession action call the session service's invalidate method to invalidate the session and log the user out:

// app/controllers/application.js
import Controller from '@ember/controller';
import { service } from '@ember/service';
import { action } from "@ember/object";

export default class ApplicationController extends Controller {
  @service session;

  …

  @action
  invalidateSession() {
    this.session.invalidate();
  }
}

For authenticating the session, the session service provides the authenticate method that takes the name of the authenticator to use as well as other arguments depending on specific authenticator used. To define an authenticator, add a new file in app/authenticators and extend one of the authenticators the library comes with, e.g.:

// app/authenticators/oauth2.js
import OAuth2PasswordGrant from 'ember-simple-auth/authenticators/oauth2-password-grant';

export default class OAuth2Authenticator extends OAuth2PasswordGrant {}

With that authenticator and a login form like

{{!-- app/templates/login.hbs --}}
<form {{on "submit" this.authenticate}}>
  <label for="identification">Login</label>
  <input id='identification' placeholder="Enter Login" value={{this.identification}} {{on "change" this.updateIdentification}}>
  <label for="password">Password</label>
  <input id='password' placeholder="Enter Password" value={{this.password}} {{on "change" this.updatePassword}}>
  <button type="submit">Login</button>
  {{#if this.errorMessage}}


{{this.errorMessage}}


  {{/if}}
</form>

the session can be authenticated with the session service's authenticate method:

// app/controllers/login.js
import Controller from '@ember/controller';
import { service } from '@ember/service';
import { action } from "@ember/object";
import { tracked } from "@glimmer/tracking";

export default class LoginController extends Controller {
  @tracked errorMessage;
  @service session;

  @action
  async authenticate(e) {
    e.preventDefault();
    let { identification, password } = this;
    try {
      await this.session.authenticate('authenticator:oauth2', identification, password);
    } catch(error) {
      this.errorMessage = error.error || error;
    }

    if (this.session.isAuthenticated) {
      // What to do with all this success?
    }
  }

  @action
  updateIdentification(e) {
    this.identification = e.target.value;
  }

  @action
  updatePassword(e) {
    this.password = e.target.value;
  }
}

To make a route in the application accessible only when the session is authenticated, call the session service's requireAuthentication method in the respective route's beforeModel method:

// app/routes/authenticated.js
import Route from '@ember/routing/route';
import { service } from '@ember/service';

export default class AuthenticatedRoute extends Route {
  @service session;

  beforeModel(transition) {
    this.session.requireAuthentication(transition, 'login');
  }
}

This will make the route (and all of its subroutes) transition to the login route if the session is not authenticated. Add the login route in the router like this:

// app/router.js
Router.map(function() {
  this.route('login');
});

It is recommended to nest all of an application's routes that require the session to be authenticated under a common parent route:

// app/router.js
Router.map(function() {
  this.route('login');
  this.route('authenticated', { path: '' }, function() {
    // all routes that require the session to be authenticated
  });
});

To prevent a route from being accessed when the session is authenticated (which makes sense for login and registration routes for example), call the session service's prohibitAuthentication method in the respective route's beforeModel method:

// app/routes/login.js
import Route from '@ember/routing/route';
import { service } from '@ember/service';

export default class LoginRoute extends Route {
  @service session;

  beforeModel(transition) {
    this.session.prohibitAuthentication('index');
  }
}

The session service also provides the handleAuthentication and handleInvalidation methods for handling authentication and invalidation of the session (which not only happens when the user submits the login form or clicks the logout button but also when the session is authenticated or invalidated in another tab or window of the application). The handleAuthentication method will transition to a configurable route while the handleInvalidation method will reload the page to clear all potentially sensitive data from memory. In order to customize those behaviours, these methods can be overridden when the application defines its own session service that extends the one provided by Ember Simple Auth.

To add authorization information to requests, you can use the session service to check if the session is authenticated and access authentication/authorization data, e.g. a token:

// app/adapters/application.js
import JSONAPIAdapter from '@ember-data/adapter/json-api';
import { computed } from '@ember/object';
import { service } from '@ember/service';

export default class ApplicationAdapter extends JSONAPIAdapter {
  @service session;

  @computed('session.{data.authenticated.access_token,isAuthenticated}')
  get headers() {
    let headers = {};
    if (this.session.isAuthenticated) {
      // OAuth 2
      headers['Authorization'] = `Bearer ${this.session.data.authenticated.access_token}`;
    }

    return headers;
  }
}

The Session Service

The session service is the main interface to the library. It defines the authenticate, invalidate and authorize methods as well as the session events as shown above.

It also provides the isAuthenticated as well as the data properties. The latter can be used to get and set the session data. While the special authenticated section in the session data contains the data that was acquired by the authenticator when it authenticated the session and is read-only, all other session data can be written and will also remain in the session after it is invalidated. It can be used to store all kinds of client side data that needs to be persisted and synchronized across tabs and windows, e.g.:

this.session.set('data.locale', 'de');

Authenticators

__Authenticators imp

Extension points exported contracts — how you extend this code

AuthenticatorEvents (Interface)
(no doc)
packages/ember-simple-auth/src/authenticators/base.ts
Window (Interface)
(no doc)
packages/test-app/types/global.d.ts
OAuth2Response (Interface)
(no doc)
packages/ember-simple-auth/src/authenticators/oauth2-password-grant.ts
Registry (Interface)
(no doc)
packages/test-app/app/services/session.ts
SessionEvents (Interface)
(no doc)
packages/ember-simple-auth/src/session-stores/base.ts

Core symbols most depended-on inside this repo

set
called by 77
packages/ember-simple-auth/src/services/session.ts
restore
called by 72
packages/ember-simple-auth/src/session-stores/cookie.ts
authenticate
called by 49
packages/test-app/app/authenticators/torii.js
invalidate
called by 33
packages/ember-simple-auth/src/services/session.ts
trigger
called by 30
packages/ember-simple-auth/src/authenticators/base.ts
on
called by 28
packages/ember-simple-auth/src/authenticators/base.ts
persist
called by 25
packages/ember-simple-auth/src/session-stores/cookie.ts
requireAuthentication
called by 18
packages/ember-simple-auth/src/services/session.ts

Shape

Method 138
Class 111
Function 92
Interface 5

Languages

TypeScript100%

Modules by API surface

packages/ember-simple-auth/src/internal-session.js22 symbols
packages/ember-simple-auth/src/session-stores/cookie.ts21 symbols
packages/ember-simple-auth/src/services/session.ts17 symbols
packages/ember-simple-auth/src/session-stores/adaptive.ts15 symbols
packages/ember-simple-auth/src/authenticators/oauth2-password-grant.ts14 symbols
packages/ember-simple-auth/src/session-stores/session-storage.ts11 symbols
packages/ember-simple-auth/src/session-stores/local-storage.ts11 symbols
packages/ember-simple-auth/src/authenticators/base.ts11 symbols
packages/test-esa/tests/unit/session-stores/cookie-test.js10 symbols
packages/ember-simple-auth/src/session-stores/ephemeral.ts9 symbols
packages/test-esa/tests/helpers/mocked-session-storage.js8 symbols
packages/test-app/app/components/login-form.js8 symbols

Used by 1 indexed graphs manifest dependencies, hub-wide

Dependencies from manifests, versioned

@babel/core7.28.6 · 1×
@babel/eslint-parser7.28.6 · 1×
@babel/plugin-proposal-class-properties7.18.6 · 1×
@babel/plugin-proposal-decorators7.28.6 · 1×
@babel/plugin-transform-typescript7.28.6 · 1×
@babel/preset-env7.28.6 · 1×
@babel/runtime7.28.6 · 1×
@ember/legacy-built-in-components0.5.0 · 1×
@ember/optional-features2.2.0 · 1×
@ember/string3.1.1 · 1×
@ember/test-helpers5.4.3 · 1×
@ember/test-waiters3 || ^4 · 1×

For agents

$ claude mcp add ember-simple-auth \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact