Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ac7dfb677 | ||
|
|
683e939b0e |
No files matched your search
@@ -1,2 +0,0 @@
|
||||
# Anyone attached to this rule will always been assigned to a pull request
|
||||
* @hashicorp/boundary-ui
|
||||
@@ -1,17 +0,0 @@
|
||||
:tickets: [Jira ticket](https://hashicorp.atlassian.net/browse/JIRA_TICKET_NUMBER)
|
||||
|
||||
## Description
|
||||
|
||||
<!--
|
||||
Replace PATH_TO_FEATURE with Vercel link
|
||||
-->
|
||||
|
||||
:technologist: [Admin preview](PATH_TO_FEATURE)
|
||||
|
||||
:rose: [Rose preview](PATH_TO_FEATURE)
|
||||
|
||||
:desktop_computer: [Desktop preview](PATH_TO_FEATURE)
|
||||
|
||||
<!-- Add a brief description of changes here. Include any other necessary relevant links -->
|
||||
|
||||
### Screenshots (if appropriate):
|
||||
@@ -1,76 +0,0 @@
|
||||
name: Build Admin UI
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
dependencies:
|
||||
name: Install dependencies
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/cache@v3
|
||||
id: node-modules-cache
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: node-modules-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
node-modules-
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '16.x'
|
||||
- run: yarn install
|
||||
build-admin-ui-oss:
|
||||
name: Build Admin UI OSS
|
||||
needs: [dependencies]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/cache@v3
|
||||
id: node-modules-cache
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: node-modules-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
node-modules-
|
||||
- name: Build
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '16.x'
|
||||
if: steps.node-modules-cache.outputs.cache-hit != 'true'
|
||||
- run: yarn run build:ui:admin:oss
|
||||
- name: Upload artifact admin-ui
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: admin-ui
|
||||
path: ./ui/admin/dist/
|
||||
- name: Upload artifact Admin UI OSS
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: admin-ui-oss
|
||||
path: ./ui/admin/dist/
|
||||
build-admin-ui-enterprise:
|
||||
name: Build Admin UI Enterprise
|
||||
needs: [dependencies]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/cache@v3
|
||||
id: node-modules-cache
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: node-modules-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
node-modules-
|
||||
- name: Build
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '16.x'
|
||||
if: steps.node-modules-cache.outputs.cache-hit != 'true'
|
||||
- run: yarn run build:ui:admin:enterprise
|
||||
- name: Upload artifact Admin UI Enterprise
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: admin-ui-ent
|
||||
path: ./ui/admin/dist/
|
||||
@@ -6,15 +6,15 @@ jobs:
|
||||
name: Install dependencies
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/cache@v3
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
id: node-modules-cache
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: node-modules-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
node-modules-
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '16.x'
|
||||
- run: yarn install
|
||||
@@ -24,15 +24,15 @@ jobs:
|
||||
needs: [dependencies]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/cache@v3
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
id: node-modules-cache
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: node-modules-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
node-modules-
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '16.x'
|
||||
if: steps.node-modules-cache.outputs.cache-hit != 'true'
|
||||
@@ -40,19 +40,19 @@ jobs:
|
||||
|
||||
lint:
|
||||
name: Lint
|
||||
needs: [dependencies, compliance]
|
||||
needs: [dependencies]
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/cache@v3
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
id: node-modules-cache
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: node-modules-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
node-modules-
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '16.x'
|
||||
if: steps.node-modules-cache.outputs.cache-hit != 'true'
|
||||
@@ -60,17 +60,17 @@ jobs:
|
||||
|
||||
test:
|
||||
name: Test
|
||||
needs: [lint]
|
||||
needs: [dependencies]
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/cache@v3
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
id: node-modules-cache
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: node-modules-${{ hashFiles('**/yarn.lock') }}
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '16.x'
|
||||
if: steps.node-modules-cache.outputs.cache-hit != 'true'
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
yarn compliance:licenses
|
||||
npx lint-staged
|
||||
yarn test
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
# This is to allow interaction with the terminal for commitizen
|
||||
exec < /dev/tty && npx git-cz --hook || true
|
||||
@@ -1,3 +0,0 @@
|
||||
url_license = "https://github.com/hashicorp/boundary-ui/blob/main/LICENSE"
|
||||
url_project_website = "https://learn.hashicorp.com/tutorials/boundary/getting-started-desktop-app"
|
||||
url_source_repository = "https://github.com/hashicorp/boundary-ui"
|
||||
@@ -38,9 +38,9 @@ You will need the following things properly installed on your computer.
|
||||
|
||||
* [Git][git]
|
||||
* [Node.js][node]
|
||||
* Supported versions:`v12`, `v14` and `v16`.
|
||||
* v10–v15
|
||||
* **Apple Silicon Users**: if you experience problems building or running
|
||||
Boundary UIs, try Node v14.
|
||||
Boundary UIs, try Node v15.
|
||||
* [Yarn][yarn] installed globally
|
||||
* [Google Chrome][chrome]
|
||||
* [Firefox][firefox]
|
||||
@@ -66,6 +66,7 @@ List of available project commands. `yarn run <command-name>`
|
||||
|---------------------|---|
|
||||
| build | Builds Admin UI. |
|
||||
| test | Runs tests in CI mode. |
|
||||
| commit | Replaces `git commit`, ensures compliance, audit, lint, and test checks pass before commit is allowed and normalizes commit messages across authors. |
|
||||
| lint | Runs ember-template-lint on all of the hbs, js, and sass files. |
|
||||
| compliance:audit | Checks for issues using `yarn audit` with moderate and above criticality.|
|
||||
| compliance:licenses | Checks that all dependencies have OSS-compatible licenses. |
|
||||
@@ -163,12 +164,11 @@ Enter the origin of your Boundary dev instance, by default is: `http://localhost
|
||||
|
||||
### Committing
|
||||
|
||||
We use `husky` and `lint-staged` to ensure linting and other checks pass before a
|
||||
commit is completed. Simply do a `yarn install` to make sure the hooks are installed.
|
||||
|
||||
Use a normal `git commit` to go through the checks, if you need to skip these checks,
|
||||
use `git commit --no-verify` to bypass them. However, a consistent commit message will
|
||||
still be enforced even if you use `--no-verify`.
|
||||
Instead of the default `git commit`, we prescribe a custom command that ensures
|
||||
linting and other checks pass before a commit may be completed. It also ensures
|
||||
that all contributors author consistent commit messages. To get started with a
|
||||
commit, stage your files as usual. Then run `yarn commit` and follow the
|
||||
on-screen instructions to author your message.
|
||||
|
||||
#### License Checking
|
||||
|
||||
|
||||
@@ -2,19 +2,20 @@
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
parser: '@babel/eslint-parser',
|
||||
parser: 'babel-eslint',
|
||||
parserOptions: {
|
||||
ecmaVersion: 2018,
|
||||
sourceType: 'module',
|
||||
// This is specific babel-config. If grows consider creating a babel config file
|
||||
requireConfigFile: false,
|
||||
babelOptions: {
|
||||
plugins: [['@babel/plugin-proposal-decorators', { legacy: true }]],
|
||||
ecmaFeatures: {
|
||||
legacyDecorators: true,
|
||||
},
|
||||
// end of babel-config
|
||||
},
|
||||
plugins: ['ember'],
|
||||
extends: ['eslint:recommended', 'plugin:ember/recommended', 'prettier'],
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:ember/recommended',
|
||||
'plugin:prettier/recommended',
|
||||
],
|
||||
env: {
|
||||
browser: true,
|
||||
},
|
||||
|
||||
@@ -47,28 +47,21 @@ List of available project commands. `yarn run <command-name>`
|
||||
| build:development | Builds the dummy app in development mode. |
|
||||
| build | Builds the dummy app for production. |
|
||||
| lint | Runs all lint commands. |
|
||||
| lint:fix | Runs automatic lint fixes for all type of file. |
|
||||
| lint:hbs | Runs lint for `hbs` template files. |
|
||||
| lint:hbs:fix | Runs automatic lint fixes for `hbs` template files. |
|
||||
| lint:js | Lints `js` files. |
|
||||
| lint:js:fix | Runs automatic lint fixes for `js` files. |
|
||||
| format | Runs all auto-formatters. |
|
||||
| format:js | Auto-formats `js` files using Prettier. |
|
||||
| start | Runs the dummy app local server. |
|
||||
| test | Runs all tests. |
|
||||
| test:ember-compatibility | Runs tests across multiple Ember versions with ember-try. |
|
||||
| precommit | Runs all lint and format. |
|
||||
| test:all | Runs tests across multiple Ember versions with ember-try. |
|
||||
| doc:toc | Automatically generates a table of contents for this README file. |
|
||||
|
||||
Additional commands in the monorepo package may affect this projects.
|
||||
|
||||
## Linting
|
||||
|
||||
* `yarn lint:fix`
|
||||
* `yarn lint:hbs`
|
||||
* `yarn lint:hbs:fix`
|
||||
* `yarn lint:js`
|
||||
* `yarn lint:js:fix`
|
||||
* `yarn lint:js --fix`
|
||||
|
||||
## Formatting
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import ModelAbility from './model';
|
||||
|
||||
/**
|
||||
* Provides abilities for credential store.
|
||||
*/
|
||||
export default class CredentialStoreAbility extends ModelAbility {
|
||||
// =permissions
|
||||
|
||||
/**
|
||||
* Only "known" credential store types may be read.
|
||||
* @type {boolean}
|
||||
*/
|
||||
get canRead() {
|
||||
return !this.model.isStatic && this.hasAuthorizedAction('read');
|
||||
}
|
||||
}
|
||||
@@ -43,20 +43,4 @@ export default class GeneratedAccountModel extends BaseModel {
|
||||
description: 'Current version number of this resource.',
|
||||
})
|
||||
version;
|
||||
|
||||
// =attributes (password)
|
||||
@attr('string', {
|
||||
for: 'password',
|
||||
isNestedAttribute: true,
|
||||
description: 'The account login name',
|
||||
})
|
||||
login_name;
|
||||
|
||||
// =attributes (OIDC)
|
||||
@attr('string', { for: 'oidc', isNestedAttribute: true }) subject;
|
||||
@attr('string', { for: 'oidc', isNestedAttribute: true }) issuer;
|
||||
@attr('string', { for: 'oidc', isNestedAttribute: true, readOnly: true })
|
||||
email;
|
||||
@attr('string', { for: 'oidc', isNestedAttribute: true, readOnly: true })
|
||||
full_name;
|
||||
}
|
||||
@@ -44,27 +44,4 @@ export default class GeneratedCredentialLibraryModel extends BaseModel {
|
||||
description: 'Current version number of this resource.',
|
||||
})
|
||||
version;
|
||||
|
||||
//= attributes (vault)
|
||||
|
||||
@attr('string', {
|
||||
isNestedAttribute: true,
|
||||
description:
|
||||
'The HTTP method the library uses when requesting credentials from Vault.',
|
||||
defaultValue: () => 'GET',
|
||||
})
|
||||
http_method;
|
||||
|
||||
@attr('string', {
|
||||
isNestedAttribute: true,
|
||||
description:
|
||||
'The body of the HTTP request the library sends to Vault when requesting credentials. Only valid if `http_method` is set to `POST`.',
|
||||
})
|
||||
http_request_body;
|
||||
|
||||
@attr('string', {
|
||||
isNestedAttribute: true,
|
||||
description: 'The path in Vault to request credentials from.',
|
||||
})
|
||||
path;
|
||||
}
|
||||
@@ -39,82 +39,4 @@ export default class GeneratedCredentialStoreModel extends BaseModel {
|
||||
description: 'Current version number of this resource.',
|
||||
})
|
||||
version;
|
||||
|
||||
// =attributes (vault)
|
||||
@attr('string', {
|
||||
for: 'vault',
|
||||
isNestedAttribute: true,
|
||||
description:
|
||||
"The address to Vault server. This should be a complete URL such as 'https://127.0.0.1:8200'",
|
||||
})
|
||||
address;
|
||||
|
||||
@attr('string', {
|
||||
for: 'vault',
|
||||
isNestedAttribute: true,
|
||||
description: 'The namespace within Vault to use.',
|
||||
})
|
||||
namespace;
|
||||
|
||||
@attr('string', {
|
||||
for: 'vault',
|
||||
isNestedAttribute: true,
|
||||
description:
|
||||
"A PEM-encoded CA certificate to verify the Vault server's TLS certificate.",
|
||||
})
|
||||
ca_cert;
|
||||
|
||||
@attr('string', {
|
||||
for: 'vault',
|
||||
isNestedAttribute: true,
|
||||
description:
|
||||
'Name to use as the SNI host when connecting to Vault via TLS.',
|
||||
})
|
||||
tls_server_name;
|
||||
|
||||
@attr('boolean', {
|
||||
for: 'vault',
|
||||
isNestedAttribute: true,
|
||||
description: 'Whether or not to skip TLS verification.',
|
||||
})
|
||||
tls_skip_verify;
|
||||
|
||||
@attr('string', {
|
||||
for: 'vault',
|
||||
isNestedAttribute: true,
|
||||
description: 'A token used for accessing Vault.',
|
||||
})
|
||||
token;
|
||||
|
||||
@attr('string', {
|
||||
for: 'vault',
|
||||
isNestedAttribute: true,
|
||||
description: 'The Vault token hmac.',
|
||||
readOnly: true,
|
||||
})
|
||||
token_hmac;
|
||||
|
||||
@attr('string', {
|
||||
for: 'vault',
|
||||
isNestedAttribute: true,
|
||||
description:
|
||||
'A PEM-encoded client certificate to use for TLS authentication to the Vault server.',
|
||||
})
|
||||
client_certificate;
|
||||
|
||||
@attr('string', {
|
||||
for: 'vault',
|
||||
isNestedAttribute: true,
|
||||
description:
|
||||
"A PEM-encoded private key matching the client certificate from 'client_certificate'.",
|
||||
})
|
||||
client_certificate_key;
|
||||
|
||||
@attr('string', {
|
||||
for: 'vault',
|
||||
isNestedAttribute: true,
|
||||
description: 'The Vault client certificate key hmac.',
|
||||
readOnly: true,
|
||||
})
|
||||
client_certificate_key_hmac;
|
||||
}
|
||||
@@ -44,13 +44,4 @@ export default class GeneratedManagedGroupModel extends BaseModel {
|
||||
'The ID of the Auth Method that is associated with this ManagedGroup',
|
||||
})
|
||||
auth_method_id;
|
||||
|
||||
// =attributes (OIDC)
|
||||
|
||||
@attr('string', {
|
||||
isNestedAttribute: true,
|
||||
description:
|
||||
'The boolean expression filter to use to determine membership.',
|
||||
})
|
||||
filter;
|
||||
}
|
||||
@@ -34,12 +34,6 @@ export default class GeneratedTargetModel extends BaseModel {
|
||||
})
|
||||
session_connection_limit;
|
||||
|
||||
@attr('string', {
|
||||
description:
|
||||
'Optional boolean expression to filter the workers that are allowed to satisfy this request.',
|
||||
})
|
||||
worker_filter;
|
||||
|
||||
@attr('date', {
|
||||
description: 'The time this resource was created\nOutput only.',
|
||||
readOnly: true,
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
import GeneratedAccountModel from '../generated/models/account';
|
||||
import { fragment } from 'ember-data-model-fragments/attributes';
|
||||
import { computed } from '@ember/object';
|
||||
import { equal } from '@ember/object/computed';
|
||||
|
||||
export default class AccountModel extends GeneratedAccountModel {
|
||||
// =attributes
|
||||
|
||||
/**
|
||||
* Attributes of this resource, if any, represented as a JSON fragment.
|
||||
* @type {FragmentAccountAttributesModel}
|
||||
*/
|
||||
@fragment('fragment-account-attributes', { defaultValue: {} }) attributes;
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
@@ -19,9 +26,9 @@ export default class AccountModel extends GeneratedAccountModel {
|
||||
* Convenience for getting username in account.
|
||||
* @type {string}
|
||||
*/
|
||||
@computed('{email,full_name,login_name}')
|
||||
@computed('attributes.{email,full_name,login_name}')
|
||||
get accountName() {
|
||||
const { email, full_name, login_name } = this;
|
||||
const { email, full_name, login_name } = this.attributes;
|
||||
return email || full_name || login_name;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import GeneratedCredentialLibraryModel from '../generated/models/credential-library';
|
||||
import { attr } from '@ember-data/model';
|
||||
import { fragment } from 'ember-data-model-fragments/attributes';
|
||||
|
||||
/**
|
||||
* Enum options for credential library.
|
||||
@@ -7,4 +9,22 @@ export const options = {
|
||||
http_method: ['GET', 'POST'],
|
||||
};
|
||||
|
||||
export default class CredentialLibraryModel extends GeneratedCredentialLibraryModel {}
|
||||
export default class CredentialLibraryModel extends GeneratedCredentialLibraryModel {
|
||||
// =error attributes
|
||||
// These attributes exist solely to capture errors on nested fields.
|
||||
// See the application adapter's error normalization method for
|
||||
// more information.
|
||||
|
||||
@attr('string', { readOnly: true }) attributes_http_method;
|
||||
@attr('string', { readOnly: true }) attributes_http_request_body;
|
||||
@attr('string', { readOnly: true }) attributes_path;
|
||||
|
||||
// =attributes
|
||||
|
||||
/**
|
||||
* Attributes of this resource, if any, represented as a JSON fragment.
|
||||
* @type {FragmentCredentialLibraryAttributesModel}
|
||||
*/
|
||||
@fragment('fragment-credential-library-attributes', { defaultValue: {} })
|
||||
attributes;
|
||||
}
|
||||
@@ -1,16 +1,34 @@
|
||||
import GeneratedCredentialStoreModel from '../generated/models/credential-store';
|
||||
import { attr } from '@ember-data/model';
|
||||
import { fragment } from 'ember-data-model-fragments/attributes';
|
||||
import { equal } from '@ember/object/computed';
|
||||
|
||||
export default class CredentialStoreModel extends GeneratedCredentialStoreModel {
|
||||
// =error attributes
|
||||
// These attributes exist solely to capture errors on nested fields.
|
||||
// See the application adapter's error normalization method for
|
||||
// more information.
|
||||
|
||||
@attr('string', { readOnly: true }) attributes_address;
|
||||
@attr('string', { readOnly: true }) attributes_namespace;
|
||||
@attr('string', { readOnly: true }) attributes_ca_cert;
|
||||
@attr('string', { readOnly: true }) attributes_tls_server_name;
|
||||
@attr('string', { readOnly: true }) attributes_tls_skip_verify;
|
||||
@attr('string', { readOnly: true }) attributes_token;
|
||||
@attr('string', { readOnly: true }) attributes_client_certificate;
|
||||
@attr('string', { readOnly: true }) attributes_client_certificate_key;
|
||||
|
||||
// =attributes
|
||||
|
||||
/**
|
||||
* Attributes of this resource, if any, represented as a JSON fragment.
|
||||
* @type {FragmentAuthMethodAttributesModel}
|
||||
*/
|
||||
@fragment('fragment-credential-store-attributes', { defaultValue: {} })
|
||||
attributes;
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
@equal('type', 'vault') isVault;
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
@equal('type', 'static') isStatic;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import Fragment from 'ember-data-model-fragments/fragment';
|
||||
import { attr } from '@ember-data/model';
|
||||
|
||||
export default class FragmentAccountAttributesModel extends Fragment {
|
||||
// =attributes (password)
|
||||
@attr('string', {
|
||||
for: 'password',
|
||||
description: 'The account login name',
|
||||
})
|
||||
login_name;
|
||||
|
||||
// =attributes (OIDC)
|
||||
@attr('string', { for: 'oidc' }) subject;
|
||||
@attr('string', { for: 'oidc' }) issuer;
|
||||
@attr('string', { for: 'oidc', readOnly: true }) email;
|
||||
@attr('string', { for: 'oidc', readOnly: true }) full_name;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import Fragment from 'ember-data-model-fragments/fragment';
|
||||
import { attr } from '@ember-data/model';
|
||||
import { options } from './credential-library';
|
||||
|
||||
export default class FragmentCredentialLibraryAttributesModel extends Fragment {
|
||||
//= attributes (vault)
|
||||
|
||||
@attr('string', {
|
||||
description:
|
||||
'The HTTP method the library uses when requesting credentials from Vault.',
|
||||
defaultValue: () => options.http_method[0],
|
||||
})
|
||||
http_method;
|
||||
|
||||
@attr('string', {
|
||||
description:
|
||||
'The body of the HTTP request the library sends to Vault when requesting credentials. Only valid if `http_method` is set to `POST`.',
|
||||
})
|
||||
http_request_body;
|
||||
|
||||
@attr('string', {
|
||||
description: 'The path in Vault to request credentials from.',
|
||||
})
|
||||
path;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
import Fragment from 'ember-data-model-fragments/fragment';
|
||||
import { attr } from '@ember-data/model';
|
||||
|
||||
export default class FragmentCredentialStoreAttributesModel extends Fragment {
|
||||
// =attributes (vault)
|
||||
@attr('string', {
|
||||
for: 'vault',
|
||||
description:
|
||||
"The address to Vault server. This should be a complete URL such as 'https://127.0.0.1:8200'",
|
||||
})
|
||||
address;
|
||||
|
||||
@attr('string', {
|
||||
for: 'vault',
|
||||
description: 'The namespace within Vault to use.',
|
||||
})
|
||||
namespace;
|
||||
|
||||
@attr('string', {
|
||||
for: 'vault',
|
||||
description:
|
||||
"A PEM-encoded CA certificate to verify the Vault server's TLS certificate.",
|
||||
})
|
||||
ca_cert;
|
||||
|
||||
@attr('string', {
|
||||
for: 'vault',
|
||||
description:
|
||||
'Name to use as the SNI host when connecting to Vault via TLS.',
|
||||
})
|
||||
tls_server_name;
|
||||
|
||||
@attr('boolean', {
|
||||
for: 'vault',
|
||||
description: 'Whether or not to skip TLS verification.',
|
||||
})
|
||||
tls_skip_verify;
|
||||
|
||||
@attr('string', {
|
||||
for: 'vault',
|
||||
description: 'A token used for accessing Vault.',
|
||||
})
|
||||
token;
|
||||
|
||||
@attr('string', {
|
||||
for: 'vault',
|
||||
description: 'The Vault token hmac.',
|
||||
readOnly: true,
|
||||
})
|
||||
token_hmac;
|
||||
|
||||
@attr('string', {
|
||||
for: 'vault',
|
||||
description:
|
||||
'A PEM-encoded client certificate to use for TLS authentication to the Vault server.',
|
||||
})
|
||||
client_certificate;
|
||||
|
||||
@attr('string', {
|
||||
for: 'vault',
|
||||
description:
|
||||
"A PEM-encoded private key matching the client certificate from 'client_certificate'.",
|
||||
})
|
||||
client_certificate_key;
|
||||
|
||||
@attr('string', {
|
||||
for: 'vault',
|
||||
description: 'The Vault client certificate key hmac.',
|
||||
readOnly: true,
|
||||
})
|
||||
client_certificate_key_hmac;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import Fragment from 'ember-data-model-fragments/fragment';
|
||||
import { attr } from '@ember-data/model';
|
||||
|
||||
export default class FragmentManagedGroupAttributesModel extends Fragment {
|
||||
// =attributes (OIDC)
|
||||
|
||||
@attr('string', {
|
||||
description:
|
||||
'The boolean expression filter to use to determine membership.',
|
||||
})
|
||||
filter;
|
||||
}
|
||||
@@ -1,10 +1,18 @@
|
||||
import GeneratedManagedGroupModel from '../generated/models/managed-group';
|
||||
import { attr } from '@ember-data/model';
|
||||
import { fragment } from 'ember-data-model-fragments/attributes';
|
||||
import { A } from '@ember/array';
|
||||
|
||||
export default class ManagedGroupModel extends GeneratedManagedGroupModel {
|
||||
// =attributes
|
||||
|
||||
// =error attributes
|
||||
// These attributes exist solely to capture errors on nested fields.
|
||||
// See the application adapter's error normalization method for
|
||||
// more information.
|
||||
|
||||
@attr('string', { readOnly: true }) attributes_filter;
|
||||
|
||||
/**
|
||||
* Members is read-only under normal circumstances. But members can
|
||||
* be persisted via calls to `addMembers()` or `removeMembers()`.
|
||||
@@ -15,4 +23,7 @@ export default class ManagedGroupModel extends GeneratedManagedGroupModel {
|
||||
emptyArrayIfMissing: true,
|
||||
})
|
||||
member_ids;
|
||||
|
||||
@fragment('fragment-managed-group-attributes', { defaultValue: {} })
|
||||
attributes;
|
||||
}
|
||||
@@ -23,13 +23,6 @@ export default class RoleModel extends GeneratedRoleModel {
|
||||
*/
|
||||
@array('string', { readOnly: true }) grant_strings;
|
||||
|
||||
/**
|
||||
* Convenience for looking up the grant scope, if loaded.
|
||||
*/
|
||||
get grantScope() {
|
||||
return this.store.peekRecord('scope', this.grant_scope_id);
|
||||
}
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,7 +13,7 @@ class SessionCredential {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static Source = class Source {
|
||||
static Library = class Library {
|
||||
id;
|
||||
name;
|
||||
description;
|
||||
@@ -42,7 +42,7 @@ class SessionCredential {
|
||||
|
||||
// =attributes
|
||||
rawCredential;
|
||||
source;
|
||||
library;
|
||||
#payloadSecret;
|
||||
|
||||
/**
|
||||
@@ -72,8 +72,8 @@ class SessionCredential {
|
||||
// =methods
|
||||
|
||||
constructor(cred) {
|
||||
const { id, name, description, type } = cred.credential_source;
|
||||
this.source = new SessionCredential.Source(id, name, description, type);
|
||||
const { id, name, description, type } = cred.credential_library;
|
||||
this.library = new SessionCredential.Library(id, name, description, type);
|
||||
this.#payloadSecret = cred.secret;
|
||||
this.rawCredential = cred;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ export default class UserModel extends GeneratedUserModel {
|
||||
* There are many options, so we fallback in order of precedence.
|
||||
* @type {string}
|
||||
*/
|
||||
@computed('email', 'full_name', 'login_name')
|
||||
@computed('email,full_name,login_name,displayName')
|
||||
get accountName() {
|
||||
const { email, full_name, login_name } = this;
|
||||
return email || full_name || login_name;
|
||||
|
||||
@@ -33,12 +33,12 @@ export default class AccountSerializer extends ApplicationSerializer {
|
||||
* `attributes` entirely on update.
|
||||
*/
|
||||
serializeOIDC(snapshot) {
|
||||
const { isNew } = snapshot?.record || {};
|
||||
const { isNew } = snapshot?.record;
|
||||
let serialized = super.serialize(...arguments);
|
||||
delete serialized.attributes;
|
||||
if (isNew) {
|
||||
serialized.attributes = {};
|
||||
const { issuer, subject } = snapshot.record;
|
||||
const { issuer, subject } = snapshot.attr('attributes').record;
|
||||
if (issuer) serialized.attributes.issuer = issuer;
|
||||
if (subject) serialized.attributes.subject = subject;
|
||||
}
|
||||
@@ -70,7 +70,7 @@ export default class AccountSerializer extends ApplicationSerializer {
|
||||
}
|
||||
// Change password custom method
|
||||
if (snapshot?.adapterOptions?.method === 'change-password') {
|
||||
const { currentPassword, newPassword } = snapshot?.adapterOptions || {};
|
||||
const { currentPassword, newPassword } = snapshot?.adapterOptions;
|
||||
serialized = this.serializeForChangePassword(
|
||||
snapshot,
|
||||
currentPassword,
|
||||
|
||||
@@ -137,7 +137,7 @@ export default class ApplicationSerializer extends RESTSerializer {
|
||||
}
|
||||
|
||||
/**
|
||||
* In our API, singular resources are _unrooted_, whereas Ember Data expects
|
||||
* In our API, singluar resources are _unrooted_, whereas Ember Data expects
|
||||
* them to be rooted under their model name, e.g. `{modelName: {…}}`.
|
||||
* This method makes this transformation to accommodate Ember Data.
|
||||
*
|
||||
@@ -268,48 +268,4 @@ export default class ApplicationSerializer extends RESTSerializer {
|
||||
});
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the API returns an updated response with removed fields, we need to
|
||||
* explicitly set any read only field that is on the model but wasn't
|
||||
* returned in the response to `null`.
|
||||
* This will let ember data know the field was removed, otherwise
|
||||
* it won't touch the removed field and will use the old value.
|
||||
*
|
||||
* @override
|
||||
* @param {object} store
|
||||
* @param {object} primaryModelClass
|
||||
* @param {object} payload
|
||||
* @param {?string} id
|
||||
* @param {string} requestType
|
||||
* @return {object}
|
||||
*/
|
||||
normalizeUpdateRecordResponse(
|
||||
store,
|
||||
primaryModelClass,
|
||||
payload,
|
||||
id,
|
||||
requestType
|
||||
) {
|
||||
const newPayload = copy(payload, true);
|
||||
|
||||
primaryModelClass.attributes.forEach((attribute) => {
|
||||
const {
|
||||
name,
|
||||
options: { readOnly },
|
||||
} = attribute;
|
||||
|
||||
if (readOnly && !Object.prototype.hasOwnProperty.call(newPayload, name)) {
|
||||
newPayload[name] = null;
|
||||
}
|
||||
});
|
||||
|
||||
return super.normalizeUpdateRecordResponse(
|
||||
store,
|
||||
primaryModelClass,
|
||||
newPayload,
|
||||
id,
|
||||
requestType
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,3 @@
|
||||
import ApplicationSerializer from './application';
|
||||
|
||||
export default class CredentialLibrarySerializer extends ApplicationSerializer {
|
||||
/**
|
||||
* @override
|
||||
* @method serialize
|
||||
* @param {Snapshot} snapshot
|
||||
*/
|
||||
serialize() {
|
||||
const serialized = super.serialize(...arguments);
|
||||
if (serialized.attributes) {
|
||||
// Serialize `http_request_body` only if `http_method` is POST
|
||||
if (!serialized.attributes?.http_method?.match(/post/i))
|
||||
delete serialized.attributes.http_request_body;
|
||||
}
|
||||
return serialized;
|
||||
}
|
||||
}
|
||||
export default class CredentialLibrarySerializer extends ApplicationSerializer {}
|
||||
@@ -1,24 +1,3 @@
|
||||
import ApplicationSerializer from './application';
|
||||
|
||||
export default class CredentialStoreSerializer extends ApplicationSerializer {
|
||||
/**
|
||||
* @override
|
||||
* @method serialize
|
||||
* @param {Snapshot} snapshot
|
||||
*/
|
||||
serialize() {
|
||||
const serialized = super.serialize(...arguments);
|
||||
if (serialized.attributes) {
|
||||
// Token cannot be unset. If it's falsy, it must be removed.
|
||||
if (!serialized.attributes?.token) delete serialized.attributes.token;
|
||||
// Client certificate key cannot be unset when certificate is set.
|
||||
// If it's falsy, it must be removed.
|
||||
if (
|
||||
!serialized.attributes?.client_certificate_key &&
|
||||
serialized.attributes?.client_certificate
|
||||
)
|
||||
delete serialized.attributes.client_certificate_key;
|
||||
}
|
||||
return serialized;
|
||||
}
|
||||
}
|
||||
export default class CredentialStoreSerializer extends ApplicationSerializer {}
|
||||
@@ -0,0 +1,26 @@
|
||||
import JSONSerializer from '@ember-data/serializer/json';
|
||||
|
||||
export default class FragmentAccountAttributesSerializer extends JSONSerializer {
|
||||
/**
|
||||
* If an attribute is annotated as readOnly in the model, don't serialize it.
|
||||
* Otherwise delegate to default attribute serializer.
|
||||
*
|
||||
* @override
|
||||
* @method serializeAttribute
|
||||
* @param {Snapshot} snapshot
|
||||
* @param {Object} json
|
||||
* @param {String} key
|
||||
* @param {Object} attribute
|
||||
*/
|
||||
serializeAttribute(snapshot, json, key, attribute) {
|
||||
const { type, options } = attribute;
|
||||
let value = super.serializeAttribute(...arguments);
|
||||
// Convert empty strings to null.
|
||||
if (type === 'string' && json[key] === '') json[key] = null;
|
||||
// Do not serialize read-only attributes.
|
||||
if (options.readOnly) delete json[key];
|
||||
// Client secret cannot be unset. If it's falsy, it must be removed.
|
||||
if (key === 'client_secret' && !json[key]) delete json[key];
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import JSONSerializer from '@ember-data/serializer/json';
|
||||
|
||||
export default class FragmentCredentialLibraryAttributesSerializer extends JSONSerializer {
|
||||
/**
|
||||
* If an attribute is annotated as readOnly in the model, don't serialize it.
|
||||
* Otherwise delegate to default attribute serializer.
|
||||
* Only serialize http_request_body when `http_method` is set to `POST`.
|
||||
* @override
|
||||
* @method serializeAttribute
|
||||
* @param {Snapshot} snapshot
|
||||
* @param {Object} json
|
||||
* @param {String} key
|
||||
* @param {Object} attribute
|
||||
*/
|
||||
serializeAttribute(snapshot, json, key, attribute) {
|
||||
const { type, options } = attribute;
|
||||
let value = super.serializeAttribute(...arguments);
|
||||
// Convert empty strings to null.
|
||||
if (type === 'string' && json[key] === '') json[key] = null;
|
||||
// Do not serialize read-only attributes.
|
||||
if (options.readOnly) delete json[key];
|
||||
// Do not serialize http_request_body unless http_method is POST
|
||||
if (key === 'http_request_body' && !json['http_method']?.match(/post/i))
|
||||
delete json[key];
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import JSONSerializer from '@ember-data/serializer/json';
|
||||
|
||||
export default class FragmentCredentialStoreAttributesSerializer extends JSONSerializer {
|
||||
/**
|
||||
* If an attribute is annotated as readOnly in the model, don't serialize it.
|
||||
* Otherwise delegate to default attribute serializer.
|
||||
*
|
||||
* @override
|
||||
* @method serializeAttribute
|
||||
* @param {Snapshot} snapshot
|
||||
* @param {Object} json
|
||||
* @param {String} key
|
||||
* @param {Object} attribute
|
||||
*/
|
||||
serializeAttribute(snapshot, json, key, attribute) {
|
||||
const { type, options } = attribute;
|
||||
let value = super.serializeAttribute(...arguments);
|
||||
// Convert empty strings to null.
|
||||
if (type === 'string' && json[key] === '') json[key] = null;
|
||||
// Do not serialize read-only attributes.
|
||||
if (options.readOnly) delete json[key];
|
||||
// Token cannot be unset. If it's falsy, it must be removed.
|
||||
if (key === 'token' && !json[key]) delete json[key];
|
||||
// Client certificate key cannot be unset when certificate is set.
|
||||
// If it's falsy, it must be removed.
|
||||
if (
|
||||
key === 'client_certificate_key' &&
|
||||
!json[key] &&
|
||||
json['client_certificate']
|
||||
)
|
||||
delete json[key];
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import JSONSerializer from '@ember-data/serializer/json';
|
||||
|
||||
export default class FragmentManagedGroupAttributesSerializer extends JSONSerializer {
|
||||
/**
|
||||
* If an attribute is annotated as readOnly in the model, don't serialize it.
|
||||
* Otherwise delegate to default attribute serializer.
|
||||
* @override
|
||||
* @method serializeAttribute
|
||||
* @param {Snapshot} snapshot
|
||||
* @param {Object} json
|
||||
* @param {String} key
|
||||
* @param {Object} attribute
|
||||
*/
|
||||
serializeAttribute(snapshot, json, key, attribute) {
|
||||
const { type, options } = attribute;
|
||||
let value = super.serializeAttribute(...arguments);
|
||||
// Convert empty string to null.
|
||||
if (type === 'string' && json[key] === '') json[key] = null;
|
||||
// Do not serialize read-only attributes.
|
||||
if (options.readOnly) delete json[key];
|
||||
// Version is sent only if it has a non-nullish value
|
||||
if (key === 'version') {
|
||||
if (json[key] === null || json[key] === undefined) delete json[key];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from 'api/abilities/credential-store';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/models/fragment-account-attributes';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/models/fragment-credential-library-attributes';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/models/fragment-credential-store-attributes';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/models/fragment-managed-group-attributes';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/serializers/fragment-account-attributes';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/serializers/fragment-credential-library-attributes';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/serializers/fragment-credential-store-attributes';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/serializers/fragment-managed-group-attributes';
|
||||
@@ -1,7 +1,6 @@
|
||||
import factory from '../generated/factories/account';
|
||||
import { random, internet } from 'faker';
|
||||
import permissions from '../helpers/permissions';
|
||||
import generateId from '../helpers/id';
|
||||
|
||||
export default factory.extend({
|
||||
authorized_actions: () =>
|
||||
@@ -12,9 +11,6 @@ export default factory.extend({
|
||||
'delete',
|
||||
'set-password',
|
||||
],
|
||||
|
||||
id: () => generateId('acct_'),
|
||||
|
||||
attributes() {
|
||||
switch (this.type) {
|
||||
case 'password':
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import factory from '../generated/factories/auth-method';
|
||||
import { trait } from 'ember-cli-mirage';
|
||||
import permissions from '../helpers/permissions';
|
||||
import generateId from '../helpers/id';
|
||||
|
||||
const types = ['password', 'oidc'];
|
||||
|
||||
@@ -19,8 +18,7 @@ export default factory.extend({
|
||||
'managed-groups': ['create', 'list'],
|
||||
};
|
||||
},
|
||||
|
||||
id: () => generateId('am_'),
|
||||
id: (i) => `auth-method-id-${i}`,
|
||||
|
||||
// Cycle through available types
|
||||
type: (i) => types[i % types.length],
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import factory from '../generated/factories/credential-library';
|
||||
import { random, system } from 'faker';
|
||||
import permissions from '../helpers/permissions';
|
||||
import generateId from '../helpers/id';
|
||||
|
||||
const types = ['vault'];
|
||||
|
||||
export default factory.extend({
|
||||
id: () => generateId('cl_'),
|
||||
id: (i) => `credential-library-id-${i}`,
|
||||
type: (i) => types[i % types.length],
|
||||
|
||||
authorized_actions: () =>
|
||||
|
||||
@@ -2,9 +2,8 @@ import factory from '../generated/factories/credential-store';
|
||||
import { random, internet, datatype } from 'faker';
|
||||
import { trait } from 'ember-cli-mirage';
|
||||
import permissions from '../helpers/permissions';
|
||||
import generateId from '../helpers/id';
|
||||
|
||||
const types = ['vault', 'static'];
|
||||
const types = ['vault'];
|
||||
|
||||
export default factory.extend({
|
||||
authorized_actions: () =>
|
||||
@@ -19,7 +18,7 @@ export default factory.extend({
|
||||
'credential-libraries': ['create', 'list'],
|
||||
};
|
||||
},
|
||||
id: () => generateId('cs_'),
|
||||
id: (i) => `credential-store-id-${i}`,
|
||||
type: (i) => types[i % types.length],
|
||||
|
||||
attributes() {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import factory from '../generated/factories/group';
|
||||
import { trait } from 'ember-cli-mirage';
|
||||
import permissions from '../helpers/permissions';
|
||||
import generateId from '../helpers/id';
|
||||
|
||||
export default factory.extend({
|
||||
authorized_actions: () =>
|
||||
@@ -13,8 +12,7 @@ export default factory.extend({
|
||||
'add-members',
|
||||
'remove-members',
|
||||
],
|
||||
|
||||
id: () => generateId('g_'),
|
||||
id: (i) => `group-${i}`,
|
||||
|
||||
/**
|
||||
* Generates some users for the same scope and assigns them to the group
|
||||
|
||||
@@ -2,7 +2,6 @@ import factory from '../generated/factories/host-catalog';
|
||||
import { trait } from 'ember-cli-mirage';
|
||||
import permissions from '../helpers/permissions';
|
||||
import { datatype, address, random } from 'faker';
|
||||
import generateId from '../helpers/id';
|
||||
|
||||
const types = ['static', 'plugin'];
|
||||
// Represents known plugin types, except "foobar" which models the possibility
|
||||
@@ -12,7 +11,7 @@ const pluginTypes = ['aws', 'azure', 'foobar'];
|
||||
let pluginTypeCounter = 1;
|
||||
|
||||
export default factory.extend({
|
||||
id: () => generateId('hc_'),
|
||||
id: (i) => `host-catalog-id-${i}`,
|
||||
|
||||
// Cycle through available types
|
||||
type: (i) => types[i % types.length],
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import factory from '../generated/factories/host-set';
|
||||
import permissions from '../helpers/permissions';
|
||||
import { datatype, internet, database } from 'faker';
|
||||
import generateId from '../helpers/id';
|
||||
|
||||
export default factory.extend({
|
||||
id: () => generateId('hs_'),
|
||||
id: (i) => `host-set-id-${i}`,
|
||||
type() {
|
||||
return this.hostCatalog?.type || factory.attrs.type;
|
||||
},
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import factory from '../generated/factories/host';
|
||||
import permissions from '../helpers/permissions';
|
||||
import { internet, datatype } from 'faker';
|
||||
import generateId from '../helpers/id';
|
||||
|
||||
export default factory.extend({
|
||||
id: () => generateId('h_'),
|
||||
|
||||
id: (i) => `host-id-${i}`,
|
||||
type() {
|
||||
return this.hostCatalog?.type || factory.attrs.type;
|
||||
},
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import factory from '../generated/factories/managed-group';
|
||||
import { random } from 'faker';
|
||||
import permissions from '../helpers/permissions';
|
||||
import generateId from '../helpers/id';
|
||||
|
||||
const types = ['oidc'];
|
||||
|
||||
export default factory.extend({
|
||||
id: (i) => `managed-groups-id-${i}`,
|
||||
type: (i) => types[i % types.length],
|
||||
|
||||
authorized_actions: () =>
|
||||
@@ -16,8 +16,6 @@ export default factory.extend({
|
||||
'delete',
|
||||
],
|
||||
|
||||
id: () => generateId('mg_'),
|
||||
|
||||
attributes() {
|
||||
switch (this.type) {
|
||||
case 'oidc':
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import factory from '../generated/factories/role';
|
||||
import { trait } from 'ember-cli-mirage';
|
||||
import permissions from '../helpers/permissions';
|
||||
import generateId from '../helpers/id';
|
||||
|
||||
export default factory.extend({
|
||||
authorized_actions: () =>
|
||||
@@ -20,8 +19,6 @@ export default factory.extend({
|
||||
'id=*;type=host-catalog;actions=create,read',
|
||||
],
|
||||
|
||||
id: () => generateId('r_'),
|
||||
|
||||
/**
|
||||
* Adds principals to the role.
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import factory from '../generated/factories/scope';
|
||||
import { trait } from 'ember-cli-mirage';
|
||||
import permissions from '../helpers/permissions';
|
||||
import generateId from '../helpers/id';
|
||||
|
||||
export default factory.extend({
|
||||
type: 'global',
|
||||
@@ -28,7 +27,15 @@ export default factory.extend({
|
||||
};
|
||||
},
|
||||
|
||||
id: () => generateId('s_'),
|
||||
/**
|
||||
* Generates realistic-ish IDs while still being deterministic.
|
||||
*/
|
||||
id(i) {
|
||||
let id = 'tv6fv3yz8p';
|
||||
if (i % 3) id = 'xk1i4dk50v';
|
||||
if (i % 2) id = 's9n819zgko';
|
||||
return `s_${id}${i}`;
|
||||
},
|
||||
|
||||
withChildren: trait({
|
||||
afterCreate(record, server) {
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
import factory from '../generated/factories/session';
|
||||
import { trait } from 'ember-cli-mirage';
|
||||
import { random } from 'faker';
|
||||
import generateId from '../helpers/id';
|
||||
|
||||
const statusStrings = ['pending', 'active', 'canceling', 'terminated'];
|
||||
|
||||
export const pickRandomStatusString = () => random.arrayElement(statusStrings);
|
||||
|
||||
export default factory.extend({
|
||||
id: () => generateId('ss_'),
|
||||
|
||||
id: (i) => `session-id-${i}`,
|
||||
status: pickRandomStatusString,
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,7 +2,6 @@ import factory from '../generated/factories/target';
|
||||
import { trait } from 'ember-cli-mirage';
|
||||
import { random, datatype } from 'faker';
|
||||
import permissions from '../helpers/permissions';
|
||||
import generateId from '../helpers/id';
|
||||
|
||||
const randomBoolean = (chance = 0.5) => Math.random() < chance;
|
||||
const hostSetChance = 0.3;
|
||||
@@ -22,13 +21,10 @@ export default factory.extend({
|
||||
'remove-credential-sources',
|
||||
],
|
||||
|
||||
id: () => generateId('t_'),
|
||||
|
||||
/**
|
||||
* -1 means "unlimited" and we want to generate these on occasion.
|
||||
*/
|
||||
session_connection_limit: () => random.arrayElement([-1, datatype.number()]),
|
||||
worker_filter: (i) => (i % 2 === 0 ? random.words() : null),
|
||||
type: (i) => types[i % types.length],
|
||||
/**
|
||||
* Generates attributes fields by type.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import factory from '../generated/factories/user';
|
||||
import permissions from '../helpers/permissions';
|
||||
import generateId from '../helpers/id';
|
||||
|
||||
export default factory.extend({
|
||||
authorized_actions: () =>
|
||||
@@ -12,5 +11,5 @@ export default factory.extend({
|
||||
'add-accounts',
|
||||
'remove-accounts',
|
||||
],
|
||||
id: () => generateId('u_'),
|
||||
id: (i) => `user-${i}`,
|
||||
});
|
||||
@@ -9,7 +9,6 @@ export default Factory.extend({
|
||||
name: () => random.words(),
|
||||
session_max_seconds: () => datatype.number(),
|
||||
session_connection_limit: () => datatype.number(),
|
||||
worker_filter: () => random.words(),
|
||||
description: () => random.words(),
|
||||
created_time: () => date.recent(),
|
||||
updated_time: () => date.recent(),
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
const characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
|
||||
/**
|
||||
* The Mulberry32 PRNG, JavaScript implementation. This is a seedable PRNG,
|
||||
* which we need in order to deterministically generate IDs which are stable
|
||||
* across reloads. Unfortunately, the built-in `Math.random` function
|
||||
* is not seedable.
|
||||
*
|
||||
* Source:
|
||||
* https://github.com/bryc/code/blob/master/jshash/PRNGs.md#mulberry32
|
||||
*
|
||||
* @param {number} a
|
||||
* @return {number}
|
||||
*/
|
||||
function mulberry32(a = 0) {
|
||||
return function () {
|
||||
a += 0x6d2b79f5 | 0;
|
||||
var t = Math.imul(a ^ (a >>> 15), 1 | a);
|
||||
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
|
||||
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
||||
};
|
||||
}
|
||||
|
||||
const random = mulberry32();
|
||||
|
||||
/**
|
||||
* Generates a random ID string at least 10 characters long with the
|
||||
* specified prefix.
|
||||
*
|
||||
* @param {string} prefix
|
||||
* @return {string}
|
||||
*/
|
||||
export default function (prefix = '') {
|
||||
let result = '';
|
||||
for (let i = 0; i < 10; i++) {
|
||||
result = result.concat(
|
||||
characters[Math.floor(random() * characters.length)]
|
||||
);
|
||||
}
|
||||
return prefix.concat(result);
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
import { belongsTo } from 'ember-cli-mirage';
|
||||
import Model from './base';
|
||||
import { Model, belongsTo } from 'ember-cli-mirage';
|
||||
|
||||
export default Model.extend({
|
||||
scope: belongsTo(),
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { belongsTo } from 'ember-cli-mirage';
|
||||
import Model from './base';
|
||||
import { Model, belongsTo } from 'ember-cli-mirage';
|
||||
|
||||
export default Model.extend({
|
||||
scope: belongsTo(),
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import { Model } from 'ember-cli-mirage';
|
||||
|
||||
export default Model.extend({
|
||||
assignDefaults(defaultAttrs, attrs) {
|
||||
Object.entries(defaultAttrs).map(([key, value]) => {
|
||||
if (!attrs[key]) {
|
||||
attrs[key] = value;
|
||||
}
|
||||
});
|
||||
},
|
||||
defaultAttrs: () => ({
|
||||
version: 1,
|
||||
authorized_actions: ['no-op', 'read', 'update', 'delete'],
|
||||
created_time: new Date(),
|
||||
}),
|
||||
save() {
|
||||
this.assignDefaults(this.defaultAttrs(), this.attrs);
|
||||
return Model.prototype.save.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
@@ -1,5 +1,4 @@
|
||||
import { belongsTo } from 'ember-cli-mirage';
|
||||
import Model from './base';
|
||||
import { Model, belongsTo } from 'ember-cli-mirage';
|
||||
|
||||
export default Model.extend({
|
||||
scope: belongsTo(),
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { belongsTo } from 'ember-cli-mirage';
|
||||
import Model from './base';
|
||||
import { Model, belongsTo } from 'ember-cli-mirage';
|
||||
|
||||
export default Model.extend({
|
||||
scope: belongsTo(),
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { belongsTo, hasMany } from 'ember-cli-mirage';
|
||||
import Model from './base';
|
||||
import { Model, belongsTo, hasMany } from 'ember-cli-mirage';
|
||||
|
||||
export default Model.extend({
|
||||
scope: belongsTo(),
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { belongsTo, hasMany } from 'ember-cli-mirage';
|
||||
import Model from './base';
|
||||
import { Model, belongsTo, hasMany } from 'ember-cli-mirage';
|
||||
|
||||
export default Model.extend({
|
||||
scope: belongsTo(),
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { belongsTo, hasMany } from 'ember-cli-mirage';
|
||||
import Model from './base';
|
||||
import { Model, belongsTo, hasMany } from 'ember-cli-mirage';
|
||||
|
||||
export default Model.extend({
|
||||
scope: belongsTo(),
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { belongsTo } from 'ember-cli-mirage';
|
||||
import Model from './base';
|
||||
import { Model, belongsTo } from 'ember-cli-mirage';
|
||||
|
||||
export default Model.extend({
|
||||
scope: belongsTo(),
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { belongsTo } from 'ember-cli-mirage';
|
||||
import Model from './base';
|
||||
import { Model, belongsTo } from 'ember-cli-mirage';
|
||||
|
||||
export default Model.extend({
|
||||
scope: belongsTo(),
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { belongsTo, hasMany } from 'ember-cli-mirage';
|
||||
import Model from './base';
|
||||
import { Model, belongsTo, hasMany } from 'ember-cli-mirage';
|
||||
|
||||
export default Model.extend({
|
||||
scope: belongsTo(),
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { belongsTo } from 'ember-cli-mirage';
|
||||
import Model from './base';
|
||||
import { Model, belongsTo } from 'ember-cli-mirage';
|
||||
|
||||
export default Model.extend({
|
||||
scope: belongsTo(),
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import Model from './base';
|
||||
import { belongsTo, hasMany } from 'ember-cli-mirage';
|
||||
import { Model, belongsTo, hasMany } from 'ember-cli-mirage';
|
||||
|
||||
export default Model.extend({
|
||||
scope: belongsTo(),
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { belongsTo, hasMany } from 'ember-cli-mirage';
|
||||
import Model from './base';
|
||||
import { Model, belongsTo, hasMany } from 'ember-cli-mirage';
|
||||
|
||||
export default Model.extend({
|
||||
scope: belongsTo(),
|
||||
|
||||
@@ -66,10 +66,10 @@ export default function initializeMockIPC(server, config) {
|
||||
session_id: newSession.id,
|
||||
credentials: [
|
||||
{
|
||||
credential_source: {
|
||||
credential_library: {
|
||||
id: 'clvlt_4cvscMTl0N',
|
||||
name: 'Source Name',
|
||||
description: 'Source Description',
|
||||
name: 'Library Name',
|
||||
description: 'Library Description',
|
||||
credential_store_id: 'csvlt_Q1HFGt7Jpm',
|
||||
type: 'vault',
|
||||
},
|
||||
@@ -78,10 +78,10 @@ export default function initializeMockIPC(server, config) {
|
||||
},
|
||||
},
|
||||
{
|
||||
credential_source: {
|
||||
credential_library: {
|
||||
id: 'clvlt_4cvscMTl0N',
|
||||
name: 'Source Name',
|
||||
description: 'Source Description',
|
||||
name: 'Library Name',
|
||||
description: 'Library Description',
|
||||
credential_store_id: 'csvlt_Q1HFGt7Jpm',
|
||||
type: 'vault',
|
||||
},
|
||||
@@ -91,10 +91,10 @@ export default function initializeMockIPC(server, config) {
|
||||
},
|
||||
},
|
||||
{
|
||||
credential_source: {
|
||||
credential_library: {
|
||||
id: 'clvlt_9KWscxpcY7',
|
||||
name: 'Source Name',
|
||||
description: 'Source Description',
|
||||
name: 'Library Name',
|
||||
description: 'Library Description',
|
||||
credential_store_id: 'csvlt_Q1HFGt7Jpm',
|
||||
type: 'vault',
|
||||
},
|
||||
@@ -103,10 +103,10 @@ export default function initializeMockIPC(server, config) {
|
||||
},
|
||||
},
|
||||
{
|
||||
credential_source: {
|
||||
credential_library: {
|
||||
id: 'clvlt_9KWscxpcY7',
|
||||
name: 'Source Name',
|
||||
description: 'Source Description',
|
||||
name: 'Library Name',
|
||||
description: 'Library Description',
|
||||
credential_store_id: 'csvlt_Q1HFGt7Jpm',
|
||||
type: 'vault',
|
||||
},
|
||||
|
||||
+11
-17
@@ -16,12 +16,11 @@
|
||||
"lint:hbs:fix": "ember-template-lint . --fix",
|
||||
"lint:js": "eslint .",
|
||||
"lint:js:fix": "eslint . --fix",
|
||||
"format": "yarn run format:js",
|
||||
"format": "npm run format:js",
|
||||
"format:js": "prettier --write '{addon,app,config,stories,tests,mirage}/**/*.js' *.js",
|
||||
"start": "ember serve",
|
||||
"test": "ember test",
|
||||
"test:ember-compatibility": "ember try:each",
|
||||
"precommit": "yarn lint && yarn format && yarn test",
|
||||
"doc:toc": "doctoc README.md"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -34,15 +33,15 @@
|
||||
"ember-fetch": "^8.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.18.5",
|
||||
"@babel/eslint-parser": "^7.18.2",
|
||||
"@babel/plugin-proposal-decorators": "^7.18.6",
|
||||
"js-bexpr": "hashicorp/js-bexpr#9b4a4b54d85eba67fdfc0990133d1518d890b1e1",
|
||||
"@babel/core": "^7.16.5",
|
||||
"@ember/optional-features": "^2.0.0",
|
||||
"@ember/test-helpers": "^2.8.1",
|
||||
"@glimmer/component": "^1.1.2",
|
||||
"@glimmer/tracking": "^1.1.2",
|
||||
"@ember/test-helpers": "^2.6.0",
|
||||
"@glimmer/component": "^1.0.4",
|
||||
"@glimmer/tracking": "^1.0.4",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"broccoli-asset-rev": "^3.0.0",
|
||||
"doctoc": "^2.2.0",
|
||||
"doctoc": "^2.1.0",
|
||||
"ember-auto-import": "^1.12.0",
|
||||
"ember-cli": "~4.1.0",
|
||||
"ember-cli-dependency-checker": "^3.2.0",
|
||||
@@ -59,12 +58,12 @@
|
||||
"ember-resolver": "^8.0.3",
|
||||
"ember-source": "~3.28.4",
|
||||
"ember-template-lint": "^3.7.0",
|
||||
"eslint": "^8.12.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-ember": "^10.5.9",
|
||||
"eslint-plugin-ember": "^10.5.4",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-qunit": "^6.2.0",
|
||||
"js-bexpr": "hashicorp/js-bexpr#9b4a4b54d85eba67fdfc0990133d1518d890b1e1",
|
||||
"loader.js": "^4.7.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.4.0",
|
||||
@@ -79,10 +78,5 @@
|
||||
},
|
||||
"ember-addon": {
|
||||
"configPath": "tests/dummy/config"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.js": "eslint --fix",
|
||||
"*.hbs": "ember-template-lint --fix",
|
||||
"*.{js,scss}": "prettier --write"
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ module('Unit | Model | account', function (hooks) {
|
||||
type: 'password',
|
||||
});
|
||||
assert.notOk(model.accountName);
|
||||
model.login_name = 'foobar';
|
||||
model.attributes.login_name = 'foobar';
|
||||
assert.equal(model.accountName, 'foobar');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module(
|
||||
'Unit | Model | fragment credential library attributes',
|
||||
function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function (assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let model = store.createRecord(
|
||||
'fragment-credential-library-attributes',
|
||||
{}
|
||||
);
|
||||
assert.ok(model);
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,13 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Model | fragment credential store attributes', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function (assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let model = store.createRecord('fragment-credential-store-attributes', {});
|
||||
assert.ok(model);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Model | fragment managed group attributes', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function (assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let model = store.createRecord('fragment-managed-group-attributes', {});
|
||||
assert.ok(model);
|
||||
});
|
||||
});
|
||||
@@ -115,39 +115,4 @@ module('Unit | Model | user', function (hooks) {
|
||||
'User has empty account_ids by default'
|
||||
);
|
||||
});
|
||||
|
||||
test('it defaults to null for readonly attributes when response does not have fields', async function (assert) {
|
||||
assert.expect(3);
|
||||
this.server.post('/v1/users/123abc:remove-accounts', (schema, request) => {
|
||||
const body = JSON.parse(request.requestBody);
|
||||
assert.deepEqual(body, {
|
||||
account_ids: ['3'],
|
||||
version: 1,
|
||||
});
|
||||
return { id: '123abc', name: 'newName' };
|
||||
});
|
||||
const store = this.owner.lookup('service:store');
|
||||
store.push({
|
||||
data: {
|
||||
id: '123abc',
|
||||
type: 'user',
|
||||
attributes: {
|
||||
name: 'user',
|
||||
description: 'Description',
|
||||
account_ids: ['3'],
|
||||
version: 1,
|
||||
login_name: 'zed',
|
||||
scope: {
|
||||
scope_id: 'o_1',
|
||||
type: 'scope',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
const model = store.peekRecord('user', '123abc');
|
||||
await model.removeAccount('3');
|
||||
|
||||
assert.equal(model.login_name, null);
|
||||
assert.equal(model.name, 'newName');
|
||||
});
|
||||
});
|
||||
@@ -13,10 +13,12 @@ module('Unit | Serializer | account', function (hooks) {
|
||||
name: 'Name',
|
||||
auth_method_id: '1',
|
||||
description: 'Description',
|
||||
issuer: 'issuer',
|
||||
subject: 'sub',
|
||||
full_name: 'full_name',
|
||||
email: 'email',
|
||||
attributes: {
|
||||
issuer: 'issuer',
|
||||
subject: 'sub',
|
||||
full_name: 'full_name',
|
||||
email: 'email',
|
||||
},
|
||||
version: 1,
|
||||
});
|
||||
const snapshot = record._createSnapshot();
|
||||
@@ -47,10 +49,12 @@ module('Unit | Serializer | account', function (hooks) {
|
||||
name: 'Name',
|
||||
auth_method_id: '1',
|
||||
description: 'Description',
|
||||
issuer: 'issuer',
|
||||
subject: 'sub',
|
||||
full_name: 'full_name',
|
||||
email: 'email',
|
||||
attributes: {
|
||||
issuer: 'issuer',
|
||||
subject: 'sub',
|
||||
full_name: 'full_name',
|
||||
email: 'email',
|
||||
},
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
@@ -77,7 +81,9 @@ module('Unit | Serializer | account', function (hooks) {
|
||||
name: 'Name',
|
||||
auth_method_id: '1',
|
||||
description: 'Description',
|
||||
login_name: 'Login Name',
|
||||
attributes: {
|
||||
login_name: 'Login Name',
|
||||
},
|
||||
version: 1,
|
||||
});
|
||||
const snapshot = record._createSnapshot();
|
||||
@@ -103,7 +109,9 @@ module('Unit | Serializer | account', function (hooks) {
|
||||
name: 'Name',
|
||||
auth_method_id: '1',
|
||||
description: 'Description',
|
||||
login_name: 'Login Name',
|
||||
attributes: {
|
||||
login_name: 'Login Name',
|
||||
},
|
||||
version: 1,
|
||||
});
|
||||
const snapshot = record._createSnapshot();
|
||||
@@ -136,7 +144,9 @@ module('Unit | Serializer | account', function (hooks) {
|
||||
type: 'password',
|
||||
name: 'Name',
|
||||
description: 'Description',
|
||||
login_name: 'Login Name',
|
||||
attributes: {
|
||||
login_name: 'Login Name',
|
||||
},
|
||||
auth_method_id: '1',
|
||||
version: 1,
|
||||
});
|
||||
@@ -160,7 +170,9 @@ module('Unit | Serializer | account', function (hooks) {
|
||||
type: 'password',
|
||||
name: 'Name',
|
||||
description: 'Description',
|
||||
login_name: 'Login Name',
|
||||
attributes: {
|
||||
login_name: 'Login Name',
|
||||
},
|
||||
auth_method_id: '1',
|
||||
version: 1,
|
||||
});
|
||||
|
||||
@@ -211,41 +211,4 @@ module('Unit | Serializer | application', function (hooks) {
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('it normalizes removed fields correctly', function (assert) {
|
||||
assert.expect(1);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const serializer = store.serializerFor('user');
|
||||
const user = store.createRecord('user').constructor;
|
||||
const payload = {
|
||||
id: '1',
|
||||
name: 'user 1',
|
||||
scope: { id: 'o_123' },
|
||||
};
|
||||
const normalized = serializer.normalizeUpdateRecordResponse(
|
||||
store,
|
||||
user,
|
||||
payload
|
||||
);
|
||||
assert.deepEqual(normalized, {
|
||||
included: [],
|
||||
data: {
|
||||
id: '1',
|
||||
type: 'user',
|
||||
attributes: {
|
||||
authorized_actions: [],
|
||||
name: 'user 1',
|
||||
scope: { scope_id: 'o_123' },
|
||||
account_ids: [],
|
||||
authorized_collection_actions: null,
|
||||
created_time: null,
|
||||
email: null,
|
||||
full_name: null,
|
||||
login_name: null,
|
||||
updated_time: null,
|
||||
},
|
||||
relationships: {},
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -12,8 +12,10 @@ module('Unit | Serializer | credential library', function (hooks) {
|
||||
type: 'vault',
|
||||
name: 'Name',
|
||||
description: 'Description',
|
||||
path: '/vault/path',
|
||||
http_method: 'GET',
|
||||
attributes: {
|
||||
path: '/vault/path',
|
||||
http_method: 'GET',
|
||||
},
|
||||
version: 1,
|
||||
});
|
||||
const snapshot = record._createSnapshot();
|
||||
@@ -43,8 +45,10 @@ module('Unit | Serializer | credential library', function (hooks) {
|
||||
type: 'vault',
|
||||
name: 'Name',
|
||||
description: 'Description',
|
||||
path: '/vault/path',
|
||||
http_method: 'GET',
|
||||
attributes: {
|
||||
path: '/vault/path',
|
||||
http_method: 'GET',
|
||||
},
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
@@ -64,66 +68,4 @@ module('Unit | Serializer | credential library', function (hooks) {
|
||||
version: 1,
|
||||
});
|
||||
});
|
||||
|
||||
test('it serializes empty strings to null', function (assert) {
|
||||
assert.expect(1);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const record = store.createRecord('credential-library', {
|
||||
http_method: '',
|
||||
path: null,
|
||||
});
|
||||
let serializedRecord = record.serialize();
|
||||
assert.deepEqual(serializedRecord, {
|
||||
attributes: {
|
||||
http_method: null,
|
||||
path: null,
|
||||
},
|
||||
credential_store_id: null,
|
||||
description: null,
|
||||
name: null,
|
||||
type: null,
|
||||
});
|
||||
});
|
||||
|
||||
test('it does not serialize http_request_body unless http_method is set to POST', function (assert) {
|
||||
assert.expect(2);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const record = store.createRecord('credential-library', {
|
||||
http_method: 'GET',
|
||||
http_request_body: 'body',
|
||||
});
|
||||
let serializedRecord = record.serialize();
|
||||
assert.deepEqual(
|
||||
serializedRecord,
|
||||
{
|
||||
attributes: {
|
||||
http_method: 'GET',
|
||||
path: null,
|
||||
},
|
||||
credential_store_id: null,
|
||||
description: null,
|
||||
name: null,
|
||||
type: null,
|
||||
},
|
||||
'http_request_body attribute is not expected'
|
||||
);
|
||||
|
||||
record.http_method = 'POST';
|
||||
serializedRecord = record.serialize();
|
||||
assert.deepEqual(
|
||||
serializedRecord,
|
||||
{
|
||||
attributes: {
|
||||
http_method: 'POST',
|
||||
http_request_body: 'body',
|
||||
path: null,
|
||||
},
|
||||
credential_store_id: null,
|
||||
description: null,
|
||||
name: null,
|
||||
type: null,
|
||||
},
|
||||
'http_request_body attribute is expected'
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -12,14 +12,16 @@ module('Unit | Serializer | credential store', function (hooks) {
|
||||
type: 'vault',
|
||||
name: 'Name',
|
||||
description: 'Description',
|
||||
address: 'http://localhost:5000',
|
||||
ca_cert: 'ca-cert-123',
|
||||
client_certificate: 'client-cert-123',
|
||||
client_certificate_key: 'client-cert-key-456',
|
||||
namespace: 'foobar',
|
||||
tls_server_name: 'yes',
|
||||
tls_skip_verify: false,
|
||||
token: 'foo',
|
||||
attributes: {
|
||||
address: 'http://localhost:5000',
|
||||
ca_cert: 'ca-cert-123',
|
||||
client_certificate: 'client-cert-123',
|
||||
client_certificate_key: 'client-cert-key-456',
|
||||
namespace: 'foobar',
|
||||
tls_server_name: 'yes',
|
||||
tls_skip_verify: false,
|
||||
token: 'foo',
|
||||
},
|
||||
version: 1,
|
||||
});
|
||||
const snapshot = record._createSnapshot();
|
||||
@@ -54,14 +56,16 @@ module('Unit | Serializer | credential store', function (hooks) {
|
||||
type: 'vault',
|
||||
name: 'Name',
|
||||
description: 'Description',
|
||||
address: 'http://localhost:5000',
|
||||
ca_cert: 'ca-cert-123',
|
||||
client_certificate: 'client-cert-123',
|
||||
client_certificate_key: 'client-cert-key-456',
|
||||
namespace: 'foobar',
|
||||
tls_server_name: 'yes',
|
||||
tls_skip_verify: false,
|
||||
token: 'foo',
|
||||
attributes: {
|
||||
address: 'http://localhost:5000',
|
||||
ca_cert: 'ca-cert-123',
|
||||
client_certificate: 'client-cert-123',
|
||||
client_certificate_key: 'client-cert-key-456',
|
||||
namespace: 'foobar',
|
||||
tls_server_name: 'yes',
|
||||
tls_skip_verify: false,
|
||||
token: 'foo',
|
||||
},
|
||||
version: 1,
|
||||
},
|
||||
},
|
||||
@@ -86,123 +90,4 @@ module('Unit | Serializer | credential store', function (hooks) {
|
||||
version: 1,
|
||||
});
|
||||
});
|
||||
|
||||
test('it serializes empty strings to null', function (assert) {
|
||||
assert.expect(1);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const record = store.createRecord('credential-store', {
|
||||
address: '',
|
||||
ca_cert: '',
|
||||
client_certificate: '',
|
||||
client_certificate_key: '',
|
||||
namespace: '',
|
||||
tls_server_name: '',
|
||||
tls_skip_verify: false,
|
||||
});
|
||||
let serializedRecord = record.serialize();
|
||||
assert.deepEqual(serializedRecord, {
|
||||
attributes: {
|
||||
address: null,
|
||||
ca_cert: null,
|
||||
client_certificate: null,
|
||||
client_certificate_key: null,
|
||||
namespace: null,
|
||||
tls_server_name: null,
|
||||
tls_skip_verify: false,
|
||||
},
|
||||
description: null,
|
||||
name: null,
|
||||
type: null,
|
||||
});
|
||||
});
|
||||
|
||||
test('it does not serialize token if present but falsy', function (assert) {
|
||||
assert.expect(1);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const record = store.createRecord('credential-store', {
|
||||
token: null,
|
||||
address: 'http://localhost:5000',
|
||||
ca_cert: 'ca-cert-123',
|
||||
client_certificate: 'client-cert-123',
|
||||
client_certificate_key: 'client-cert-key-456',
|
||||
namespace: 'foobar',
|
||||
tls_server_name: 'yes',
|
||||
tls_skip_verify: false,
|
||||
});
|
||||
let serializedRecord = record.serialize();
|
||||
assert.deepEqual(
|
||||
serializedRecord,
|
||||
{
|
||||
attributes: {
|
||||
address: 'http://localhost:5000',
|
||||
ca_cert: 'ca-cert-123',
|
||||
client_certificate: 'client-cert-123',
|
||||
client_certificate_key: 'client-cert-key-456',
|
||||
namespace: 'foobar',
|
||||
tls_server_name: 'yes',
|
||||
tls_skip_verify: false,
|
||||
},
|
||||
description: null,
|
||||
name: null,
|
||||
type: null,
|
||||
},
|
||||
'token attribute is not expected'
|
||||
);
|
||||
});
|
||||
|
||||
test('it does not serialize client certificate key if present but falsy when client certificate is present', function (assert) {
|
||||
assert.expect(2);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const record = store.createRecord('credential-store', {
|
||||
client_certificate: 'client-cert-123',
|
||||
client_certificate_key: '',
|
||||
address: 'http://localhost:5000',
|
||||
token: 'foo',
|
||||
ca_cert: 'ca-cert-123',
|
||||
namespace: 'foobar',
|
||||
tls_server_name: 'yes',
|
||||
tls_skip_verify: false,
|
||||
});
|
||||
let serializedRecord = record.serialize();
|
||||
assert.deepEqual(
|
||||
serializedRecord,
|
||||
{
|
||||
attributes: {
|
||||
client_certificate: 'client-cert-123',
|
||||
address: 'http://localhost:5000',
|
||||
token: 'foo',
|
||||
ca_cert: 'ca-cert-123',
|
||||
namespace: 'foobar',
|
||||
tls_server_name: 'yes',
|
||||
tls_skip_verify: false,
|
||||
},
|
||||
description: null,
|
||||
name: null,
|
||||
type: null,
|
||||
},
|
||||
'client certificate key attribute is not expected'
|
||||
);
|
||||
|
||||
record.client_certificate_key = 'client-cert-key-456';
|
||||
serializedRecord = record.serialize();
|
||||
assert.deepEqual(
|
||||
serializedRecord,
|
||||
{
|
||||
attributes: {
|
||||
client_certificate: 'client-cert-123',
|
||||
client_certificate_key: 'client-cert-key-456',
|
||||
address: 'http://localhost:5000',
|
||||
token: 'foo',
|
||||
ca_cert: 'ca-cert-123',
|
||||
namespace: 'foobar',
|
||||
tls_server_name: 'yes',
|
||||
tls_skip_verify: false,
|
||||
},
|
||||
description: null,
|
||||
name: null,
|
||||
type: null,
|
||||
},
|
||||
'client certificate key attribute is expected'
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Serializer | fragment account attributes', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function (assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let serializer = store.serializerFor('fragment-account-attributes');
|
||||
|
||||
assert.ok(serializer);
|
||||
});
|
||||
|
||||
test('it serializes records', function (assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let record = store.createRecord('fragment-account-attributes', {});
|
||||
|
||||
let serializedRecord = record.serialize();
|
||||
|
||||
assert.ok(serializedRecord);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,59 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module(
|
||||
'Unit | Serializer | fragment credential library attributes',
|
||||
function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it serializes empty strings to null', function (assert) {
|
||||
assert.expect(1);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const record = store.createRecord(
|
||||
'fragment-credential-library-attributes',
|
||||
{
|
||||
http_method: '',
|
||||
path: null,
|
||||
}
|
||||
);
|
||||
let serializedRecord = record.serialize();
|
||||
assert.deepEqual(serializedRecord, {
|
||||
http_method: null,
|
||||
path: null,
|
||||
});
|
||||
});
|
||||
|
||||
test('it does not serialize http_request_body unless http_method is set to POST', function (assert) {
|
||||
assert.expect(2);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const record = store.createRecord(
|
||||
'fragment-credential-library-attributes',
|
||||
{
|
||||
http_method: 'GET',
|
||||
http_request_body: 'body',
|
||||
}
|
||||
);
|
||||
let serializedRecord = record.serialize();
|
||||
assert.deepEqual(
|
||||
serializedRecord,
|
||||
{
|
||||
http_method: 'GET',
|
||||
path: null,
|
||||
},
|
||||
'http_request_body attribute is not expected'
|
||||
);
|
||||
|
||||
record.http_method = 'POST';
|
||||
serializedRecord = record.serialize();
|
||||
assert.deepEqual(
|
||||
serializedRecord,
|
||||
{
|
||||
http_method: 'POST',
|
||||
http_request_body: 'body',
|
||||
path: null,
|
||||
},
|
||||
'http_request_body attribute is expected'
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,117 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module(
|
||||
'Unit | Serializer | fragment credential store attributes',
|
||||
function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it serializes empty strings to null', function (assert) {
|
||||
assert.expect(1);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const record = store.createRecord(
|
||||
'fragment-credential-store-attributes',
|
||||
{
|
||||
address: '',
|
||||
ca_cert: '',
|
||||
client_certificate: '',
|
||||
client_certificate_key: '',
|
||||
namespace: '',
|
||||
tls_server_name: '',
|
||||
tls_skip_verify: false,
|
||||
}
|
||||
);
|
||||
let serializedRecord = record.serialize();
|
||||
assert.deepEqual(serializedRecord, {
|
||||
address: null,
|
||||
ca_cert: null,
|
||||
client_certificate: null,
|
||||
client_certificate_key: null,
|
||||
namespace: null,
|
||||
tls_server_name: null,
|
||||
tls_skip_verify: false,
|
||||
});
|
||||
});
|
||||
|
||||
test('it does not serialize token if present but falsy', function (assert) {
|
||||
assert.expect(1);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const record = store.createRecord(
|
||||
'fragment-credential-store-attributes',
|
||||
{
|
||||
token: null,
|
||||
address: 'http://localhost:5000',
|
||||
ca_cert: 'ca-cert-123',
|
||||
client_certificate: 'client-cert-123',
|
||||
client_certificate_key: 'client-cert-key-456',
|
||||
namespace: 'foobar',
|
||||
tls_server_name: 'yes',
|
||||
tls_skip_verify: false,
|
||||
}
|
||||
);
|
||||
let serializedRecord = record.serialize();
|
||||
assert.deepEqual(
|
||||
serializedRecord,
|
||||
{
|
||||
address: 'http://localhost:5000',
|
||||
ca_cert: 'ca-cert-123',
|
||||
client_certificate: 'client-cert-123',
|
||||
client_certificate_key: 'client-cert-key-456',
|
||||
namespace: 'foobar',
|
||||
tls_server_name: 'yes',
|
||||
tls_skip_verify: false,
|
||||
},
|
||||
'token attribute is not expected'
|
||||
);
|
||||
});
|
||||
|
||||
test('it does not serialize client certificate key if present but falsy when client certificate is present', function (assert) {
|
||||
assert.expect(2);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const record = store.createRecord(
|
||||
'fragment-credential-store-attributes',
|
||||
{
|
||||
client_certificate: 'client-cert-123',
|
||||
client_certificate_key: '',
|
||||
address: 'http://localhost:5000',
|
||||
token: 'foo',
|
||||
ca_cert: 'ca-cert-123',
|
||||
namespace: 'foobar',
|
||||
tls_server_name: 'yes',
|
||||
tls_skip_verify: false,
|
||||
}
|
||||
);
|
||||
let serializedRecord = record.serialize();
|
||||
assert.deepEqual(
|
||||
serializedRecord,
|
||||
{
|
||||
client_certificate: 'client-cert-123',
|
||||
address: 'http://localhost:5000',
|
||||
token: 'foo',
|
||||
ca_cert: 'ca-cert-123',
|
||||
namespace: 'foobar',
|
||||
tls_server_name: 'yes',
|
||||
tls_skip_verify: false,
|
||||
},
|
||||
'client certificate key attribute is not expected'
|
||||
);
|
||||
|
||||
record.client_certificate_key = 'client-cert-key-456';
|
||||
serializedRecord = record.serialize();
|
||||
assert.deepEqual(
|
||||
serializedRecord,
|
||||
{
|
||||
client_certificate: 'client-cert-123',
|
||||
client_certificate_key: 'client-cert-key-456',
|
||||
address: 'http://localhost:5000',
|
||||
token: 'foo',
|
||||
ca_cert: 'ca-cert-123',
|
||||
namespace: 'foobar',
|
||||
tls_server_name: 'yes',
|
||||
tls_skip_verify: false,
|
||||
},
|
||||
'client certificate key attribute is expected'
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,21 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module(
|
||||
'Unit | Serializer | fragment managed groups attributes',
|
||||
function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it serializes empty string to null', function (assert) {
|
||||
assert.expect(1);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const record = store.createRecord('fragment-managed-group-attributes', {
|
||||
filter: '',
|
||||
});
|
||||
const serializedRecord = record.serialize();
|
||||
assert.deepEqual(serializedRecord, {
|
||||
filter: null,
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -41,7 +41,9 @@ module('Unit | Serializer | Managed group', function (hooks) {
|
||||
version: 1,
|
||||
auth_method_id: '1234',
|
||||
type: 'oidc',
|
||||
filter: 'key=value',
|
||||
attributes: {
|
||||
filter: 'key=value',
|
||||
},
|
||||
});
|
||||
const snapshot = record._createSnapshot();
|
||||
snapshot.adapterOptions = {};
|
||||
@@ -73,7 +75,9 @@ module('Unit | Serializer | Managed group', function (hooks) {
|
||||
version: undefined,
|
||||
auth_method_id: '1234',
|
||||
type: 'oidc',
|
||||
filter: 'key=value',
|
||||
attributes: {
|
||||
filter: 'key=value',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -134,7 +138,9 @@ module('Unit | Serializer | Managed group', function (hooks) {
|
||||
version: 1,
|
||||
auth_method_id: '1234',
|
||||
type: 'oidc',
|
||||
filter: 'key=value',
|
||||
attributes: {
|
||||
filter: 'key=value',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -35,7 +35,6 @@ module('Unit | Serializer | target', function (hooks) {
|
||||
scope_id: 'org_1',
|
||||
session_max_seconds: 28800,
|
||||
session_connection_limit: 1,
|
||||
worker_filter: null,
|
||||
attributes: {
|
||||
default_port: 1234,
|
||||
},
|
||||
@@ -87,38 +86,6 @@ module('Unit | Serializer | target', function (hooks) {
|
||||
});
|
||||
});
|
||||
|
||||
test('it serializes the worker_filter attribute if present', function (assert) {
|
||||
assert.expect(1);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const serializer = store.serializerFor('target');
|
||||
const record = store.createRecord('target', {
|
||||
name: 'User',
|
||||
description: 'Description',
|
||||
version: 1,
|
||||
type: 'ssh',
|
||||
worker_filter: 'worker',
|
||||
default_port: 1234,
|
||||
scope: {
|
||||
scope_id: 'org_1',
|
||||
},
|
||||
});
|
||||
const snapshot = record._createSnapshot();
|
||||
const serializedRecord = serializer.serialize(snapshot);
|
||||
assert.deepEqual(serializedRecord, {
|
||||
name: 'User',
|
||||
description: 'Description',
|
||||
version: 1,
|
||||
type: 'ssh',
|
||||
scope_id: 'org_1',
|
||||
session_max_seconds: 28800,
|
||||
session_connection_limit: 1,
|
||||
worker_filter: 'worker',
|
||||
attributes: {
|
||||
default_port: 1234,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('it normalizes records with array fields', function (assert) {
|
||||
assert.expect(1);
|
||||
const store = this.owner.lookup('service:store');
|
||||
@@ -222,36 +189,4 @@ module('Unit | Serializer | target', function (hooks) {
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('it normalizes the worker_filter attribute if present', function (assert) {
|
||||
assert.expect(1);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const serializer = store.serializerFor('target');
|
||||
const target = store.createRecord('target').constructor;
|
||||
const payload = {
|
||||
id: '1',
|
||||
name: 'Target 1',
|
||||
worker_filter: 'worker',
|
||||
};
|
||||
const normalized = serializer.normalizeSingleResponse(
|
||||
store,
|
||||
target,
|
||||
payload
|
||||
);
|
||||
assert.deepEqual(normalized, {
|
||||
included: [],
|
||||
data: {
|
||||
id: '1',
|
||||
type: 'target',
|
||||
attributes: {
|
||||
authorized_actions: [],
|
||||
name: 'Target 1',
|
||||
host_sources: [],
|
||||
application_credential_source_ids: [],
|
||||
worker_filter: 'worker',
|
||||
},
|
||||
relationships: {},
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -2,19 +2,20 @@
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
parser: '@babel/eslint-parser',
|
||||
parser: 'babel-eslint',
|
||||
parserOptions: {
|
||||
ecmaVersion: 2018,
|
||||
sourceType: 'module',
|
||||
// This is specific babel-config. If grows consider creating a babel config file
|
||||
requireConfigFile: false,
|
||||
babelOptions: {
|
||||
plugins: [['@babel/plugin-proposal-decorators', { legacy: true }]],
|
||||
ecmaFeatures: {
|
||||
legacyDecorators: true,
|
||||
},
|
||||
// end of babel-config
|
||||
},
|
||||
plugins: ['ember'],
|
||||
extends: ['eslint:recommended', 'plugin:ember/recommended', 'prettier'],
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:ember/recommended',
|
||||
'plugin:prettier/recommended',
|
||||
],
|
||||
env: {
|
||||
browser: true,
|
||||
},
|
||||
|
||||
@@ -34,21 +34,19 @@ List of available project commands. `yarn run <command-name>`
|
||||
| Command | Description |
|
||||
| ------- | ----------- |
|
||||
| lint | Runs all lint commands. |
|
||||
| lint:fix | Runs automatic lint fixes for all files. |
|
||||
| lint:js | Lints `js` files. |
|
||||
| lint:js:fix | Runs automatic lint fixes for `js` files. |
|
||||
| format | Runs all auto-formatters. |
|
||||
| format:js | Auto-formats `js` files using Prettier. |
|
||||
| start | Runs the dummy app local server. |
|
||||
| test | Runs all tests. |
|
||||
| test:all | Runs tests across multiple Ember versions with ember-try. |
|
||||
| precommit | Runs all lint, format and tests. |
|
||||
| doc:toc | Automatically generates a table of contents for this README file. |
|
||||
|
||||
Additional commands in the monorepo package may affect this projects.
|
||||
|
||||
## Linting
|
||||
|
||||
* `yarn lint:hbs`
|
||||
* `yarn lint:js`
|
||||
* `yarn lint:js --fix`
|
||||
|
||||
|
||||
+11
-16
@@ -10,14 +10,14 @@
|
||||
"scripts": {
|
||||
"lint": "npm-run-all --aggregate-output --continue-on-error --parallel 'lint:!(fix)'",
|
||||
"lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix",
|
||||
"lint:hbs:fix": "ember-template-lint . --fix",
|
||||
"lint:js": "eslint .",
|
||||
"lint:js:fix": "eslint . --fix",
|
||||
"format": "yarn run format:js",
|
||||
"format": "npm run format:js",
|
||||
"format:js": "prettier --write '{addon,app,config,stories,tests}/**/*.js' *.js",
|
||||
"lint:js:fix": "eslint . --fix",
|
||||
"start": "ember serve",
|
||||
"test": "ember test",
|
||||
"test:ember-compatibility": "ember try:each",
|
||||
"precommit": "yarn lint && yarn format && yarn test",
|
||||
"doc:toc": "doctoc README.md"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -27,15 +27,14 @@
|
||||
"ember-simple-auth": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/eslint-parser": "^7.18.2",
|
||||
"@babel/plugin-proposal-decorators": "^7.18.6",
|
||||
"@ember/optional-features": "^2.0.0",
|
||||
"@ember/test-helpers": "^2.8.1",
|
||||
"@glimmer/component": "^1.1.2",
|
||||
"@glimmer/tracking": "^1.1.2",
|
||||
"@ember/test-helpers": "^2.6.0",
|
||||
"@glimmer/component": "^1.0.4",
|
||||
"@glimmer/tracking": "^1.0.4",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"broccoli-asset-rev": "^3.0.0",
|
||||
"core": "*",
|
||||
"doctoc": "^2.2.0",
|
||||
"doctoc": "^2.1.0",
|
||||
"ember-auto-import": "^1.12.0",
|
||||
"ember-cli": "~4.1.0",
|
||||
"ember-cli-dependency-checker": "^3.2.0",
|
||||
@@ -52,10 +51,11 @@
|
||||
"ember-resolver": "^8.0.3",
|
||||
"ember-source": "~3.28.4",
|
||||
"ember-template-lint": "^3.7.0",
|
||||
"eslint": "^8.12.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-ember": "^10.5.9",
|
||||
"eslint-plugin-ember": "^10.5.4",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-qunit": "^6.2.0",
|
||||
"loader.js": "^4.7.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
@@ -71,10 +71,5 @@
|
||||
},
|
||||
"ember-addon": {
|
||||
"configPath": "tests/dummy/config"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.js": "eslint --fix",
|
||||
"*.hbs": "ember-template-lint --fix",
|
||||
"*.{js,scss}": "prettier --write"
|
||||
}
|
||||
}
|
||||
@@ -2,19 +2,20 @@
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
parser: '@babel/eslint-parser',
|
||||
parser: 'babel-eslint',
|
||||
parserOptions: {
|
||||
ecmaVersion: 2018,
|
||||
sourceType: 'module',
|
||||
// This is specific babel-config. If grows consider creating a babel config file
|
||||
requireConfigFile: false,
|
||||
babelOptions: {
|
||||
plugins: [['@babel/plugin-proposal-decorators', { legacy: true }]],
|
||||
ecmaFeatures: {
|
||||
legacyDecorators: true,
|
||||
},
|
||||
// end of babel-config
|
||||
},
|
||||
plugins: ['ember'],
|
||||
extends: ['eslint:recommended', 'plugin:ember/recommended', 'prettier'],
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:ember/recommended',
|
||||
'plugin:prettier/recommended',
|
||||
],
|
||||
env: {
|
||||
browser: true,
|
||||
},
|
||||
|
||||
+14
-7
@@ -5,6 +5,7 @@ helpers.
|
||||
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
|
||||
- [Add core to an App](#add-core-to-an-app)
|
||||
- [Installation](#installation)
|
||||
@@ -25,6 +26,18 @@ helpers.
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
|
||||
- [Add core to an App](#add-core-to-an-app)
|
||||
- [Installation](#installation)
|
||||
- [Yarn Commands](#yarn-commands)
|
||||
- [Linting](#linting)
|
||||
- [Formatting](#formatting)
|
||||
- [Running tests](#running-tests)
|
||||
- [Running the dummy application](#running-the-dummy-application)
|
||||
- [Contributing](#contributing)
|
||||
- [Building ToC](#building-toc)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
|
||||
## Add core to an App
|
||||
|
||||
Add this addon to an Ember application's `devDependencies` as:
|
||||
@@ -141,16 +154,11 @@ List of available project commands. `yarn run <command-name>`
|
||||
| build | Builds the dummy app for production. |
|
||||
| lint | Runs all lint commands. |
|
||||
| lint:js | Lints `js` files. |
|
||||
| lint:js:fix | Runs automatic lint fixes for `js` files. |
|
||||
| lint:hbs | Runs lint for `hbs` template files. |
|
||||
| lint:hbs:fix | Runs automatic lint fixes for `hbs` template files. |
|
||||
| format | Runs all auto-formatters. |
|
||||
| format:js | Auto-formats `js` files using Prettier. |
|
||||
| format:hbs | Auto-formats `hbs` files using Prettier. |
|
||||
| start | Runs the dummy app local server. |
|
||||
| test | Runs all tests. |
|
||||
| test:ember-compatibility | Runs tests across multiple Ember versions with ember-try. |
|
||||
| precommit | Runs all lint, format and tests. |
|
||||
| test:all | Runs tests across multiple Ember versions with ember-try. |
|
||||
| doc:toc | Automatically generates a table of contents for this README file. |
|
||||
|
||||
Additional commands in the monorepo package may affect this projects.
|
||||
@@ -158,7 +166,6 @@ Additional commands in the monorepo package may affect this projects.
|
||||
## Linting
|
||||
|
||||
* `yarn lint:hbs`
|
||||
* `yarn lint:hbs --fix`
|
||||
* `yarn lint:js`
|
||||
* `yarn lint:js --fix`
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
{{!-- //TODO fix the issue and delete disabling the rule --}}
|
||||
{{!-- template-lint-disable no-passed-in-event-handlers --}}
|
||||
{{#if @model.type}}
|
||||
{{component (concat "form/authenticate/" @model.type)
|
||||
submit=@submit
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
<span ...attributes class='image-container'>
|
||||
{{inline-svg @name}}
|
||||
</span>
|
||||
@@ -1,18 +0,0 @@
|
||||
<Rose::Button
|
||||
...attributes
|
||||
@style='inline-link-action'
|
||||
@iconLeft={{if
|
||||
this.isLoading
|
||||
'flight-icons/svg/loading-16'
|
||||
'flight-icons/svg/reload-16'
|
||||
}}
|
||||
class={{if
|
||||
this.isLoading
|
||||
'loading-button is-loading'
|
||||
'loading-button'
|
||||
}}
|
||||
@disabled={{this.isLoading}}
|
||||
{{on 'click' this.toggleRefresh}}
|
||||
>
|
||||
{{yield}}
|
||||
</Rose::Button>
|
||||
@@ -1,20 +0,0 @@
|
||||
import Component from '@glimmer/component';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import { action } from '@ember/object';
|
||||
import { later } from '@ember/runloop';
|
||||
|
||||
export default class LoadingButton extends Component {
|
||||
// =actions
|
||||
@tracked isLoading = false;
|
||||
|
||||
@action
|
||||
async toggleRefresh() {
|
||||
this.isLoading = true;
|
||||
try {
|
||||
await this.args.onClick();
|
||||
} catch (e) {
|
||||
console.error('Error while loading data', e);
|
||||
}
|
||||
later(() => (this.isLoading = false), 1000);
|
||||
}
|
||||
}
|
||||
Loaded 100 of 292 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user