Merge pull request #3 from kaermorchen/auth

Add ember-simple-auth
This commit is contained in:
Stanislav Romanov 2022-08-20 18:20:19 +03:00 committed by GitHub
commit 4fa8192327
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 707 additions and 34 deletions

View file

@ -0,0 +1,26 @@
import Base from 'ember-simple-auth/authenticators/base';
function makeRequest({ url, key }) {
const headers = new Headers({
'Content-Type': 'application/json',
});
if (key) {
headers.append('Authorization', `Bearer ${key}`);
}
// TODO: how to check session?
const req = new Request(new URL('/version', url), { headers });
return fetch(req).then(() => ({ url, key }));
}
export default class MeilisearchAuthenticator extends Base {
restore({ url, key }) {
return makeRequest({ url, key });
}
authenticate(url, key) {
return makeRequest({ url, key });
}
}

View file

@ -1,7 +1,7 @@
<div class="mb-4">
{{#if @label}}
<label for={{this.id}} class="block font-medium mb-1 text-dark">
{{@label}}
<label for={{this.id}} class="block font-medium mb-1 text-dark {{if @required "after:content-['*'] after:text-red-500"}}">
{{~@label~}}
</label>
{{/if}}
<div class="relative flex items-center border rounded-md">
@ -15,6 +15,7 @@
class="block w-full p-2 bg-transparent focus:outline-none"
placeholder={{@placeholder}}
value={{@value}}
required={{@required}}
{{on 'input' this.onChange}}
/>
</div>

View file

@ -1,7 +1,16 @@
import Controller from '@ember/controller';
import { CheckboxMarkedCircle, AlertCircle } from 'ember-mdi/icons';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
export default class AdminController extends Controller {
@service session;
CheckboxMarkedCircle = CheckboxMarkedCircle;
AlertCircle = AlertCircle;
@action
invalidateSession() {
this.session.invalidate();
}
}

25
app/controllers/login.js Normal file
View file

@ -0,0 +1,25 @@
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
export default class LoginController extends Controller {
@service session;
@tracked errorMessage;
@tracked url;
@tracked key;
@action
async authenticate(e) {
e.preventDefault();
let { url, key } = this;
try {
await this.session.authenticate('authenticator:meilisearch', url, key);
} catch (error) {
this.errorMessage = error.error || error;
}
}
}

View file

@ -0,0 +1,9 @@
export let instance;
export function initialize(owner) {
instance = owner;
}
export default {
initialize,
};

View file

@ -15,4 +15,5 @@ Router.map(function () {
});
});
});
this.route('login');
});

View file

