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

View file

@ -1,7 +1,16 @@
import Controller from '@ember/controller'; import Controller from '@ember/controller';
import { CheckboxMarkedCircle, AlertCircle } from 'ember-mdi/icons'; 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 { export default class AdminController extends Controller {
@service session;
CheckboxMarkedCircle = CheckboxMarkedCircle; CheckboxMarkedCircle = CheckboxMarkedCircle;
AlertCircle = AlertCircle; 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 { export default class AdminRoute extends Route {
@service meilisearch; @service meilisearch;
@service session;
beforeModel(transition) {
this.session.requireAuthentication(transition, 'login');
}
async model() { async model() {
return hash({ 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='relative min-h-screen flex'>
<div class="flex flex-col w-64 min-h-screen px-4 py-8 border-r"> <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"> <h2 class='flex items-center text-xl mb-8'>
<img src="/logo.svg" alt="MeiliSearch" class="w-8 h-8 mr-2"> <img src='/logo.svg' alt='MeiliSearch' class='w-8 h-8 mr-2' />
MeiliSearch Admin MeiliSearch Admin
</h2> </h2>
<div class="flex flex-col flex-1"> <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|}} {{#let
'flex items-center px-4 py-2 font-semibold text-lg text-gray-dark hover:text-black'
as |linkClass|
}}
<nav> <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|}} {{#each @model.indexes as |item|}}
<LinkTo <LinkTo
@route="admin.indexes.item" @route='admin.indexes.item'
@model={{item}} @model={{item}}
class={{linkClass}}> class={{linkClass}}
<MdIcon::CircleMedium class="mr-1" /> {{capitalize item.uid}} >
<MdIcon::CircleMedium class='mr-1' />
{{capitalize item.uid}}
</LinkTo> </LinkTo>
{{/each}} {{/each}}
{{!-- TODO: add link "create new index" --}} {{! TODO: add link "create new index" }}
<div class="border-t my-4" /> <div class='border-t my-4'></div>
<a href="https://docs.meilisearch.com/" class={{linkClass}} target="_blank" rel="noopener noreferrer"> <a
<MdIcon::HelpCircleOutline class="mr-1" /> Documentation href='https://docs.meilisearch.com/'
class={{linkClass}}
target='_blank'
rel='noopener noreferrer'
>
<MdIcon::HelpCircleOutline class='mr-1' />
Documentation
</a> </a>
<a href="https://github.com/kaermorchen/meilisearch-admin" class={{linkClass}} target="_blank" rel="noopener noreferrer"> <a
<MdIcon::Github class="mr-1" /> MeiliSearch Admin href='https://github.com/kaermorchen/meilisearch-admin'
class={{linkClass}}
target='_blank'
rel='noopener noreferrer'
>
<MdIcon::Github class='mr-1' />
MeiliSearch Admin
</a> </a>
<button
type='button'
{{on 'click' this.invalidateSession}}
class={{linkClass}}
><MdIcon::Logout class='mr-1'/>Logout</button>
</nav> </nav>
{{/let}} {{/let}}
<div class="flex flex-row items-center mt-auto px-4 pt-2"> <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> <span
{{#if (eq @model.health.status "available")}} class='mr-1 text-gray'
<this.CheckboxMarkedCircle class="text-green" @size={{18}} @title={{@model.health.status}}/> 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}} {{else}}
<this.AlertCircle class="text-yellow" @size={{18}} @title={{@model.health.status}}/> <this.AlertCircle
class='text-yellow'
@size={{18}}
@title={{@model.health.status}}
/>
{{/if}} {{/if}}
</div> </div>
</div> </div>
</div> </div>
<div class="flex-1 p-4"> <div class='flex-1 p-4'>
{{outlet}} {{outlet}}
</div> </div>
</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) { export default function query(path, options = {}) {
const url = `${host}/${path}`; const session = instance.lookup('service:session');
const defaultOptions = { const { url, key } = session.data.authenticated;
headers: { const defaultHeaders = { 'Content-Type': 'application/json' };
'Content-Type': 'application/json', const headers = new Headers(Object.assign(defaultHeaders, options.headers));
},
};
return fetch(url, Object.assign(defaultOptions, options)).then((response) => if (key) {
response.json() 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': { 'ember-power-select': {
theme: false, theme: false,
}, },
'ember-simple-auth': {
useSessionSetupMethod: true,
},
}); });
return require('@embroider/compat').compatBuild(app, Webpack, { return require('@embroider/compat').compatBuild(app, Webpack, {

405
package-lock.json generated
View file

@ -56,6 +56,7 @@
"ember-resolver": "^8.0.3", "ember-resolver": "^8.0.3",
"ember-resources": "^4.7.1", "ember-resources": "^4.7.1",
"ember-set-helper": "^2.0.1", "ember-set-helper": "^2.0.1",
"ember-simple-auth": "^4.2.2",
"ember-sortable": "^3.0.1", "ember-sortable": "^3.0.1",
"ember-source": "~4.6.0", "ember-source": "~4.6.0",
"ember-template-lint": "^4.10.1", "ember-template-lint": "^4.10.1",
@ -7260,6 +7261,12 @@
"node": ">=0.10.0" "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": { "node_modules/base/node_modules/define-property": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
@ -14143,6 +14150,19 @@
"node": "8.* || >= 10.*" "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": { "node_modules/ember-destroyable-polyfill": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/ember-destroyable-polyfill/-/ember-destroyable-polyfill-2.0.3.tgz", "resolved": "https://registry.npmjs.org/ember-destroyable-polyfill/-/ember-destroyable-polyfill-2.0.3.tgz",
@ -14174,6 +14194,40 @@
"ember-source": "^3.8 || 4" "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": { "node_modules/ember-fetch": {
"version": "8.1.1", "version": "8.1.1",
"resolved": "https://registry.npmjs.org/ember-fetch/-/ember-fetch-8.1.1.tgz", "resolved": "https://registry.npmjs.org/ember-fetch/-/ember-fetch-8.1.1.tgz",
@ -14338,6 +14392,41 @@
"node": "12.* || 14.* || >= 16" "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": { "node_modules/ember-in-element-polyfill": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/ember-in-element-polyfill/-/ember-in-element-polyfill-1.0.1.tgz", "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": "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": { "node_modules/ember-sortable": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/ember-sortable/-/ember-sortable-3.0.1.tgz", "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": { "base64-js": {
"version": "1.5.1", "version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "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": { "ember-destroyable-polyfill": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/ember-destroyable-polyfill/-/ember-destroyable-polyfill-2.0.3.tgz", "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-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": { "ember-fetch": {
"version": "8.1.1", "version": "8.1.1",
"resolved": "https://registry.npmjs.org/ember-fetch/-/ember-fetch-8.1.1.tgz", "resolved": "https://registry.npmjs.org/ember-fetch/-/ember-fetch-8.1.1.tgz",
@ -41476,6 +41742,34 @@
"ember-cli-babel": "^7.26.6" "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": { "ember-in-element-polyfill": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/ember-in-element-polyfill/-/ember-in-element-polyfill-1.0.1.tgz", "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-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": { "ember-sortable": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/ember-sortable/-/ember-sortable-3.0.1.tgz", "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-resolver": "^8.0.3",
"ember-resources": "^4.7.1", "ember-resources": "^4.7.1",
"ember-set-helper": "^2.0.1", "ember-set-helper": "^2.0.1",
"ember-simple-auth": "^4.2.2",
"ember-sortable": "^3.0.1", "ember-sortable": "^3.0.1",
"ember-source": "~4.6.0", "ember-source": "~4.6.0",
"ember-template-lint": "^4.10.1", "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);
});
});