diff --git a/.editorconfig b/.editorconfig index 219985c2..c35a0024 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,7 +4,6 @@ root = true - [*] end_of_line = lf charset = utf-8 diff --git a/.ember-cli b/.ember-cli deleted file mode 100644 index 59bb55fe..00000000 --- a/.ember-cli +++ /dev/null @@ -1,9 +0,0 @@ -{ - /** - Ember CLI sends analytics information by default. The data is completely - anonymous, but there are times when you might want to disable this behavior. - - Setting `disableAnalytics` to true will prevent any data from being sent. - */ - "disableAnalytics": true -} diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 4f1412a6..00000000 --- a/.eslintrc.js +++ /dev/null @@ -1,76 +0,0 @@ -module.exports = { - root: true, - parserOptions: { - ecmaVersion: 2017, - sourceType: 'module' - }, - plugins: [ - 'ember' - ], - extends: [ - 'eslint:recommended', - 'plugin:ember/recommended' - ], - env: { - browser: true - }, - rules: { - 'arrow-spacing': ['error', {'before': true, 'after': true}], - 'callback-return': ['error', ['callback', 'cb', 'next', 'done', 'proceed']], - 'camelcase': ['error', {'properties': 'always'}], - 'comma-dangle': ['error', 'never'], - 'comma-style': ['error', 'last'], - 'curly': ['error'], - 'eol-last': ['error'], - 'eqeqeq': ['error', 'always'], - 'handle-callback-err': ['error'], - 'indent': ['error', 2, {'SwitchCase': 1}], - 'linebreak-style': ['error', 'unix'], - 'no-const-assign': ['error'], - 'no-mixed-spaces-and-tabs': ['error', 'smart-tabs'], - 'no-return-assign': ['error', 'always'], - 'no-sequences': ['error'], - 'no-trailing-spaces': ['error'], - 'no-undef': ['error'], - 'no-unexpected-multiline': ['error'], - 'no-unused-vars': ['error'], - 'no-var': ['error'], - 'one-var': ['error', 'never'], - 'prefer-const': ['error'], - 'rest-spread-spacing': ['error', 'never'], - 'semi': ['error', 'always'] - }, - overrides: [ - { - files: [ - 'eslintrc.js', - 'blueprints/*/index.js', - 'config/**/*.js', - 'ember-cli-build.js', - 'index.js', - 'server/**/*.js', - 'testem.js', - 'tests/dummy/config/**/*.js' - ], - excludedFiles: [ - 'addon-test-support/**', - 'addon/**', - 'app/**', - 'tests/dummy/app/**' - ], - parserOptions: { - sourceType: 'script', - ecmaVersion: 2015 - }, - env: { - browser: false, - node: true - }, - plugins: ['node'], - rules: Object.assign({}, require('eslint-plugin-node').configs.recommended.rules, { - 'camelcase': ['off'], - 'no-var': ['off'] - }) - } - ] -}; diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index b4f405fb..be3e5479 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -24,12 +24,12 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 63f08fff..ee649a6a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,85 +10,35 @@ jobs: continue-on-error: ${{ matrix.experimental }} strategy: matrix: + node: + - v16 + - v18 + - v20 scenario: - - ember-lts-2.16-ember-simple-auth-1.6 - - ember-lts-2.16-ember-simple-auth-2.0 - - ember-lts-2.18-ember-simple-auth-1.6 - - ember-lts-2.18-ember-simple-auth-2.0 - - ember-lts-3.4-ember-simple-auth-1.6 - - ember-lts-3.4-ember-simple-auth-2.0 - - ember-lts-3.4-ember-simple-auth-3.0 - - ember-lts-3.4-ember-simple-auth-4.0 - - ember-lts-3.4-ember-simple-auth-5.0 - - ember-lts-3.8-ember-simple-auth-1.6 - - ember-lts-3.8-ember-simple-auth-2.0 - - ember-lts-3.8-ember-simple-auth-3.0 - - ember-lts-3.8-ember-simple-auth-4.0 - - ember-lts-3.8-ember-simple-auth-5.0 - - ember-lts-3.12-ember-simple-auth-1.6 - - ember-lts-3.12-ember-simple-auth-2.0 - - ember-lts-3.12-ember-simple-auth-3.0 - - ember-lts-3.12-ember-simple-auth-4.0 - - ember-lts-3.12-ember-simple-auth-5.0 - - ember-lts-3.16-ember-simple-auth-1.6 - - ember-lts-3.16-ember-simple-auth-2.0 - - ember-lts-3.16-ember-simple-auth-3.0 - - ember-lts-3.16-ember-simple-auth-4.0 - - ember-lts-3.16-ember-simple-auth-5.0 - - ember-lts-3.20-ember-simple-auth-1.6 - - ember-lts-3.20-ember-simple-auth-2.0 - - ember-lts-3.20-ember-simple-auth-3.0 - - ember-lts-3.20-ember-simple-auth-4.0 - - ember-lts-3.20-ember-simple-auth-5.0 - - ember-lts-3.24-ember-simple-auth-1.6 - - ember-lts-3.24-ember-simple-auth-2.0 - - ember-lts-3.24-ember-simple-auth-3.0 - - ember-lts-3.24-ember-simple-auth-4.0 - - ember-lts-3.24-ember-simple-auth-5.0 - - ember-lts-3.28-ember-simple-auth-1.6 - - ember-lts-3.28-ember-simple-auth-2.0 - - ember-lts-3.28-ember-simple-auth-3.0 - - ember-lts-3.28-ember-simple-auth-4.0 - - ember-lts-3.28-ember-simple-auth-5.0 + - ember-lts-4.4-ember-simple-auth-6.0 + - ember-lts-4.8-ember-simple-auth-6.0 + - ember-lts-4.12-ember-simple-auth-6.0 + - ember-lts-5.4-ember-simple-auth-6.0 + - ember-lts-5.8-ember-simple-auth-6.0 experimental: - false include: - - scenario: ember-release-ember-simple-auth-1.6 + - scenario: ember-release-ember-simple-auth-6.0 + node: v20 experimental: true - - scenario: ember-release-ember-simple-auth-2.0 + - scenario: ember-beta-ember-simple-auth-6.0 + node: v20 experimental: true - - scenario: ember-release-ember-simple-auth-3.0 - experimental: true - - scenario: ember-release-ember-simple-auth-4.0 - experimental: true - - scenario: ember-release-ember-simple-auth-5.0 - experimental: true - - scenario: ember-beta-ember-simple-auth-1.6 - experimental: true - - scenario: ember-beta-ember-simple-auth-2.0 - experimental: true - - scenario: ember-beta-ember-simple-auth-3.0 - experimental: true - - scenario: ember-beta-ember-simple-auth-4.0 - experimental: true - - scenario: ember-beta-ember-simple-auth-5.0 - experimental: true - - scenario: ember-canary-ember-simple-auth-1.6 - experimental: true - - scenario: ember-canary-ember-simple-auth-2.0 - experimental: true - - scenario: ember-canary-ember-simple-auth-3.0 - experimental: true - - scenario: ember-canary-ember-simple-auth-4.0 - experimental: true - - scenario: ember-canary-ember-simple-auth-5.0 + - scenario: ember-canary-ember-simple-auth-6.0 + node: v20 experimental: true steps: - uses: actions/checkout@v4 - - name: Test scenario ${{ matrix.scenario }} - uses: actions/setup-node@v3 + - name: Test scenario ${{ matrix.scenario }} using node ${{ matrix.node }} + uses: actions/setup-node@v4 with: - node-version: 14.x + node-version: ${{ matrix.node }} - run: npm ci - - run: npm run lint:js - - run: npm run test:one ${{ matrix.scenario }} --skip-cleanup + - run: npm run lint + - run: npm run test:ember ${{ matrix.scenario }} --skip-cleanup + working-directory: test-app diff --git a/.gitignore b/.gitignore index 98eb0615..3e58c96d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,24 +1,22 @@ # See https://help.github.com/ignore-files/ for more about ignoring files. -# compiled output -/dist -/tmp - # dependencies -/node_modules -/bower_components +node_modules/ # misc -/.sass-cache -/connect.lock -/coverage/* -/libpeerconnection.log +.env* +.pnp* +.pnpm-debug.log +.sass-cache +.eslintcache +coverage/ npm-debug.log* yarn-error.log -testem.log # ember-try -.node_modules.ember-try/ -bower.json.ember-try -package.json.ember-try -package-lock.json.ember-try +/.node_modules.ember-try/ +/package.json.ember-try +/package-lock.json.ember-try +/yarn.lock.ember-try +/pnpm-lock.ember-try.yaml + diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 8b9c8a84..00000000 --- a/.npmignore +++ /dev/null @@ -1,23 +0,0 @@ -/bower_components -/config/ember-try.js -/dist -/tests -/tmp -/server -**/.gitkeep -.bowerrc -.editorconfig -.ember-cli -.eslintrc.js -.gitignore -.watchmanconfig -.travis.yml -.github -bower.json -ember-cli-build.js -testem.js - -# ember-try -.node_modules.ember-try/ -bower.json.ember-try -package.json.ember-try diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000..9a2a0e21 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v20 diff --git a/.watchmanconfig b/.watchmanconfig deleted file mode 100644 index e7834e3e..00000000 --- a/.watchmanconfig +++ /dev/null @@ -1,3 +0,0 @@ -{ - "ignore_dirs": ["tmp", "dist"] -} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 91dc6adf..962e962e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,4 +20,4 @@ Please note that you must adhere to each of the aforementioned rules. Failure to do so will result in an immediate closing of the pull request. If you update and rebase the pull request to follow the guidelines your pull request will be re-opened and considered for -inclusion. +inclusion. \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md index 9b2a69f5..ff84a5be 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2015-2018 +Copyright (c) 2024 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/README.md b/README.md index 730db903..02f08d60 100644 --- a/README.md +++ b/README.md @@ -4,28 +4,138 @@ [![ember-observer-image]][ember-observer] [![npm-image]][npm] -This is Ember addon is an extension to the Ember Simple Auth library that provides a basic token authenticator, a JSON Web Tokens token authenticator with automatic refresh capability, and an authorizer mixin. You can find more about why JSON Web Tokens are so awesome in [this article][medium-jwt]. +This Ember addon is an extension of the Ember Simple Auth library which provides a basic token authenticator and a JSON Web Tokens (jwt) token authenticator with automatic refresh capability. You can find more about why JSON Web Tokens are so awesome in [this blog](https://medium.com/@extio/understanding-json-web-tokens-jwt-a-secure-approach-to-web-authentication-f551e8d66deb) and [here as well](https://medium.com/swlh/all-you-need-to-know-about-json-web-token-jwt-8a5d6131157f). -**Because user's credentials and tokens are exchanged between the Ember.js app and the server, you must use HTTPS for this connection!** +**Because users' credentials and tokens are exchanged between the Ember.js app and the server, you must use HTTPS for this connection!** ## Demo -A demo is available [here][demo]. +The test-app has an example of implementing jwt with auto-refresh. It can be run by cloning the repo, then: + +```node +cd ember-simple-auth-token +npm i +npm start // express server +// or +npm run mirage // mirage api mock +// navigate to http://localhost:4201 +``` + +## Compatibility + +| Library | Compatible Versions | +| - | - | +| node | v16, v18, v20 | +| ember | v4.4, v4.8, v4.12, v5.4, v5.8 | +| ember-simple-auth | v6 | +| ember-auto-import | v2 | +| webpack | v5 | ## Installation -Ember Simple Auth Token can be installed with [Ember CLI][ember-cli] by running: +Ember Simple Auth Token can be installed with [Ember CLI](https://ember-cli.com) by running: ``` ember install ember-simple-auth-token ``` -If using FastBoot, `ember-fetch` must be installed as a direct dependency and `node-fetch` must be added to your `fastbootDependencies`. If using FastBoot and the JWT authenticator, `node-fetch` and `buffer` must be added to you `fastbootDependencies`. - -`ember-simple-auth-token` will automatically install a compatible version of `ember-simple-auth`. If you want to manually install `ember-simple-auth`, you must ensure to install a version that is supported by `ember-simple-auth-token`. +You must manually install a compatible version of `ember-simple-auth`. ## Setup +### Calling session.setup() on ember-simple-auth session service + +`ember-simple-auth` no longer uses an initializer to wire up the session service. Your applicaton must implement an application route to call `session.setup()` on the `ember-simple-auth` session service: + +```js +// app/routes/application.js +import Route from '@ember/routing/route'; +import { inject } from '@ember/service'; + +export default class ApplicationRoute extends Route { + @inject session; + + async beforeModel() { + await this.session.setup(); + } +} +``` + +### Routing + +It is [recommended by](https://github.com/mainmatter/ember-simple-auth) `ember-simple-auth` to use an authenticated route in your application, placing all secure routes under it, and employing `session.requireAuthentication()` in `beforeModel`. + +```javascript +// app/router.js +import EmberRouter from '@ember/routing/router'; +import config from 'test-app/config/environment'; + +export default class Router extends EmberRouter { + location = config.locationType; + rootURL = config.rootURL; +} + +Router.map(function () { + this.route('login'); + this.route('authenticated', { path: '' }, function() { + // all routes that require the session to be authenticated + this.route('index', { path: '' }); + this.route('secure'); + }); +}); + +// app/routes/authenticated.js +import Route from '@ember/routing/route'; +import { inject as service } from '@ember/service'; + +export default class AuthenticatedRoute extends Route { + @service session; + + beforeModel(transition) { + this.session.requireAuthentication(transition, 'login'); + } +} +``` + +Leaving `path: ''` in your router for the authenticated root will keep all secure roots at the top-level, without an extra added path segment. You can also use a path, such as `path: 'application'`, etc. to separate the secured routes from non-secured routes in your URL structure. EG: `myapp/application/secure` and `myapp/login`. + +All authenticated routes can then inherit the authenticated route: + +```javascript +// app/routes/authenticated/secure.js +import Route from '../authenticated'; + +export default class SecureRoute extends Route {} +``` + +Your project's folder structure would look like this: + +``` +project +│ +└───app + │ router.js + │ + └───routes + │ application.js + │ authenticated.js + │ login.js + │ + └───authenticated + secure.js + index.js +``` + +Make sure `ember-simple-auth` is configured to utilize this route structure in your environment file: + +```javascript +// config/environment.js +ENV['ember-simple-auth'] = { + routeAfterAuthentication: 'authenticated.index', + routeAfterInvalidation: 'login', +}; +``` + ### Authenticator In order to use the token authenticator or the JSON Web Token authenticator, the application should have a route for login. In most cases, the login route will display a form with a `username` and `password` field. On form submit, the `authenticate` action will be called on the `session`: @@ -39,7 +149,7 @@ Router.map(function() { ```html {{! app/templates/login.hbs }} -