@ -4,6 +4,11 @@ import { hash } from 'rsvp';
export default class AdminRoute extends Route {
@service meilisearch;
@service session;
beforeModel(transition) {
this.session.requireAuthentication(transition, 'login');
}
async model() {
return hash({

10
app/routes/application.js Normal file
View file

@ -0,0 +1,10 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
export default class ApplicationRoute extends Route {
@service session;
async beforeModel() {
await this.session.setup();
}
}

10
app/routes/login.js Normal file
View file

@ -0,0 +1,10 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
export default class LoginRoute extends Route {
@service session;
beforeModel() {
this.session.prohibitAuthentication('admin');
}
}

View file

@ -1,44 +1,78 @@
<div class="relative min-h-screen flex">
<div class="flex flex-col w-64 min-h-screen px-4 py-8 border-r">
<h2 class="flex items-center text-xl mb-8">
<img src="/logo.svg" alt="MeiliSearch" class="w-8 h-8 mr-2">
<div class='relative min-h-screen flex'>
<div class='flex flex-col w-64 min-h-screen px-4 py-8 border-r'>
<h2 class='flex items-center text-xl mb-8'>
<img src='/logo.svg' alt='MeiliSearch' class='w-8 h-8 mr-2' />
MeiliSearch Admin
</h2>
<div class="flex flex-col flex-1">
{{#let "flex items-center px-4 py-2 font-semibold text-lg text-gray-dark hover:text-black" as |linkClass|}}
<div class='flex flex-col flex-1'>
{{#let
'flex items-center px-4 py-2 font-semibold text-lg text-gray-dark hover:text-black'
as |linkClass|
}}
<nav>
<div class="px-4 py-2 text-sm text-gray">Indexes</div>
<div class='px-4 py-2 text-sm text-gray'>Indexes</div>
{{#each @model.indexes as |item|}}
<LinkTo
@route="admin.indexes.item"
@route='admin.indexes.item'
@model={{item}}
class={{linkClass}}>
<MdIcon::CircleMedium class="mr-1" /> {{capitalize item.uid}}
class={{linkClass}}
>
<MdIcon::CircleMedium class='mr-1' />
{{capitalize item.uid}}
</LinkTo>
{{/each}}
{{!-- TODO: add link "create new index" --}}
<div class="border-t my-4" />
<a href="https://docs.meilisearch.com/" class={{linkClass}} target="_blank" rel="noopener noreferrer">
<MdIcon::HelpCircleOutline class="mr-1" /> Documentation
{{! TODO: add link "create new index" }}
<div class='border-t my-4'></div>
<a
href='https://docs.meilisearch.com/'
class={{linkClass}}
target='_blank'
rel='noopener noreferrer'
>
<MdIcon::HelpCircleOutline class='mr-1' />
Documentation
</a>
<a href="https://github.com/kaermorchen/meilisearch-admin" class={{linkClass}} target="_blank" rel="noopener noreferrer">
<MdIcon::Github class="mr-1" /> MeiliSearch Admin
<a
href='https://github.com/kaermorchen/meilisearch-admin'
class={{linkClass}}
target='_blank'
rel='noopener noreferrer'
>
<MdIcon::Github class='mr-1' />
MeiliSearch Admin
</a>
<button
type='button'
{{on 'click' this.invalidateSession}}
class={{linkClass}}
><MdIcon::Logout class='mr-1'/>Logout</button>
</nav>
{{/let}}
<div class="flex flex-row items-center mt-auto px-4 pt-2">
<span class="mr-1 text-gray" title="The version of a running Meilisearch instance">v{{@model.version.pkgVersion}}</span>
{{#if (eq @model.health.status "available")}}
<this.CheckboxMarkedCircle class="text-green" @size={{18}} @title={{@model.health.status}}/>
<div class='flex flex-row items-center mt-auto px-4 pt-2'>
<span
class='mr-1 text-gray'
title='The version of a running Meilisearch instance'
>v{{@model.version.pkgVersion}}</span>
{{#if (eq @model.health.status 'available')}}
<this.CheckboxMarkedCircle
class='text-green'
@size={{18}}
@title={{@model.health.status}}
/>
{{else}}
<this.AlertCircle class="text-yellow" @size={{18}} @title={{@model.health.status}}/>
<this.AlertCircle
class='text-yellow'
@size={{18}}
@title={{@model.health.status}}
/>
{{/if}}
</div>
</div>
</div>
<div class="flex-1 p-4">
<div class='flex-1 p-4'>
{{outlet}}
</div>
</div>

View file

@ -0,0 +1,2 @@
{{page-title "Application"}}
{{outlet}}

54
app/templates/login.hbs Normal file
View file

@ -0,0 +1,54 @@
{{page-title 'Login'}}
<div class='min-h-screen flex flex-col justify-center py-12 sm:px-6 lg:px-8'>
<div class='sm:mx-auto sm:w-full sm:max-w-md'>
<div class='bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10 mb-4'>
<form class='space-y-6' {{on 'submit' this.authenticate}}>
<h1 class='text-2xl text-center'>MeiliSearch Admin</h1>
<InputText
@label='URL'
@value={{this.url}}
@required={{true}}
@onChange={{set this 'url'}}
@placeholder='https://example.com'
class='mt-1'
/>
<InputText
@label='API key'
@value={{this.key}}
@onChange={{set this 'key'}}
class='mt-1'
/>
<Button
type='submit'
@text='Sign in'
@style='primary'
class='w-full flex justify-center'
/>
{{#if this.errorMessage}}
{{this.errorMessage}}
{{/if}}
</form>
</div>
<p class='text-center mb-4'>
<a
href='https://www.meilisearch.com/'
title='Website Meilisearch'
>Meilisearch</a>
— an open-source, lightning-fast, and hyper-relevant search engine that
fits effortlessly into your apps, websites, and workflow.
</p>
<p class='flex items-center justify-center'>
<MdIcon::Github @size='20' class='mr-1' />
<a
href='https://github.com/kaermorchen/meilisearch-admin'
title='Meilisearch Admin on GitHub'
>Meilisearch Admin</a>
</p>
</div>
</div>

View file

@ -1,14 +1,19 @@
const host = 'http://127.0.0.1:7700';
import { instance } from '../instance-initializers/application';
export default function query(path, options) {
const url = `${host}/${path}`;
const defaultOptions = {
headers: {
'Content-Type': 'application/json',
},
};
export default function query(path, options = {}) {
const session = instance.lookup('service:session');
const { url, key } = session.data.authenticated;
const defaultHeaders = { 'Content-Type': 'application/json' };
const headers = new Headers(Object.assign(defaultHeaders, options.headers));
return fetch(url, Object.assign(defaultOptions, options)).then((response) =>
response.json()
if (key) {
headers.append('Authorization', `Bearer ${key}`);
}
const req = new Request(
new URL(path, url),
Object.assign(options, { headers })
);
return fetch(req).then((res) => res.json());
}

View file

@ -12,6 +12,9 @@ module.exports = function (defaults) {
'ember-power-select': {
theme: false,
},
'ember-simple-auth': {
useSessionSetupMethod: true,
},
});
return require('@embroider/compat').compatBuild(app, Webpack, {

405
package-lock.json generated
View file

@ -56,6 +56,7 @@
"ember-resolver": "^8.0.3",
"ember-resources": "^4.7.1",
"ember-set-helper": "^2.0.1",
"ember-simple-auth": "^4.2.2",
"ember-sortable": "^3.0.1",
"ember-source": "~4.6.0",
"ember-template-lint": "^4.10.1",
@ -7260,6 +7261,12 @@
"node": ">=0.10.0"
}
},
"node_modules/base-64": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz",
"integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA==",
"dev": true
},
"node_modules/base/node_modules/define-property": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
@ -14143,6 +14150,19 @@
"node": "8.* || >= 10.*"
}
},
"node_modules/ember-cookies": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/ember-cookies/-/ember-cookies-0.5.2.tgz",
"integrity": "sha512-nZ7oG97kBcO9UHjO95ryABpnVx62Bhxo7lIsBJNmWvFXleILm9DGueiAynzXxuYWWPuKIeeSbYakrS1869tNTw==",
"dev": true,
"dependencies": {
"ember-cli-babel": "^7.1.0",
"ember-getowner-polyfill": "^1.1.0 || ^2.0.0"
},
"engines": {
"node": "8.* || 10.* || >= 12.*"
}
},
"node_modules/ember-destroyable-polyfill": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/ember-destroyable-polyfill/-/ember-destroyable-polyfill-2.0.3.tgz",
@ -14174,6 +14194,40 @@
"ember-source": "^3.8 || 4"
}
},
"node_modules/ember-factory-for-polyfill": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/ember-factory-for-polyfill/-/ember-factory-for-polyfill-1.3.1.tgz",
"integrity": "sha512-y3iG2iCzH96lZMTWQw6LWNLAfOmDC4pXKbZP6FxG8lt7GGaNFkZjwsf+Z5GAe7kxfD7UG4lVkF7x37K82rySGA==",
"dev": true,
"dependencies": {
"ember-cli-version-checker": "^2.1.0"
},
"engines": {
"node": "^4.5 || 6.* || >= 7.*"
}
},
"node_modules/ember-factory-for-polyfill/node_modules/ember-cli-version-checker": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/ember-cli-version-checker/-/ember-cli-version-checker-2.2.0.tgz",
"integrity": "sha512-G+KtYIVlSOWGcNaTFHk76xR4GdzDLzAS4uxZUKdASuFX0KJE43C6DaqL+y3VTpUFLI2FIkAS6HZ4I1YBi+S3hg==",
"dev": true,
"dependencies": {
"resolve": "^1.3.3",
"semver": "^5.3.0"
},
"engines": {
"node": ">= 4"
}
},
"node_modules/ember-factory-for-polyfill/node_modules/semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"dev": true,
"bin": {
"semver": "bin/semver"
}
},
"node_modules/ember-fetch": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/ember-fetch/-/ember-fetch-8.1.1.tgz",
@ -14338,6 +14392,41 @@
"node": "12.* || 14.* || >= 16"
}
},
"node_modules/ember-getowner-polyfill": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/ember-getowner-polyfill/-/ember-getowner-polyfill-2.2.0.tgz",
"integrity": "sha512-rwGMJgbGzxIAiWYjdpAh04Abvt0s3HuS/VjHzUFhVyVg2pzAuz45B9AzOxYXzkp88vFC7FPaiA4kE8NxNk4A4Q==",
"dev": true,
"dependencies": {
"ember-cli-version-checker": "^2.1.0",
"ember-factory-for-polyfill": "^1.3.1"
},
"engines": {
"node": "^4.5 || 6.* || >= 7.*"
}
},
"node_modules/ember-getowner-polyfill/node_modules/ember-cli-version-checker": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/ember-cli-version-checker/-/ember-cli-version-checker-2.2.0.tgz",
"integrity": "sha512-G+KtYIVlSOWGcNaTFHk76xR4GdzDLzAS4uxZUKdASuFX0KJE43C6DaqL+y3VTpUFLI2FIkAS6HZ4I1YBi+S3hg==",
"dev": true,
"dependencies": {
"resolve": "^1.3.3",
"semver": "^5.3.0"
},
"engines": {
"node": ">= 4"
}
},
"node_modules/ember-getowner-polyfill/node_modules/semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"dev": true,
"bin": {
"semver": "bin/semver"
}
},
"node_modules/ember-in-element-polyfill": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/ember-in-element-polyfill/-/ember-in-element-polyfill-1.0.1.tgz",
@ -16099,6 +16188,140 @@
"node": "10.* || >= 12"
}
},
"node_modules/ember-simple-auth": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/ember-simple-auth/-/ember-simple-auth-4.2.2.tgz",
"integrity": "sha512-D7W6OREUvf5OzeB0ePptSNBilccchRYukH4f7mkbL6WT+z6VEqRRAIaQuBZdFM6lrcSFGmzctINLZJwsIpI3wg==",
"dev": true,
"dependencies": {
"base-64": "^0.1.0",
"broccoli-file-creator": "^2.1.1",
"broccoli-funnel": "^1.2.0 || ^2.0.0",
"broccoli-merge-trees": "^4.0.0",
"ember-cli-babel": "^7.20.5",
"ember-cli-is-package-missing": "^1.0.0",
"ember-cookies": "^0.5.0",
"silent-error": "^1.0.0"
},
"engines": {
"node": ">= 12"
},
"peerDependencies": {
"ember-fetch": "^8.0.1"
}
},
"node_modules/ember-simple-auth/node_modules/broccoli-funnel": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/broccoli-funnel/-/broccoli-funnel-2.0.2.tgz",
"integrity": "sha512-/vDTqtv7ipjEZQOVqO4vGDVAOZyuYzQ/EgGoyewfOgh1M7IQAToBKZI0oAQPgMBeFPPlIbfMuAngk+ohPBuaHQ==",
"dev": true,
"dependencies": {
"array-equal": "^1.0.0",
"blank-object": "^1.0.1",
"broccoli-plugin": "^1.3.0",
"debug": "^2.2.0",
"fast-ordered-set": "^1.0.0",
"fs-tree-diff": "^0.5.3",
"heimdalljs": "^0.2.0",
"minimatch": "^3.0.0",
"mkdirp": "^0.5.0",
"path-posix": "^1.0.0",
"rimraf": "^2.4.3",
"symlink-or-copy": "^1.0.0",
"walk-sync": "^0.3.1"
},
"engines": {
"node": "^4.5 || 6.* || >= 7.*"
}
},
"node_modules/ember-simple-auth/node_modules/broccoli-merge-trees": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/broccoli-merge-trees/-/broccoli-merge-trees-4.2.0.tgz",
"integrity": "sha512-nTrQe5AQtCrW4enLRvbD/vTLHqyW2tz+vsLXQe4IEaUhepuMGVKJJr+I8n34Vu6fPjmPLwTjzNC8izMIDMtHPw==",
"dev": true,
"dependencies": {
"broccoli-plugin": "^4.0.2",
"merge-trees": "^2.0.0"
},
"engines": {
"node": "10.* || >= 12.*"
}
},
"node_modules/ember-simple-auth/node_modules/broccoli-merge-trees/node_modules/broccoli-plugin": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/broccoli-plugin/-/broccoli-plugin-4.0.7.tgz",
"integrity": "sha512-a4zUsWtA1uns1K7p9rExYVYG99rdKeGRymW0qOCNkvDPHQxVi3yVyJHhQbM3EZwdt2E0mnhr5e0c/bPpJ7p3Wg==",
"dev": true,
"dependencies": {
"broccoli-node-api": "^1.7.0",
"broccoli-output-wrapper": "^3.2.5",
"fs-merger": "^3.2.1",
"promise-map-series": "^0.3.0",
"quick-temp": "^0.1.8",
"rimraf": "^3.0.2",
"symlink-or-copy": "^1.3.1"
},
"engines": {
"node": "10.* || >= 12.*"
}
},
"node_modules/ember-simple-auth/node_modules/broccoli-merge-trees/node_modules/rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"dependencies": {
"glob": "^7.1.3"
},
"bin": {
"rimraf": "bin.js"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/ember-simple-auth/node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"dependencies": {
"ms": "2.0.0"
}
},
"node_modules/ember-simple-auth/node_modules/minimist": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
"dev": true
},
"node_modules/ember-simple-auth/node_modules/mkdirp": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
"integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
"dev": true,
"dependencies": {
"minimist": "^1.2.6"
},
"bin": {
"mkdirp": "bin/cmd.js"
}
},
"node_modules/ember-simple-auth/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"dev": true
},
"node_modules/ember-simple-auth/node_modules/promise-map-series": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/promise-map-series/-/promise-map-series-0.3.0.tgz",
"integrity": "sha512-3npG2NGhTc8BWBolLLf8l/92OxMGaRLbqvIh9wjCHhDXNvk4zsxaTaCpiCunW09qWPrN2zeNSNwRLVBrQQtutA==",
"dev": true,
"engines": {
"node": "10.* || >= 12.*"
}
},
"node_modules/ember-sortable": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/ember-sortable/-/ember-sortable-3.0.1.tgz",
@ -35584,6 +35807,12 @@
}
}
},
"base-64": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz",
"integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA==",
"dev": true
},
"base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
@ -41319,6 +41548,16 @@
}
}
},
"ember-cookies": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/ember-cookies/-/ember-cookies-0.5.2.tgz",
"integrity": "sha512-nZ7oG97kBcO9UHjO95ryABpnVx62Bhxo7lIsBJNmWvFXleILm9DGueiAynzXxuYWWPuKIeeSbYakrS1869tNTw==",
"dev": true,
"requires": {
"ember-cli-babel": "^7.1.0",
"ember-getowner-polyfill": "^1.1.0 || ^2.0.0"
}
},
"ember-destroyable-polyfill": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/ember-destroyable-polyfill/-/ember-destroyable-polyfill-2.0.3.tgz",
@ -41341,6 +41580,33 @@
"ember-cli-htmlbars": "^6.0.1"
}
},
"ember-factory-for-polyfill": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/ember-factory-for-polyfill/-/ember-factory-for-polyfill-1.3.1.tgz",
"integrity": "sha512-y3iG2iCzH96lZMTWQw6LWNLAfOmDC4pXKbZP6FxG8lt7GGaNFkZjwsf+Z5GAe7kxfD7UG4lVkF7x37K82rySGA==",
"dev": true,
"requires": {
"ember-cli-version-checker": "^2.1.0"
},
"dependencies": {
"ember-cli-version-checker": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/ember-cli-version-checker/-/ember-cli-version-checker-2.2.0.tgz",
"integrity": "sha512-G+KtYIVlSOWGcNaTFHk76xR4GdzDLzAS4uxZUKdASuFX0KJE43C6DaqL+y3VTpUFLI2FIkAS6HZ4I1YBi+S3hg==",
"dev": true,
"requires": {
"resolve": "^1.3.3",
"semver": "^5.3.0"
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"dev": true
}
}
},
"ember-fetch": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/ember-fetch/-/ember-fetch-8.1.1.tgz",
@ -41476,6 +41742,34 @@
"ember-cli-babel": "^7.26.6"
}
},
"ember-getowner-polyfill": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/ember-getowner-polyfill/-/ember-getowner-polyfill-2.2.0.tgz",
"integrity": "sha512-rwGMJgbGzxIAiWYjdpAh04Abvt0s3HuS/VjHzUFhVyVg2pzAuz45B9AzOxYXzkp88vFC7FPaiA4kE8NxNk4A4Q==",
"dev": true,
"requires": {
"ember-cli-version-checker": "^2.1.0",
"ember-factory-for-polyfill": "^1.3.1"
},
"dependencies": {
"ember-cli-version-checker": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/ember-cli-version-checker/-/ember-cli-version-checker-2.2.0.tgz",
"integrity": "sha512-G+KtYIVlSOWGcNaTFHk76xR4GdzDLzAS4uxZUKdASuFX0KJE43C6DaqL+y3VTpUFLI2FIkAS6HZ4I1YBi+S3hg==",
"dev": true,
"requires": {
"resolve": "^1.3.3",
"semver": "^5.3.0"
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"dev": true
}
}
},
"ember-in-element-polyfill": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/ember-in-element-polyfill/-/ember-in-element-polyfill-1.0.1.tgz",
@ -42903,6 +43197,117 @@
"ember-cli-babel": "^7.18.0"
}
},
"ember-simple-auth": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/ember-simple-auth/-/ember-simple-auth-4.2.2.tgz",
"integrity": "sha512-D7W6OREUvf5OzeB0ePptSNBilccchRYukH4f7mkbL6WT+z6VEqRRAIaQuBZdFM6lrcSFGmzctINLZJwsIpI3wg==",
"dev": true,
"requires": {
"base-64": "^0.1.0",
"broccoli-file-creator": "^2.1.1",
"broccoli-funnel": "^1.2.0 || ^2.0.0",
"broccoli-merge-trees": "^4.0.0",
"ember-cli-babel": "^7.20.5",
"ember-cli-is-package-missing": "^1.0.0",
"ember-cookies": "^0.5.0",
"silent-error": "^1.0.0"
},
"dependencies": {
"broccoli-funnel": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/broccoli-funnel/-/broccoli-funnel-2.0.2.tgz",
"integrity": "sha512-/vDTqtv7ipjEZQOVqO4vGDVAOZyuYzQ/EgGoyewfOgh1M7IQAToBKZI0oAQPgMBeFPPlIbfMuAngk+ohPBuaHQ==",
"dev": true,
"requires": {
"array-equal": "^1.0.0",
"blank-object": "^1.0.1",
"broccoli-plugin": "^1.3.0",
"debug": "^2.2.0",
"fast-ordered-set": "^1.0.0",
"fs-tree-diff": "^0.5.3",
"heimdalljs": "^0.2.0",
"minimatch": "^3.0.0",
"mkdirp": "^0.5.0",
"path-posix": "^1.0.0",
"rimraf": "^2.4.3",
"symlink-or-copy": "^1.0.0",
"walk-sync": "^0.3.1"
}
},
"broccoli-merge-trees": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/broccoli-merge-trees/-/broccoli-merge-trees-4.2.0.tgz",
"integrity": "sha512-nTrQe5AQtCrW4enLRvbD/vTLHqyW2tz+vsLXQe4IEaUhepuMGVKJJr+I8n34Vu6fPjmPLwTjzNC8izMIDMtHPw==",
"dev": true,
"requires": {
"broccoli-plugin": "^4.0.2",
"merge-trees": "^2.0.0"
},
"dependencies": {
"broccoli-plugin": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/broccoli-plugin/-/broccoli-plugin-4.0.7.tgz",
"integrity": "sha512-a4zUsWtA1uns1K7p9rExYVYG99rdKeGRymW0qOCNkvDPHQxVi3yVyJHhQbM3EZwdt2E0mnhr5e0c/bPpJ7p3Wg==",
"dev": true,
"requires": {
"broccoli-node-api": "^1.7.0",
"broccoli-output-wrapper": "^3.2.5",
"fs-merger": "^3.2.1",
"promise-map-series": "^0.3.0",
"quick-temp": "^0.1.8",
"rimraf": "^3.0.2",
"symlink-or-copy": "^1.3.1"
}
},
"rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"requires": {
"glob": "^7.1.3"
}
}
}
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"requires": {
"ms": "2.0.0"
}
},
"minimist": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
"dev": true
},
"mkdirp": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
"integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
"dev": true,
"requires": {
"minimist": "^1.2.6"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"dev": true
},
"promise-map-series": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/promise-map-series/-/promise-map-series-0.3.0.tgz",
"integrity": "sha512-3npG2NGhTc8BWBolLLf8l/92OxMGaRLbqvIh9wjCHhDXNvk4zsxaTaCpiCunW09qWPrN2zeNSNwRLVBrQQtutA==",
"dev": true
}
}
},
"ember-sortable": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/ember-sortable/-/ember-sortable-3.0.1.tgz",

View file

@ -76,6 +76,7 @@
"ember-resolver": "^8.0.3",
"ember-resources": "^4.7.1",
"ember-set-helper": "^2.0.1",
"ember-simple-auth": "^4.2.2",
"ember-sortable": "^3.0.1",
"ember-source": "~4.6.0",
"ember-template-lint": "^4.10.1",

View file

@ -0,0 +1,12 @@
import { module, test } from 'qunit';
import { setupTest } from 'meilisearch-admin/tests/helpers';
module('Unit | Controller | login', function (hooks) {
setupTest(hooks);
// TODO: Replace this with your real tests.
test('it exists', function (assert) {
let controller = this.owner.lookup('controller:login');
assert.ok(controller);
});
});

View file

@ -0,0 +1,39 @@
import Application from '@ember/application';
import config from 'meilisearch-admin/config/environment';
import { initialize } from 'meilisearch-admin/instance-initializers/application';
import { module, test } from 'qunit';
import Resolver from 'ember-resolver';
import { run } from '@ember/runloop';
module('Unit | Instance Initializer | application', function (hooks) {
hooks.beforeEach(function () {
this.TestApplication = class TestApplication extends Application {
modulePrefix = config.modulePrefix;
podModulePrefix = config.podModulePrefix;
Resolver = Resolver;
};
this.TestApplication.instanceInitializer({
name: 'initializer under test',
initialize,
});
this.application = this.TestApplication.create({
autoboot: false,
});
this.instance = this.application.buildInstance();
});
hooks.afterEach(function () {
run(this.instance, 'destroy');
run(this.application, 'destroy');
});
// TODO: Replace this with your real tests.
test('it works', async function (assert) {
await this.instance.boot();
assert.ok(true);
});
});

View file

@ -0,0 +1,11 @@
import { module, test } from 'qunit';
import { setupTest } from 'meilisearch-admin/tests/helpers';
module('Unit | Route | application', function (hooks) {
setupTest(hooks);
test('it exists', function (assert) {
let route = this.owner.lookup('route:application');
assert.ok(route);
});
});

View file

@ -0,0 +1,11 @@
import { module, test } from 'qunit';
import { setupTest } from 'meilisearch-admin/tests/helpers';
module('Unit | Route | login', function (hooks) {
setupTest(hooks);
test('it exists', function (assert) {
let route = this.owner.lookup('route:login');
assert.ok(route);
});
});