Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ac7dfb677 | ||
|
|
683e939b0e |
No files matched your search
@@ -1,21 +0,0 @@
|
|||||||
schema_version = 1
|
|
||||||
|
|
||||||
project {
|
|
||||||
license = "BUSL-1.1"
|
|
||||||
copyright_year = 2021
|
|
||||||
|
|
||||||
# (OPTIONAL) A list of globs that should not have copyright/license headers.
|
|
||||||
# Supports doublestar glob patterns for more flexibility in defining which
|
|
||||||
# files or folders should be ignored
|
|
||||||
header_ignore = [
|
|
||||||
".husky/**",
|
|
||||||
"**/node_modules/**",
|
|
||||||
"**/dist/**",
|
|
||||||
"**/coverage/**",
|
|
||||||
"**/pnpm-lock.yaml",
|
|
||||||
"**/pnpm-workspace.yaml",
|
|
||||||
"ui/desktop/electron-app/out/**",
|
|
||||||
"ui/desktop/electron-app/ember-dist/**",
|
|
||||||
"e2e-tests/api-client/**"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
name: ci
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
tags-ignore: ["**"]
|
|
||||||
workflow_dispatch:
|
|
||||||
schedule:
|
|
||||||
- cron: "41 5 * * *" # nightly: dependency audit + full test run
|
|
||||||
|
|
||||||
# One job on purpose: the shared runner pool is small, so everything runs
|
|
||||||
# sequentially on a single runner instead of a matrix.
|
|
||||||
jobs:
|
|
||||||
check:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
timeout-minutes: 90
|
|
||||||
env:
|
|
||||||
CI: "true"
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: "22"
|
|
||||||
|
|
||||||
- name: install pnpm
|
|
||||||
run: |
|
|
||||||
npm install -g pnpm@10.33.3
|
|
||||||
pnpm --version
|
|
||||||
|
|
||||||
- name: install dependencies
|
|
||||||
# Lifecycle scripts are skipped: the desktop postinstall compiles
|
|
||||||
# electron-app native modules, which the admin build and ember tests
|
|
||||||
# do not need.
|
|
||||||
run: pnpm install --frozen-lockfile --ignore-scripts
|
|
||||||
|
|
||||||
- name: install headless chrome
|
|
||||||
# Debian/Ubuntu chromium from the distro archive (fast, mirrored),
|
|
||||||
# exposed under the name testem's "Chrome" launcher looks for.
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
if ! command -v google-chrome >/dev/null 2>&1; then
|
|
||||||
SUDO=""; [ "$(id -u)" -ne 0 ] && SUDO="sudo"
|
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
|
||||||
$SUDO apt-get update -qq
|
|
||||||
$SUDO apt-get install -y -qq --no-install-recommends chromium \
|
|
||||||
|| $SUDO apt-get install -y -qq --no-install-recommends chromium-browser
|
|
||||||
CHROME_BIN=$(command -v chromium || command -v chromium-browser)
|
|
||||||
mkdir -p "$HOME/bin"
|
|
||||||
ln -sf "$CHROME_BIN" "$HOME/bin/google-chrome"
|
|
||||||
echo "$HOME/bin" >> "$GITHUB_PATH"
|
|
||||||
fi
|
|
||||||
PATH="$HOME/bin:$PATH" google-chrome --version
|
|
||||||
|
|
||||||
- name: build admin ui
|
|
||||||
run: pnpm --filter admin build
|
|
||||||
|
|
||||||
- name: test addons
|
|
||||||
run: |
|
|
||||||
for a in core auth rose; do
|
|
||||||
echo "::group::addons/$a"
|
|
||||||
(cd addons/$a && npx ember test --test-port 0)
|
|
||||||
echo "::endgroup::"
|
|
||||||
done
|
|
||||||
echo "::group::addons/api"
|
|
||||||
(cd addons/api && npx ember exam --test-port 0 --split=4 --parallel=1)
|
|
||||||
echo "::endgroup::"
|
|
||||||
|
|
||||||
- name: test desktop ui
|
|
||||||
run: cd ui/desktop && npx ember test --test-port 0
|
|
||||||
|
|
||||||
- name: test admin ui
|
|
||||||
# The test build is made once and the partitions then run against the
|
|
||||||
# static output, one browser at a time. Rebuilding in-process (and four
|
|
||||||
# concurrent browsers) stalled on the small shared runners.
|
|
||||||
run: |
|
|
||||||
cd ui/admin
|
|
||||||
npx ember build --environment=test --output-path="$RUNNER_TEMP/admin-test-dist"
|
|
||||||
for p in 1 2 3 4; do
|
|
||||||
echo "::group::admin partition $p/4"
|
|
||||||
timeout 25m npx ember exam --test-port 0 --path "$RUNNER_TEMP/admin-test-dist" --split=4 --partition=$p
|
|
||||||
echo "::endgroup::"
|
|
||||||
done
|
|
||||||
|
|
||||||
- name: dependency audit
|
|
||||||
# Fails on critical advisories only; remaining high/moderate advisories
|
|
||||||
# are build/test tooling and are tracked in pnpm-overrides.md.
|
|
||||||
run: |
|
|
||||||
pnpm audit --audit-level=critical
|
|
||||||
(cd ui/desktop/electron-app && pnpm audit --audit-level=critical)
|
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Let us know about a bug!
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- Please reserve GitHub issues for bug reports and feature requests.
|
||||||
|
|
||||||
|
For questions, the best place to get answers is on our [discussion forum](https://discuss.hashicorp.com/c/boundary), as they will get more visibility from experienced users than the issue tracker.
|
||||||
|
|
||||||
|
Please note: We take Boundary's security and our users' trust very seriously. If you believe you have found a security issue in Boundary, please responsibly disclose by contacting us at security@hashicorp.com. Our PGP key is available at [our security page](https://www.hashicorp.com/security/).
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Run `boundary authenticate ...`
|
||||||
|
2. Run `boundary connect ...`
|
||||||
|
3. See error
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
contact_links:
|
||||||
|
- name: Ask a question
|
||||||
|
url: https://discuss.hashicorp.com/c/boundary
|
||||||
|
about: For increased visibility, please post questions on the discussion forum.
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest something!
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Explain any additional use-cases**
|
||||||
|
If there are any use-cases that would help us understand the use/need/value please share them as they can help us decide on acceptance and prioritization.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
addons:
|
||||||
|
- addons/**/*
|
||||||
|
|
||||||
|
api-addon:
|
||||||
|
- addons/api/**/*
|
||||||
|
|
||||||
|
auth-addon:
|
||||||
|
- addons/auth/**/*
|
||||||
|
|
||||||
|
styles-addon:
|
||||||
|
- addons/rose/**/*
|
||||||
|
|
||||||
|
ui:
|
||||||
|
- ui/**/*
|
||||||
|
|
||||||
|
admin:
|
||||||
|
- ui/admin/**/*
|
||||||
|
|
||||||
|
desktop:
|
||||||
|
- ui/desktop/**/*
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
# For most projects, this workflow file will not need changing; you simply need
|
||||||
|
# to commit it to your repository.
|
||||||
|
#
|
||||||
|
# You may wish to alter this file to override the set of languages analyzed,
|
||||||
|
# or to provide custom queries or build logic.
|
||||||
|
name: "CodeQL"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main, release-v0.1.0]
|
||||||
|
pull_request:
|
||||||
|
# The branches below must be a subset of the branches above
|
||||||
|
branches: [main]
|
||||||
|
schedule:
|
||||||
|
- cron: '0 19 * * 4'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Analyze
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
# Override automatic language detection by changing the below list
|
||||||
|
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
|
||||||
|
language: ['javascript']
|
||||||
|
# Learn more...
|
||||||
|
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
# We must fetch at least the immediate parents so that if this is
|
||||||
|
# a pull request then we can checkout the head.
|
||||||
|
fetch-depth: 2
|
||||||
|
|
||||||
|
# If this run was triggered by a pull request event, then checkout
|
||||||
|
# the head of the pull request instead of the merge commit.
|
||||||
|
- run: git checkout HEAD^2
|
||||||
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
|
|
||||||
|
# Initializes the CodeQL tools for scanning.
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v1
|
||||||
|
with:
|
||||||
|
languages: ${{ matrix.language }}
|
||||||
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
|
# By default, queries listed here will override any specified in a config file.
|
||||||
|
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||||
|
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||||
|
|
||||||
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
|
- name: Autobuild
|
||||||
|
uses: github/codeql-action/autobuild@v1
|
||||||
|
|
||||||
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
|
# 📚 https://git.io/JvXDl
|
||||||
|
|
||||||
|
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||||
|
# and modify them (or add more) to build your code if your project
|
||||||
|
# uses a compiled language
|
||||||
|
|
||||||
|
#- run: |
|
||||||
|
# make bootstrap
|
||||||
|
# make release
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v1
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types: [opened, closed, deleted, reopened]
|
||||||
|
pull_request_target:
|
||||||
|
types: [opened, closed, reopened]
|
||||||
|
issue_comment: # Also triggers when commenting on a PR from the conversation view
|
||||||
|
types: [created]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
name: Jira Sync
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
sync:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Jira sync
|
||||||
|
steps:
|
||||||
|
- name: Check if community user
|
||||||
|
if: github.event.action == 'opened'
|
||||||
|
id: boundary-team-role
|
||||||
|
run: |
|
||||||
|
TEAM=boundary
|
||||||
|
ROLE="$(hub api orgs/hashicorp/teams/${TEAM}/memberships/${{ github.actor }} | jq -r '.role | select(.!=null)')"
|
||||||
|
if [[ -n ${ROLE} ]]; then
|
||||||
|
echo "Actor ${{ github.actor }} is a ${TEAM} team member, skipping ticket creation"
|
||||||
|
else
|
||||||
|
echo "Actor ${{ github.actor }} is not a ${TEAM} team member"
|
||||||
|
fi
|
||||||
|
echo "::set-output name=role::${ROLE}"
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.JIRA_SYNC_GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Login
|
||||||
|
uses: atlassian/gajira-login@v2.0.0
|
||||||
|
env:
|
||||||
|
JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }}
|
||||||
|
JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }}
|
||||||
|
JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
|
||||||
|
|
||||||
|
- name: Set ticket type
|
||||||
|
if: github.event.action == 'opened' && !steps.boundary-team-role.outputs.role
|
||||||
|
id: set-ticket-type
|
||||||
|
run: |
|
||||||
|
if [[ "${{ github.event_name }}" == "pull_request_target" ]]; then
|
||||||
|
echo "::set-output name=type::PR"
|
||||||
|
else
|
||||||
|
echo "::set-output name=type::ISS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Create ticket
|
||||||
|
if: github.event.action == 'opened' && !steps.boundary-team-role.outputs.role
|
||||||
|
uses: tomhjp/gh-action-jira-create@v0.1.0
|
||||||
|
with:
|
||||||
|
project: ICU
|
||||||
|
issuetype: "GH Issue"
|
||||||
|
summary: "${{ github.event.repository.name }} [${{ steps.set-ticket-type.outputs.type }} #${{ github.event.issue.number || github.event.pull_request.number }}]: ${{ github.event.issue.title || github.event.pull_request.title }}"
|
||||||
|
description: "${{ github.event.issue.body || github.event.pull_request.body }}\n\n_Created from GitHub Action for ${{ github.event.issue.html_url || github.event.pull_request.html_url }}, from ${{ github.actor }}_"
|
||||||
|
# customfield_10089 is Issue Link custom field
|
||||||
|
# customfield_10091 is team custom field
|
||||||
|
extraFields: '{"customfield_10089": "${{ github.event.issue.html_url || github.event.pull_request.html_url }}"}'
|
||||||
|
|
||||||
|
- name: Search
|
||||||
|
if: github.event.action != 'opened'
|
||||||
|
id: search
|
||||||
|
uses: tomhjp/gh-action-jira-search@v0.2.1
|
||||||
|
with:
|
||||||
|
# cf[10089] is Issue Link custom field
|
||||||
|
jql: 'issuetype = "GH Issue" and cf[10089]="${{ github.event.issue.html_url || github.event.pull_request.html_url }}"'
|
||||||
|
|
||||||
|
- name: Sync comment
|
||||||
|
if: github.event.action == 'created' && steps.search.outputs.issue
|
||||||
|
uses: atlassian/gajira-comment@v2.0.2
|
||||||
|
with:
|
||||||
|
issue: ${{ steps.search.outputs.issue }}
|
||||||
|
comment: "${{ github.actor }} ${{ github.event.review.state || 'commented' }}:\n\n${{ github.event.comment.body || github.event.review.body }}\n\n${{ github.event.comment.html_url || github.event.review.html_url }}"
|
||||||
|
|
||||||
|
- name: Close ticket
|
||||||
|
if: (github.event.action == 'closed' || github.event.action == 'deleted') && steps.search.outputs.issue
|
||||||
|
uses: atlassian/gajira-transition@v2.0.1
|
||||||
|
with:
|
||||||
|
issue: ${{ steps.search.outputs.issue }}
|
||||||
|
transition: Done
|
||||||
|
|
||||||
|
- name: Reopen ticket
|
||||||
|
if: github.event.action == 'reopened' && steps.search.outputs.issue
|
||||||
|
uses: atlassian/gajira-transition@v2.0.1
|
||||||
|
with:
|
||||||
|
issue: ${{ steps.search.outputs.issue }}
|
||||||
|
transition: "To Do"
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
name: "Pull Request Labeler"
|
||||||
|
on:
|
||||||
|
- pull_request_target
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
triage:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/labeler@main
|
||||||
|
with:
|
||||||
|
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
name: Validate Monorepo
|
||||||
|
on: pull_request
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
name: Install dependencies
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- 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@v2
|
||||||
|
with:
|
||||||
|
node-version: '16.x'
|
||||||
|
- run: yarn install
|
||||||
|
|
||||||
|
compliance:
|
||||||
|
name: License Compliance
|
||||||
|
needs: [dependencies]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- 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@v2
|
||||||
|
with:
|
||||||
|
node-version: '16.x'
|
||||||
|
if: steps.node-modules-cache.outputs.cache-hit != 'true'
|
||||||
|
- run: yarn run compliance:licenses
|
||||||
|
|
||||||
|
lint:
|
||||||
|
name: Lint
|
||||||
|
needs: [dependencies]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 5
|
||||||
|
steps:
|
||||||
|
- 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@v2
|
||||||
|
with:
|
||||||
|
node-version: '16.x'
|
||||||
|
if: steps.node-modules-cache.outputs.cache-hit != 'true'
|
||||||
|
- run: yarn lint
|
||||||
|
|
||||||
|
test:
|
||||||
|
name: Test
|
||||||
|
needs: [dependencies]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 15
|
||||||
|
steps:
|
||||||
|
- 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@v2
|
||||||
|
with:
|
||||||
|
node-version: '16.x'
|
||||||
|
if: steps.node-modules-cache.outputs.cache-hit != 'true'
|
||||||
|
- run: yarn test
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
name: "Trigger Test Boundary UI release"
|
||||||
|
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
branch:
|
||||||
|
description: Please use tag-like format n.n.n-someword (1.111.11-beta)
|
||||||
|
required: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
trigger-circleci-release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: Trigger Release job
|
||||||
|
if: github.event_name == 'workflow_dispatch'
|
||||||
|
run: |
|
||||||
|
echo "Triggering Test release using BRANCH and TEST_TAG ${{ github.event.inputs.branch }}"
|
||||||
|
|
||||||
|
curl -u ${{ secrets.CIRCLE_TOKEN }}: -X POST --header "Content-Type: application/json" \
|
||||||
|
-d '{ "branch": "main", "parameters": {"TAG": "'${{ github.event.inputs.branch }}'" }}' \
|
||||||
|
https://circleci.com/api/v2/project/github/hashicorp/boundary-ui-releases/pipeline
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
name: "Trigger Boundary UI release"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
trigger-circleci-release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Trigger Release job
|
||||||
|
run: |
|
||||||
|
echo "Triggering release with a TAG ${GITHUB_REF#refs/tags/}"
|
||||||
|
|
||||||
|
curl -u ${{ secrets.CIRCLE_TOKEN }}: -X POST --header "Content-Type: application/json" \
|
||||||
|
-d '{ "branch": "main", "parameters": {"TAG": "'${GITHUB_REF#refs/tags/}'" }}' \
|
||||||
|
https://circleci.com/api/v2/project/github/hashicorp/boundary-ui-releases/pipeline
|
||||||
+3
-19
@@ -19,23 +19,7 @@ coverage-*
|
|||||||
libpeerconnection.log
|
libpeerconnection.log
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
testem.log
|
testem.log
|
||||||
|
yarn-error.log
|
||||||
|
storybook-static
|
||||||
|
**/.storybook/*.html
|
||||||
.watchman-cookie*
|
.watchman-cookie*
|
||||||
|
|
||||||
### VisualStudioCode ###
|
|
||||||
.vscode/*
|
|
||||||
!.vscode/settings.json
|
|
||||||
!.vscode/tasks.json
|
|
||||||
!.vscode/launch.json
|
|
||||||
!.vscode/extensions.json
|
|
||||||
!.vscode/*.code-snippets
|
|
||||||
|
|
||||||
# Local History for Visual Studio Code
|
|
||||||
.history/
|
|
||||||
|
|
||||||
# Built Visual Studio Code Extensions
|
|
||||||
*.vsix
|
|
||||||
|
|
||||||
### VisualStudioCode Patch ###
|
|
||||||
# Ignore all local history of files
|
|
||||||
.history
|
|
||||||
.ionide
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
pnpm compliance:licenses
|
|
||||||
pnpm lint-staged
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
COMMIT_MSG_FILE=$1
|
|
||||||
COMMIT_SOURCE=$2
|
|
||||||
SHA1=$3
|
|
||||||
# Gets the current branch name but if we're in a detached head state, return "HEAD"
|
|
||||||
BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD)
|
|
||||||
# Regex to match the ICU-#### branch name pattern we use
|
|
||||||
ISSUE_REGEX="^(ICU-[0-9]+)"
|
|
||||||
|
|
||||||
# Don't run commitizen for merge or squash commits, as well as when rebasing
|
|
||||||
if [ "${COMMIT_SOURCE}" = merge ] || [ "${COMMIT_SOURCE}" = squash ] || [ "${COMMIT_SOURCE}" = "message" -a "${BRANCH_NAME}" = "HEAD" ];then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If the branch name matches, set the JIRA link automatically
|
|
||||||
if [[ $BRANCH_NAME =~ $ISSUE_REGEX ]]
|
|
||||||
then
|
|
||||||
issue="${BASH_REMATCH[1]}"
|
|
||||||
url="https://hashicorp.atlassian.net/browse/${issue}"
|
|
||||||
exec < /dev/tty && npx git-cz --issues="$url" --hook || true
|
|
||||||
else
|
|
||||||
# This is to allow interaction with the terminal for commitizen
|
|
||||||
exec < /dev/tty && npx git-cz --hook || true
|
|
||||||
fi
|
|
||||||
@@ -1,91 +1,362 @@
|
|||||||
License text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.
|
Mozilla Public License, version 2.0
|
||||||
"Business Source License" is a trademark of MariaDB Corporation Ab.
|
|
||||||
|
|
||||||
Parameters
|
1. Definitions
|
||||||
|
|
||||||
Licensor: International Business Machines Corporation (IBM)
|
1.1. "Contributor"
|
||||||
Licensed Work: The Licensed Work is (c) 2024 IBM Corp.
|
|
||||||
Additional Use Grant: You may make production use of the Licensed Work, provided
|
|
||||||
Your use does not include offering the Licensed Work to third
|
|
||||||
parties on a hosted or embedded basis in order to compete with
|
|
||||||
IBM Corp's paid version(s) of the Licensed Work. For purposes
|
|
||||||
of this license:
|
|
||||||
|
|
||||||
A "competitive offering" is a Product that is offered to third
|
means each individual or legal entity that creates, contributes to the
|
||||||
parties on a paid basis, including through paid support
|
creation of, or owns Covered Software.
|
||||||
arrangements, that significantly overlaps with the capabilities
|
|
||||||
of IBM Corp's paid version(s) of the Licensed Work. If Your
|
|
||||||
Product is not a competitive offering when You first make it
|
|
||||||
generally available, it will not become a competitive offering
|
|
||||||
later due to IBM Corp releasing a new version of the Licensed
|
|
||||||
Work with additional capabilities. In addition, Products that
|
|
||||||
are not provided on a paid basis are not competitive.
|
|
||||||
|
|
||||||
"Product" means software that is offered to end users to manage
|
1.2. "Contributor Version"
|
||||||
in their own environments or offered as a service on a hosted
|
|
||||||
basis.
|
|
||||||
|
|
||||||
"Embedded" means including the source code or executable code
|
means the combination of the Contributions of others (if any) used by a
|
||||||
from the Licensed Work in a competitive offering. "Embedded"
|
Contributor and that particular Contributor's Contribution.
|
||||||
also means packaging the competitive offering in such a way
|
|
||||||
that the Licensed Work must be accessed or downloaded for the
|
|
||||||
competitive offering to operate.
|
|
||||||
|
|
||||||
Hosting or using the Licensed Work(s) for internal purposes
|
1.3. "Contribution"
|
||||||
within an organization is not considered a competitive
|
|
||||||
offering. IBM Corp considers your organization to include all
|
|
||||||
of your affiliates under common control.
|
|
||||||
|
|
||||||
For binding interpretive guidance on using IBM Corp products
|
means Covered Software of a particular Contributor.
|
||||||
under the Business Source License, please visit our FAQ.
|
|
||||||
(https://www.hashicorp.com/license-faq)
|
|
||||||
Change Date: Four years from the date the Licensed Work is published.
|
|
||||||
Change License: MPL 2.0
|
|
||||||
|
|
||||||
For information about alternative licensing arrangements for the Licensed Work,
|
1.4. "Covered Software"
|
||||||
please contact licensing@hashicorp.com.
|
|
||||||
|
|
||||||
Notice
|
means Source Code Form to which the initial Contributor has attached the
|
||||||
|
notice in Exhibit A, the Executable Form of such Source Code Form, and
|
||||||
|
Modifications of such Source Code Form, in each case including portions
|
||||||
|
thereof.
|
||||||
|
|
||||||
Business Source License 1.1
|
1.5. "Incompatible With Secondary Licenses"
|
||||||
|
means
|
||||||
|
|
||||||
Terms
|
a. that the initial Contributor has attached the notice described in
|
||||||
|
Exhibit B to the Covered Software; or
|
||||||
|
|
||||||
The Licensor hereby grants you the right to copy, modify, create derivative
|
b. that the Covered Software was made available under the terms of
|
||||||
works, redistribute, and make non-production use of the Licensed Work. The
|
version 1.1 or earlier of the License, but not also under the terms of
|
||||||
Licensor may make an Additional Use Grant, above, permitting limited production use.
|
a Secondary License.
|
||||||
|
|
||||||
Effective on the Change Date, or the fourth anniversary of the first publicly
|
1.6. "Executable Form"
|
||||||
available distribution of a specific version of the Licensed Work under this
|
|
||||||
License, whichever comes first, the Licensor hereby grants you rights under
|
|
||||||
the terms of the Change License, and the rights granted in the paragraph
|
|
||||||
above terminate.
|
|
||||||
|
|
||||||
If your use of the Licensed Work does not comply with the requirements
|
means any form of the work other than Source Code Form.
|
||||||
currently in effect as described in this License, you must purchase a
|
|
||||||
commercial license from the Licensor, its affiliated entities, or authorized
|
|
||||||
resellers, or you must refrain from using the Licensed Work.
|
|
||||||
|
|
||||||
All copies of the original and modified Licensed Work, and derivative works
|
1.7. "Larger Work"
|
||||||
of the Licensed Work, are subject to this License. This License applies
|
|
||||||
separately for each version of the Licensed Work and the Change Date may vary
|
|
||||||
for each version of the Licensed Work released by Licensor.
|
|
||||||
|
|
||||||
You must conspicuously display this License on each original or modified copy
|
means a work that combines Covered Software with other material, in a
|
||||||
of the Licensed Work. If you receive the Licensed Work in original or
|
separate file or files, that is not Covered Software.
|
||||||
modified form from a third party, the terms and conditions set forth in this
|
|
||||||
License apply to your use of that work.
|
|
||||||
|
|
||||||
Any use of the Licensed Work in violation of this License will automatically
|
1.8. "License"
|
||||||
terminate your rights under this License for the current and all other
|
|
||||||
versions of the Licensed Work.
|
|
||||||
|
|
||||||
This License does not grant you any right in any trademark or logo of
|
means this document.
|
||||||
Licensor or its affiliates (provided that you may use a trademark or logo of
|
|
||||||
Licensor as expressly required by this License).
|
|
||||||
|
|
||||||
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
|
1.9. "Licensable"
|
||||||
AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
|
means having the right to grant, to the maximum extent possible, whether
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
|
at the time of the initial grant or subsequently, any and all of the
|
||||||
TITLE.
|
rights conveyed by this License.
|
||||||
|
|
||||||
|
1.10. "Modifications"
|
||||||
|
|
||||||
|
means any of the following:
|
||||||
|
|
||||||
|
a. any file in Source Code Form that results from an addition to,
|
||||||
|
deletion from, or modification of the contents of Covered Software; or
|
||||||
|
|
||||||
|
b. any new file in Source Code Form that contains any Covered Software.
|
||||||
|
|
||||||
|
1.11. "Patent Claims" of a Contributor
|
||||||
|
|
||||||
|
means any patent claim(s), including without limitation, method,
|
||||||
|
process, and apparatus claims, in any patent Licensable by such
|
||||||
|
Contributor that would be infringed, but for the grant of the License,
|
||||||
|
by the making, using, selling, offering for sale, having made, import,
|
||||||
|
or transfer of either its Contributions or its Contributor Version.
|
||||||
|
|
||||||
|
1.12. "Secondary License"
|
||||||
|
|
||||||
|
means either the GNU General Public License, Version 2.0, the GNU Lesser
|
||||||
|
General Public License, Version 2.1, the GNU Affero General Public
|
||||||
|
License, Version 3.0, or any later versions of those licenses.
|
||||||
|
|
||||||
|
1.13. "Source Code Form"
|
||||||
|
|
||||||
|
means the form of the work preferred for making modifications.
|
||||||
|
|
||||||
|
1.14. "You" (or "Your")
|
||||||
|
|
||||||
|
means an individual or a legal entity exercising rights under this
|
||||||
|
License. For legal entities, "You" includes any entity that controls, is
|
||||||
|
controlled by, or is under common control with You. For purposes of this
|
||||||
|
definition, "control" means (a) the power, direct or indirect, to cause
|
||||||
|
the direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (b) ownership of more than fifty percent (50%) of the
|
||||||
|
outstanding shares or beneficial ownership of such entity.
|
||||||
|
|
||||||
|
|
||||||
|
2. License Grants and Conditions
|
||||||
|
|
||||||
|
2.1. Grants
|
||||||
|
|
||||||
|
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||||
|
non-exclusive license:
|
||||||
|
|
||||||
|
a. under intellectual property rights (other than patent or trademark)
|
||||||
|
Licensable by such Contributor to use, reproduce, make available,
|
||||||
|
modify, display, perform, distribute, and otherwise exploit its
|
||||||
|
Contributions, either on an unmodified basis, with Modifications, or
|
||||||
|
as part of a Larger Work; and
|
||||||
|
|
||||||
|
b. under Patent Claims of such Contributor to make, use, sell, offer for
|
||||||
|
sale, have made, import, and otherwise transfer either its
|
||||||
|
Contributions or its Contributor Version.
|
||||||
|
|
||||||
|
2.2. Effective Date
|
||||||
|
|
||||||
|
The licenses granted in Section 2.1 with respect to any Contribution
|
||||||
|
become effective for each Contribution on the date the Contributor first
|
||||||
|
distributes such Contribution.
|
||||||
|
|
||||||
|
2.3. Limitations on Grant Scope
|
||||||
|
|
||||||
|
The licenses granted in this Section 2 are the only rights granted under
|
||||||
|
this License. No additional rights or licenses will be implied from the
|
||||||
|
distribution or licensing of Covered Software under this License.
|
||||||
|
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||||
|
Contributor:
|
||||||
|
|
||||||
|
a. for any code that a Contributor has removed from Covered Software; or
|
||||||
|
|
||||||
|
b. for infringements caused by: (i) Your and any other third party's
|
||||||
|
modifications of Covered Software, or (ii) the combination of its
|
||||||
|
Contributions with other software (except as part of its Contributor
|
||||||
|
Version); or
|
||||||
|
|
||||||
|
c. under Patent Claims infringed by Covered Software in the absence of
|
||||||
|
its Contributions.
|
||||||
|
|
||||||
|
This License does not grant any rights in the trademarks, service marks,
|
||||||
|
or logos of any Contributor (except as may be necessary to comply with
|
||||||
|
the notice requirements in Section 3.4).
|
||||||
|
|
||||||
|
2.4. Subsequent Licenses
|
||||||
|
|
||||||
|
No Contributor makes additional grants as a result of Your choice to
|
||||||
|
distribute the Covered Software under a subsequent version of this
|
||||||
|
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||||
|
permitted under the terms of Section 3.3).
|
||||||
|
|
||||||
|
2.5. Representation
|
||||||
|
|
||||||
|
Each Contributor represents that the Contributor believes its
|
||||||
|
Contributions are its original creation(s) or it has sufficient rights to
|
||||||
|
grant the rights to its Contributions conveyed by this License.
|
||||||
|
|
||||||
|
2.6. Fair Use
|
||||||
|
|
||||||
|
This License is not intended to limit any rights You have under
|
||||||
|
applicable copyright doctrines of fair use, fair dealing, or other
|
||||||
|
equivalents.
|
||||||
|
|
||||||
|
2.7. Conditions
|
||||||
|
|
||||||
|
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
|
||||||
|
Section 2.1.
|
||||||
|
|
||||||
|
|
||||||
|
3. Responsibilities
|
||||||
|
|
||||||
|
3.1. Distribution of Source Form
|
||||||
|
|
||||||
|
All distribution of Covered Software in Source Code Form, including any
|
||||||
|
Modifications that You create or to which You contribute, must be under
|
||||||
|
the terms of this License. You must inform recipients that the Source
|
||||||
|
Code Form of the Covered Software is governed by the terms of this
|
||||||
|
License, and how they can obtain a copy of this License. You may not
|
||||||
|
attempt to alter or restrict the recipients' rights in the Source Code
|
||||||
|
Form.
|
||||||
|
|
||||||
|
3.2. Distribution of Executable Form
|
||||||
|
|
||||||
|
If You distribute Covered Software in Executable Form then:
|
||||||
|
|
||||||
|
a. such Covered Software must also be made available in Source Code Form,
|
||||||
|
as described in Section 3.1, and You must inform recipients of the
|
||||||
|
Executable Form how they can obtain a copy of such Source Code Form by
|
||||||
|
reasonable means in a timely manner, at a charge no more than the cost
|
||||||
|
of distribution to the recipient; and
|
||||||
|
|
||||||
|
b. You may distribute such Executable Form under the terms of this
|
||||||
|
License, or sublicense it under different terms, provided that the
|
||||||
|
license for the Executable Form does not attempt to limit or alter the
|
||||||
|
recipients' rights in the Source Code Form under this License.
|
||||||
|
|
||||||
|
3.3. Distribution of a Larger Work
|
||||||
|
|
||||||
|
You may create and distribute a Larger Work under terms of Your choice,
|
||||||
|
provided that You also comply with the requirements of this License for
|
||||||
|
the Covered Software. If the Larger Work is a combination of Covered
|
||||||
|
Software with a work governed by one or more Secondary Licenses, and the
|
||||||
|
Covered Software is not Incompatible With Secondary Licenses, this
|
||||||
|
License permits You to additionally distribute such Covered Software
|
||||||
|
under the terms of such Secondary License(s), so that the recipient of
|
||||||
|
the Larger Work may, at their option, further distribute the Covered
|
||||||
|
Software under the terms of either this License or such Secondary
|
||||||
|
License(s).
|
||||||
|
|
||||||
|
3.4. Notices
|
||||||
|
|
||||||
|
You may not remove or alter the substance of any license notices
|
||||||
|
(including copyright notices, patent notices, disclaimers of warranty, or
|
||||||
|
limitations of liability) contained within the Source Code Form of the
|
||||||
|
Covered Software, except that You may alter any license notices to the
|
||||||
|
extent required to remedy known factual inaccuracies.
|
||||||
|
|
||||||
|
3.5. Application of Additional Terms
|
||||||
|
|
||||||
|
You may choose to offer, and to charge a fee for, warranty, support,
|
||||||
|
indemnity or liability obligations to one or more recipients of Covered
|
||||||
|
Software. However, You may do so only on Your own behalf, and not on
|
||||||
|
behalf of any Contributor. You must make it absolutely clear that any
|
||||||
|
such warranty, support, indemnity, or liability obligation is offered by
|
||||||
|
You alone, and You hereby agree to indemnify every Contributor for any
|
||||||
|
liability incurred by such Contributor as a result of warranty, support,
|
||||||
|
indemnity or liability terms You offer. You may include additional
|
||||||
|
disclaimers of warranty and limitations of liability specific to any
|
||||||
|
jurisdiction.
|
||||||
|
|
||||||
|
4. Inability to Comply Due to Statute or Regulation
|
||||||
|
|
||||||
|
If it is impossible for You to comply with any of the terms of this License
|
||||||
|
with respect to some or all of the Covered Software due to statute,
|
||||||
|
judicial order, or regulation then You must: (a) comply with the terms of
|
||||||
|
this License to the maximum extent possible; and (b) describe the
|
||||||
|
limitations and the code they affect. Such description must be placed in a
|
||||||
|
text file included with all distributions of the Covered Software under
|
||||||
|
this License. Except to the extent prohibited by statute or regulation,
|
||||||
|
such description must be sufficiently detailed for a recipient of ordinary
|
||||||
|
skill to be able to understand it.
|
||||||
|
|
||||||
|
5. Termination
|
||||||
|
|
||||||
|
5.1. The rights granted under this License will terminate automatically if You
|
||||||
|
fail to comply with any of its terms. However, if You become compliant,
|
||||||
|
then the rights granted under this License from a particular Contributor
|
||||||
|
are reinstated (a) provisionally, unless and until such Contributor
|
||||||
|
explicitly and finally terminates Your grants, and (b) on an ongoing
|
||||||
|
basis, if such Contributor fails to notify You of the non-compliance by
|
||||||
|
some reasonable means prior to 60 days after You have come back into
|
||||||
|
compliance. Moreover, Your grants from a particular Contributor are
|
||||||
|
reinstated on an ongoing basis if such Contributor notifies You of the
|
||||||
|
non-compliance by some reasonable means, this is the first time You have
|
||||||
|
received notice of non-compliance with this License from such
|
||||||
|
Contributor, and You become compliant prior to 30 days after Your receipt
|
||||||
|
of the notice.
|
||||||
|
|
||||||
|
5.2. If You initiate litigation against any entity by asserting a patent
|
||||||
|
infringement claim (excluding declaratory judgment actions,
|
||||||
|
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||||
|
directly or indirectly infringes any patent, then the rights granted to
|
||||||
|
You by any and all Contributors for the Covered Software under Section
|
||||||
|
2.1 of this License shall terminate.
|
||||||
|
|
||||||
|
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
|
||||||
|
license agreements (excluding distributors and resellers) which have been
|
||||||
|
validly granted by You or Your distributors under this License prior to
|
||||||
|
termination shall survive termination.
|
||||||
|
|
||||||
|
6. Disclaimer of Warranty
|
||||||
|
|
||||||
|
Covered Software is provided under this License on an "as is" basis,
|
||||||
|
without warranty of any kind, either expressed, implied, or statutory,
|
||||||
|
including, without limitation, warranties that the Covered Software is free
|
||||||
|
of defects, merchantable, fit for a particular purpose or non-infringing.
|
||||||
|
The entire risk as to the quality and performance of the Covered Software
|
||||||
|
is with You. Should any Covered Software prove defective in any respect,
|
||||||
|
You (not any Contributor) assume the cost of any necessary servicing,
|
||||||
|
repair, or correction. This disclaimer of warranty constitutes an essential
|
||||||
|
part of this License. No use of any Covered Software is authorized under
|
||||||
|
this License except under this disclaimer.
|
||||||
|
|
||||||
|
7. Limitation of Liability
|
||||||
|
|
||||||
|
Under no circumstances and under no legal theory, whether tort (including
|
||||||
|
negligence), contract, or otherwise, shall any Contributor, or anyone who
|
||||||
|
distributes Covered Software as permitted above, be liable to You for any
|
||||||
|
direct, indirect, special, incidental, or consequential damages of any
|
||||||
|
character including, without limitation, damages for lost profits, loss of
|
||||||
|
goodwill, work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses, even if such party shall have been
|
||||||
|
informed of the possibility of such damages. This limitation of liability
|
||||||
|
shall not apply to liability for death or personal injury resulting from
|
||||||
|
such party's negligence to the extent applicable law prohibits such
|
||||||
|
limitation. Some jurisdictions do not allow the exclusion or limitation of
|
||||||
|
incidental or consequential damages, so this exclusion and limitation may
|
||||||
|
not apply to You.
|
||||||
|
|
||||||
|
8. Litigation
|
||||||
|
|
||||||
|
Any litigation relating to this License may be brought only in the courts
|
||||||
|
of a jurisdiction where the defendant maintains its principal place of
|
||||||
|
business and such litigation shall be governed by laws of that
|
||||||
|
jurisdiction, without reference to its conflict-of-law provisions. Nothing
|
||||||
|
in this Section shall prevent a party's ability to bring cross-claims or
|
||||||
|
counter-claims.
|
||||||
|
|
||||||
|
9. Miscellaneous
|
||||||
|
|
||||||
|
This License represents the complete agreement concerning the subject
|
||||||
|
matter hereof. If any provision of this License is held to be
|
||||||
|
unenforceable, such provision shall be reformed only to the extent
|
||||||
|
necessary to make it enforceable. Any law or regulation which provides that
|
||||||
|
the language of a contract shall be construed against the drafter shall not
|
||||||
|
be used to construe this License against a Contributor.
|
||||||
|
|
||||||
|
|
||||||
|
10. Versions of the License
|
||||||
|
|
||||||
|
10.1. New Versions
|
||||||
|
|
||||||
|
Mozilla Foundation is the license steward. Except as provided in Section
|
||||||
|
10.3, no one other than the license steward has the right to modify or
|
||||||
|
publish new versions of this License. Each version will be given a
|
||||||
|
distinguishing version number.
|
||||||
|
|
||||||
|
10.2. Effect of New Versions
|
||||||
|
|
||||||
|
You may distribute the Covered Software under the terms of the version
|
||||||
|
of the License under which You originally received the Covered Software,
|
||||||
|
or under the terms of any subsequent version published by the license
|
||||||
|
steward.
|
||||||
|
|
||||||
|
10.3. Modified Versions
|
||||||
|
|
||||||
|
If you create software not governed by this License, and you want to
|
||||||
|
create a new license for such software, you may create and use a
|
||||||
|
modified version of this License if you rename the license and remove
|
||||||
|
any references to the name of the license steward (except to note that
|
||||||
|
such modified license differs from this License).
|
||||||
|
|
||||||
|
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||||
|
Licenses If You choose to distribute Source Code Form that is
|
||||||
|
Incompatible With Secondary Licenses under the terms of this version of
|
||||||
|
the License, the notice described in Exhibit B of this License must be
|
||||||
|
attached.
|
||||||
|
|
||||||
|
Exhibit A - Source Code Form License Notice
|
||||||
|
|
||||||
|
This Source Code Form is subject to the
|
||||||
|
terms of the Mozilla Public License, v.
|
||||||
|
2.0. If a copy of the MPL was not
|
||||||
|
distributed with this file, You can
|
||||||
|
obtain one at
|
||||||
|
http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
If it is not possible or desirable to put the notice in a particular file,
|
||||||
|
then You may include the notice in a location (such as a LICENSE file in a
|
||||||
|
relevant directory) where a recipient would be likely to look for such a
|
||||||
|
notice.
|
||||||
|
|
||||||
|
You may add additional accurate notices of copyright ownership.
|
||||||
|
|
||||||
|
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||||
|
|
||||||
|
This Source Code Form is "Incompatible
|
||||||
|
With Secondary Licenses", as defined by
|
||||||
|
the Mozilla Public License, v. 2.0.
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
Threshold UI
|
|
||||||
Copyright (c) 2026 CyberCove LLC
|
|
||||||
|
|
||||||
This repository is a community fork of "Boundary UI"
|
|
||||||
(https://github.com/hashicorp/boundary-ui), the admin web UI and desktop
|
|
||||||
client for HashiCorp Boundary.
|
|
||||||
|
|
||||||
Upstream work: Copyright (c) HashiCorp, Inc. 2020-2023;
|
|
||||||
Copyright (c) IBM Corp. 2024-2026
|
|
||||||
Upstream license: Business Source License 1.1 (see LICENSE)
|
|
||||||
|
|
||||||
The upstream LICENSE and per-file copyright / SPDX headers are retained
|
|
||||||
unchanged. Modifications made in this fork are provided under the same
|
|
||||||
license terms (BUSL-1.1), including its Additional Use Grant and Change
|
|
||||||
Date as stated in LICENSE.
|
|
||||||
|
|
||||||
This project is an independent community effort. It is NOT affiliated with,
|
|
||||||
endorsed by, or sponsored by HashiCorp, Inc. or IBM Corp. "HashiCorp",
|
|
||||||
"Boundary", and related marks and logos are trademarks of their respective
|
|
||||||
owners; they are used here only to describe the upstream origin of this work
|
|
||||||
and to name the upstream CLI/API this software interoperates with. The
|
|
||||||
upstream logos and brand art have been removed and replaced with plain
|
|
||||||
placeholder marks.
|
|
||||||
|
|
||||||
Third-party components keep their own licenses (see pnpm-lock.yaml and the
|
|
||||||
`pnpm compliance:licenses` script). The HashiCorp Design System packages
|
|
||||||
(@hashicorp/design-system-components, -tokens, @hashicorp/flight-icons) are
|
|
||||||
consumed unmodified from the public npm registry under their own licenses.
|
|
||||||
@@ -1,41 +1,10 @@
|
|||||||
# Threshold UI Monorepo
|
# Boundary UI Monorepo
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
This monorepo contains multiple projects, including UIs and addons, used by
|
This monorepo contains multiple projects, including UIs and addons, used by
|
||||||
Threshold (the admin web UI and the desktop client).
|
Boundary.
|
||||||
|
|
||||||
## About this fork
|
|
||||||
|
|
||||||
This repository is a community fork of
|
|
||||||
[hashicorp/boundary-ui](https://github.com/hashicorp/boundary-ui), rebranded
|
|
||||||
for the Threshold project (a community fork of Boundary CE). It is licensed
|
|
||||||
under the upstream Business Source License 1.1 (see [LICENSE](LICENSE) and
|
|
||||||
[NOTICE](NOTICE)) and is **not affiliated with, endorsed by, or sponsored by
|
|
||||||
HashiCorp or IBM**.
|
|
||||||
|
|
||||||
What changed relative to upstream:
|
|
||||||
|
|
||||||
- User-visible product name is Threshold (window titles, menus, about dialog,
|
|
||||||
installer/package names, app id `net.anhonesthost.cybercove.threshold`).
|
|
||||||
API paths, field names, protocol strings and environment variable names are
|
|
||||||
unchanged for compatibility with the server. The desktop client's persisted
|
|
||||||
settings are copied from the former "Boundary" user-data directory on first
|
|
||||||
launch.
|
|
||||||
- The desktop client looks for a `threshold` CLI first, then `boundary`.
|
|
||||||
- HashiCorp/IBM logos and brand art were removed and replaced with plain
|
|
||||||
placeholder marks.
|
|
||||||
- Nothing contacts HashiCorp services by default. The in-app updater, the
|
|
||||||
"unsupported controller" release-metadata lookup, and the CLI bundling
|
|
||||||
download are disabled until you configure your own hosts:
|
|
||||||
`THRESHOLD_UPDATE_FEED_URL` (desktop build, updater feed),
|
|
||||||
`THRESHOLD_RELEASES_METADATA_URL` / `THRESHOLD_RELEASES_PAGE_URL`
|
|
||||||
(desktop build, release links) and `THRESHOLD_CLI_RELEASES_URL` /
|
|
||||||
`THRESHOLD_CLI_ARCHIVE_PREFIX` (used with `SETUP_CLI=true` to bundle a CLI).
|
|
||||||
- Documentation links still point at the upstream Boundary documentation,
|
|
||||||
which is user-initiated only.
|
|
||||||
- Upstream HashiCorp-internal GitHub workflows and release metadata were
|
|
||||||
removed; CI lives in `.gitea/workflows/ci.yml`.
|
|
||||||
|
|
||||||
Upstream history, CHANGELOGs and copyright headers are preserved.
|
|
||||||
|
|
||||||
This top-level repository provides limited common tasks, such as installation
|
This top-level repository provides limited common tasks, such as installation
|
||||||
and commit assistance. However, most tasks must be executed from within a
|
and commit assistance. However, most tasks must be executed from within a
|
||||||
@@ -44,95 +13,62 @@ subproject, e.g. running or testing.
|
|||||||
|
|
||||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||||
|
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
|
||||||
|
|
||||||
- [Boundary UI Monorepo](#boundary-ui-monorepo)
|
- [Prerequisites](#prerequisites)
|
||||||
- [Projects](#projects)
|
- [Installation](#installation)
|
||||||
- [Core (addons/core):](#core-addonscore)
|
- [Yarn Commands](#yarn-commands)
|
||||||
- [API (addons/api):](#api-addonsapi)
|
- [Contributing](#contributing)
|
||||||
- [Auth (addons/auth):](#auth-addonsauth)
|
- [Branching](#branching)
|
||||||
- [Rose (addons/rose)](#rose-addonsrose)
|
- [Building ToC](#building-toc)
|
||||||
- [Admin (ui/admin)](#admin-uiadmin)
|
- [Building Admin UI for Production](#building-admin-ui-for-production)
|
||||||
- [Desktop Client (ui/desktop)](#desktop-client-uidesktop)
|
- [Building with a Container](#building-with-a-container)
|
||||||
- [Prerequisites](#prerequisites)
|
- [Building Desktop UI for Production](#building-desktop-ui-for-production)
|
||||||
- [Optional Tooling](#optional-tooling)
|
- [Connect Boundary UI to Boundary local instance](#connect-boundary-ui-to-boundary-local-instance)
|
||||||
- [Installation](#installation)
|
- [For admin](#for-admin)
|
||||||
- [Pnpm Commands](#pnpm-commands)
|
- [For desktop](#for-desktop)
|
||||||
- [Contributing](#contributing)
|
- [Committing](#committing)
|
||||||
- [Branching](#branching)
|
- [License Checking](#license-checking)
|
||||||
- [Building ToC](#building-toc)
|
|
||||||
- [Building Admin UI for Production](#building-admin-ui-for-production)
|
|
||||||
- [Building with a Container](#building-with-a-container)
|
|
||||||
- [Building Desktop UI for Production](#building-desktop-ui-for-production)
|
|
||||||
- [Connect Boundary UI to Boundary local instance](#connect-boundary-ui-to-boundary-local-instance)
|
|
||||||
- [For Admin](#for-admin)
|
|
||||||
- [For Desktop](#for-desktop)
|
|
||||||
- [Committing](#committing)
|
|
||||||
- [License Checking](#license-checking)
|
|
||||||
|
|
||||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||||
|
|
||||||
## Projects
|
|
||||||
|
|
||||||
This monorepo contains multiple projects.
|
|
||||||
### Core (addons/core):
|
|
||||||
Core features use by Boundary UI's, i.e i18n, helpers or components. [Project Readme](addons/core).
|
|
||||||
|
|
||||||
### API (addons/api):
|
|
||||||
The API data access layer for Boundary and all the related mocks. [Project Readme](addons/api).
|
|
||||||
|
|
||||||
### Auth (addons/auth):
|
|
||||||
Authentication layer for Boundary. [Project Readme](addons/auth).
|
|
||||||
|
|
||||||
### Rose (addons/rose)
|
|
||||||
Common styles and components shared by Boundary UIs. [Project Readme](addons/rose).
|
|
||||||
|
|
||||||
### Admin (ui/admin)
|
|
||||||
The Admin UI for Boundary. [Project Readme](ui/admin).
|
|
||||||
|
|
||||||
### Desktop Client (ui/desktop)
|
|
||||||
The desktop client UI for Boundary. [Project Readme](ui/desktop).
|
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
You will need the following things properly installed on your computer.
|
You will need the following things properly installed on your computer.
|
||||||
|
|
||||||
* [Git][git]
|
* [Git][git]
|
||||||
* [Node.js][node]
|
* [Node.js][node]
|
||||||
* Supported versions: `v20` and `v22`.
|
* v10–v15
|
||||||
* [Pnpm][pnpm] installed globally
|
* **Apple Silicon Users**: if you experience problems building or running
|
||||||
|
Boundary UIs, try Node v15.
|
||||||
|
* [Yarn][yarn] installed globally
|
||||||
* [Google Chrome][chrome]
|
* [Google Chrome][chrome]
|
||||||
* [Firefox][firefox]
|
* [Firefox][firefox]
|
||||||
|
|
||||||
|
[git]: https://git-scm.com/
|
||||||
## Optional Tooling
|
[node]: https://nodejs.org/
|
||||||
|
[yarn]: https://classic.yarnpkg.com/lang/en/
|
||||||
Our team finds the following applications useful in day-to-day development
|
[chrome]: https://google.com/chrome/
|
||||||
workflows. These are merely recommendations. We encourage you to use the tools
|
[firefox]: https://firefox.com/
|
||||||
that best suit you and your personal style.
|
[yarn-workspaces]: https://classic.yarnpkg.com/en/docs/workspaces/
|
||||||
|
|
||||||
* [VS Code][vscode]: Code editor for building and debugging web applications
|
|
||||||
* [Warp][warp]: Terminal application for macOS
|
|
||||||
* [Homebrew][homebrew]: The missing package manager for macOS and Linux
|
|
||||||
* [Ember Inspector][ember-inspector]: Understand and debug Ember applications
|
|
||||||
* [Postman][postman]: Test and inspect APIs
|
|
||||||
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
* `git clone <repository-url>` this repository
|
* `git clone <repository-url>` this repository
|
||||||
* `cd boundary-ui`
|
* `cd boundary-ui`
|
||||||
* `pnpm install`
|
* `yarn install`
|
||||||
|
|
||||||
## Pnpm Commands
|
## Yarn Commands
|
||||||
|
|
||||||
List of available project commands. `pnpm run <command-name>`
|
List of available project commands. `yarn run <command-name>`
|
||||||
|
|
||||||
| Command | Description |
|
| Command | Description |
|
||||||
|---------------------|---|
|
|---------------------|---|
|
||||||
| build | Builds Admin UI for production. |
|
| build | Builds Admin UI. |
|
||||||
| test | Runs tests in CI mode. |
|
| 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. |
|
| lint | Runs ember-template-lint on all of the hbs, js, and sass files. |
|
||||||
| compliance:audit | Checks for issues using `pnpm audit` with moderate and above criticality.|
|
| compliance:audit | Checks for issues using `yarn audit` with moderate and above criticality.|
|
||||||
| compliance:licenses | Checks that all dependencies have OSS-compatible licenses. |
|
| compliance:licenses | Checks that all dependencies have OSS-compatible licenses. |
|
||||||
| doc:toc | Automatically generates a table of contents for the README file. |
|
| doc:toc | Automatically generates a table of contents for the README file. |
|
||||||
|
|
||||||
@@ -145,20 +81,20 @@ We follow [GitHub Flow][github-flow].
|
|||||||
### Building ToC
|
### Building ToC
|
||||||
|
|
||||||
To autogenerate a ToC (table of contents) for this README,
|
To autogenerate a ToC (table of contents) for this README,
|
||||||
run `pnpm doc:toc`. Please update the ToC whenever editing the structure
|
run `yarn doc:toc`. Please update the ToC whenever editing the structure
|
||||||
of README.
|
of README.
|
||||||
|
|
||||||
### Building Admin UI for Production
|
### Building Admin UI for Production
|
||||||
|
|
||||||
See [Admin UI README](ui/admin/README.md#building-for-production) for more information on how to
|
See ui/admin/README.md Building for Production for more information on how to
|
||||||
build the Admin UI for production. Be sure to set build-related environment variables as
|
build the Admin UI. Be sure to set build-related environment variables as
|
||||||
necessary for your target environment, as described in the [Environment Variables](ui/admin/README.md#environment-variables) section of README.
|
necessary for your target environment, as described in the Admin UI readme.
|
||||||
|
|
||||||
To quickly produce a production build of Admin UI, run from this folder:
|
To quickly produce a production build of Admin UI, run from this folder:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm install
|
yarn install
|
||||||
pnpm build
|
yarn build
|
||||||
```
|
```
|
||||||
|
|
||||||
Assets are saved to `ui/admin/dist/`.
|
Assets are saved to `ui/admin/dist/`.
|
||||||
@@ -175,27 +111,27 @@ Assets are saved to `ui/admin/dist/`.
|
|||||||
|
|
||||||
### Building Desktop UI for Production
|
### Building Desktop UI for Production
|
||||||
|
|
||||||
See [Desktop UI README](ui/desktop/README.md#building-for-production) for more information on how to
|
See ui/desktop/README.md Building for Production for more information on how to
|
||||||
build the Desktop UI. Be sure to set build-related environment variables as
|
build the Desktop UI. Be sure to set build-related environment variables as
|
||||||
necessary for your target environment, as described in the [Environment Variables](ui/desktop/README.md#environment-variables-prod) section of README.
|
necessary for your target environment, as described in the Desktop UI readme.
|
||||||
|
|
||||||
To quickly produce a production build of Desktop UI, run from this folder:
|
To quickly produce a production build of Desktop UI, run from this folder:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm install
|
yarn install
|
||||||
pnpm build:ui:desktop
|
yarn build:ui:desktop
|
||||||
```
|
```
|
||||||
|
|
||||||
In windows, UI is generated using docker to provide a stable UI across platforms.
|
In windows, UI is generated using docker to provide a stable UI across platforms.
|
||||||
|
|
||||||
```cmd
|
```cmd
|
||||||
pnpm install
|
yarn install
|
||||||
docker-compose -f docker-compose-embedding.yml run build-desktop-production
|
docker-compose -f docker-compose-embedding.yml run build-desktop-production
|
||||||
pnpm build:ui:desktop:app
|
yarn build:ui:desktop:app
|
||||||
```
|
```
|
||||||
|
|
||||||
To provide a signing identify for macOS build, use `BOUNDARY_DESKTOP_SIGNING_IDENTITY`
|
To provide a signing identify for macOS build, use `BOUNDARY_DESKTOP_SIGNING_IDENTITY`
|
||||||
environment variable to set signing certificate name (e.g Developer ID Application: * (*)) when building desktop app using `pnpm build:ui:desktop:app`.
|
environment variable to set signing certificate name (e.g Developer ID Application: * (*)) when building desktop app using `yarn build:ui:desktop:app`.
|
||||||
|
|
||||||
Assets are saved to `ui/desktop/electron-app/out/make/`.
|
Assets are saved to `ui/desktop/electron-app/out/make/`.
|
||||||
DMG packaged desktop UI is available at asset location as `boundary.dmg`.
|
DMG packaged desktop UI is available at asset location as `boundary.dmg`.
|
||||||
@@ -205,36 +141,34 @@ EXE archived desktop UI is available at asset location under `zip` folder.
|
|||||||
|
|
||||||
This describes how to connect local Boundary UI to your local instance of Boundary.
|
This describes how to connect local Boundary UI to your local instance of Boundary.
|
||||||
|
|
||||||
This assumes you already have up and running a Boundary dev instance in your local environment with a listener `127.0.0.1:9200` (default behaviour). [Learn how to start a local Boundary dev instance](https://developer.hashicorp.com/boundary/tutorials/get-started-community/community-get-started-dev)
|
This assumes you already have up and running a Boundary dev instance in your local environment with a listener `127.0.0.1:9200` (default behaviour). [Learn how to start a local Boundary dev instance](https://learn.hashicorp.com/tutorials/boundary/getting-started-dev?in=boundary/getting-started#start-a-dev-environment).
|
||||||
|
#### For admin
|
||||||
#### For Admin
|
|
||||||
|
|
||||||
This assumes you are within `boundary-ui/ui/admin`.
|
This assumes you are within `boundary-ui/ui/admin`.
|
||||||
|
|
||||||
You will need to turn `off` mirage, tell the UI where to find Boundary and run it: `$ ENABLE_MIRAGE=false API_HOST=http://localhost:9200 pnpm start`.
|
You will need to turn `off` mirage, tell the UI where to find Boundary and run it: `$ ENABLE_MIRAGE=false API_HOST=http://localhost:9200 yarn start`.
|
||||||
|
|
||||||
Following terminal instructions, open in your browser: `http://localhost:4200/`.
|
Following terminal instructions, open in your browser: `http://localhost:4200/`.
|
||||||
|
|
||||||
Once you open the UI you will see the login screen, authenticate using generated admin login name and password.
|
Once you open the UI you will see the login screen, authenticate using generated admin login name and password.
|
||||||
|
|
||||||
#### For Desktop
|
#### For desktop
|
||||||
|
|
||||||
This assumes you are within `boundary-ui/ui/desktop`.
|
This assumes you are within `boundary-ui/ui/desktop`.
|
||||||
|
|
||||||
You will need to turn `off` mirage and run it: `$ ENABLE_MIRAGE=false pnpm start:desktop`.
|
You will need to turn `off` mirage and run it: `$ ENABLE_MIRAGE=false yarn start:desktop`.
|
||||||
|
|
||||||
In login screen, authenticate using generated admin login name and password.
|
In login screen, authenticate using generated admin login name and password.
|
||||||
|
|
||||||
Enter the cluster URL of your Boundary dev instance, by default is: `http://localhost:9200`.
|
Enter the origin of your Boundary dev instance, by default is: `http://localhost:9200`.
|
||||||
|
|
||||||
### Committing
|
### Committing
|
||||||
|
|
||||||
We use `husky` and `lint-staged` to ensure linting and other checks pass before a
|
Instead of the default `git commit`, we prescribe a custom command that ensures
|
||||||
commit is completed. Simply do a `pnpm install` to make sure the hooks are installed.
|
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
|
||||||
Use a normal `git commit` to go through the checks, if you need to skip these checks,
|
commit, stage your files as usual. Then run `yarn commit` and follow the
|
||||||
use `git commit --no-verify` to bypass them. However, a consistent commit message will
|
on-screen instructions to author your message.
|
||||||
still be enforced even if you use `--no-verify`.
|
|
||||||
|
|
||||||
#### License Checking
|
#### License Checking
|
||||||
|
|
||||||
@@ -246,15 +180,3 @@ The change will be verified upon PR. GPL variants and UNLICENSED dependencies
|
|||||||
will not be accepted.
|
will not be accepted.
|
||||||
|
|
||||||
[github-flow]: https://guides.github.com/introduction/flow/
|
[github-flow]: https://guides.github.com/introduction/flow/
|
||||||
|
|
||||||
[git]: https://git-scm.com/
|
|
||||||
[node]: https://nodejs.org/
|
|
||||||
[pnpm]: https://pnpm.io
|
|
||||||
[chrome]: https://google.com/chrome/
|
|
||||||
[firefox]: https://firefox.com/
|
|
||||||
[pnpm-workspaces]: https://pnpm.io/workspaces
|
|
||||||
[homebrew]: https://brew.sh
|
|
||||||
[warp]: https://www.warp.dev
|
|
||||||
[vscode]: https://code.visualstudio.com/
|
|
||||||
[ember-inspector]: https://guides.emberjs.com/release/ember-inspector/
|
|
||||||
[postman]: https://www.postman.com/downloads/
|
|
||||||
@@ -12,8 +12,5 @@ insert_final_newline = true
|
|||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
[*.hbs]
|
|
||||||
insert_final_newline = false
|
|
||||||
|
|
||||||
[*.{diff,md}]
|
[*.{diff,md}]
|
||||||
trim_trailing_whitespace = false
|
trim_trailing_whitespace = false
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
Setting `isTypeScriptProject` to true will force the blueprint generators to generate TypeScript
|
Ember CLI sends analytics information by default. The data is completely
|
||||||
rather than JavaScript by default, when a TypeScript version of a given blueprint is available.
|
anonymous, but there are times when you might want to disable this behavior.
|
||||||
|
|
||||||
|
Setting `disableAnalytics` to true will prevent any data from being sent.
|
||||||
*/
|
*/
|
||||||
"isTypeScriptProject": false
|
"disableAnalytics": false
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# unconventional js
|
||||||
|
/blueprints/*/files/
|
||||||
|
/vendor/
|
||||||
|
|
||||||
|
# compiled output
|
||||||
|
/dist/
|
||||||
|
/tmp/
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/bower_components/
|
||||||
|
/node_modules/
|
||||||
|
|
||||||
|
# misc
|
||||||
|
/coverage/
|
||||||
|
!.*
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
parser: 'babel-eslint',
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2018,
|
||||||
|
sourceType: 'module',
|
||||||
|
ecmaFeatures: {
|
||||||
|
legacyDecorators: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: ['ember'],
|
||||||
|
extends: [
|
||||||
|
'eslint:recommended',
|
||||||
|
'plugin:ember/recommended',
|
||||||
|
'plugin:prettier/recommended',
|
||||||
|
],
|
||||||
|
env: {
|
||||||
|
browser: true,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'ember/no-get': 'off',
|
||||||
|
'ember/no-get-with-default': 'off',
|
||||||
|
'ember/no-computed-properties-in-native-classes': 'off',
|
||||||
|
'ember/no-assignment-of-untracked-properties-used-in-tracking-contexts':
|
||||||
|
'off',
|
||||||
|
},
|
||||||
|
overrides: [
|
||||||
|
// node files
|
||||||
|
{
|
||||||
|
files: [
|
||||||
|
'.eslintrc.js',
|
||||||
|
'.prettierrc.js',
|
||||||
|
'.template-lintrc.js',
|
||||||
|
'ember-cli-build.js',
|
||||||
|
'index.js',
|
||||||
|
'testem.js',
|
||||||
|
'blueprints/*/index.js',
|
||||||
|
'config/**/*.js',
|
||||||
|
'tests/dummy/config/**/*.js',
|
||||||
|
],
|
||||||
|
excludedFiles: [
|
||||||
|
'addon/**',
|
||||||
|
'addon-test-support/**',
|
||||||
|
'app/**',
|
||||||
|
'tests/dummy/app/**',
|
||||||
|
],
|
||||||
|
parserOptions: {
|
||||||
|
sourceType: 'script',
|
||||||
|
},
|
||||||
|
env: {
|
||||||
|
browser: false,
|
||||||
|
node: true,
|
||||||
|
},
|
||||||
|
plugins: ['node'],
|
||||||
|
extends: ['plugin:node/recommended'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Test files:
|
||||||
|
files: ['tests/**/*-test.{js,ts}'],
|
||||||
|
extends: ['plugin:qunit/recommended'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
# compiled output
|
|
||||||
/dist/
|
|
||||||
/declarations/
|
|
||||||
|
|
||||||
# dependencies
|
|
||||||
/node_modules/
|
|
||||||
|
|
||||||
# misc
|
|
||||||
/.env*
|
|
||||||
/.pnp*
|
|
||||||
/.eslintcache
|
|
||||||
/coverage/
|
|
||||||
/testem.log
|
|
||||||
|
|
||||||
# ember-try
|
|
||||||
/.node_modules.ember-try/
|
|
||||||
/package.json.ember-try
|
|
||||||
|
|
||||||
# broccoli-debug
|
|
||||||
/DEBUG/
|
|
||||||
@@ -2,7 +2,11 @@
|
|||||||
/dist/
|
/dist/
|
||||||
/tmp/
|
/tmp/
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/bower_components/
|
||||||
|
|
||||||
# misc
|
# misc
|
||||||
|
/.bowerrc
|
||||||
/.editorconfig
|
/.editorconfig
|
||||||
/.ember-cli
|
/.ember-cli
|
||||||
/.env*
|
/.env*
|
||||||
@@ -10,20 +14,14 @@
|
|||||||
/.eslintignore
|
/.eslintignore
|
||||||
/.eslintrc.js
|
/.eslintrc.js
|
||||||
/.git/
|
/.git/
|
||||||
/.github/
|
|
||||||
/.gitignore
|
/.gitignore
|
||||||
/.prettierignore
|
|
||||||
/.prettierrc.js
|
|
||||||
/.template-lintrc.js
|
/.template-lintrc.js
|
||||||
|
/.travis.yml
|
||||||
/.watchmanconfig
|
/.watchmanconfig
|
||||||
|
/bower.json
|
||||||
/CONTRIBUTING.md
|
/CONTRIBUTING.md
|
||||||
/ember-cli-build.js
|
/ember-cli-build.js
|
||||||
/testem.js
|
/testem.js
|
||||||
/tests/
|
/tests/
|
||||||
/tsconfig.declarations.json
|
/yarn.lock
|
||||||
/tsconfig.json
|
|
||||||
.gitkeep
|
.gitkeep
|
||||||
|
|
||||||
# ember-try
|
|
||||||
/.node_modules.ember-try/
|
|
||||||
/package.json.ember-try
|
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
# unconventional js
|
# unconventional js
|
||||||
/blueprints/*/files/
|
/blueprints/*/files/
|
||||||
|
/vendor/
|
||||||
|
|
||||||
# compiled output
|
# compiled output
|
||||||
/dist/
|
/dist/
|
||||||
|
/tmp/
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/bower_components/
|
||||||
|
/node_modules/
|
||||||
|
|
||||||
# misc
|
# misc
|
||||||
/coverage/
|
/coverage/
|
||||||
!.*
|
!.*
|
||||||
.*/
|
.eslintcache
|
||||||
|
|
||||||
# ember-try
|
|
||||||
/.node_modules.ember-try/
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"printWidth": 80
|
||||||
|
}
|
||||||
@@ -1,17 +1,5 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
overrides: [
|
singleQuote: true,
|
||||||
{
|
|
||||||
files: '*.{js,ts}',
|
|
||||||
options: {
|
|
||||||
singleQuote: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
@@ -1,10 +1,5 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
extends: ['recommended', 'stylistic'],
|
extends: 'octane',
|
||||||
};
|
};
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"ignore_dirs": ["dist"]
|
"ignore_dirs": ["tmp", "dist"]
|
||||||
}
|
}
|
||||||
+18
-58
@@ -8,7 +8,7 @@ This addon contains the API data access layer for Boundary.
|
|||||||
|
|
||||||
- [Add API to an App](#add-api-to-an-app)
|
- [Add API to an App](#add-api-to-an-app)
|
||||||
- [Installation](#installation)
|
- [Installation](#installation)
|
||||||
- [Pnpm Commands](#pnpm-commands)
|
- [Yarn Commands](#yarn-commands)
|
||||||
- [Linting](#linting)
|
- [Linting](#linting)
|
||||||
- [Formatting](#formatting)
|
- [Formatting](#formatting)
|
||||||
- [Running tests](#running-tests)
|
- [Running tests](#running-tests)
|
||||||
@@ -21,104 +21,64 @@ This addon contains the API data access layer for Boundary.
|
|||||||
## Add API to an App
|
## Add API to an App
|
||||||
|
|
||||||
Add this addon to an Ember application's `devDependencies` as:
|
Add this addon to an Ember application's `devDependencies` as:
|
||||||
`"api": "workspace:*"`, for applications included in this monorepo.
|
`"api": "*"`, for applications included in this monorepo.
|
||||||
|
|
||||||
This addon also includes Mirage mocks. To include the `miragejs` dependency and this addon's mirage handlers configure the consuming app's `config/environment.js`
|
Since this addon also includes Mirage mocks, be sure to install
|
||||||
|
`ember-cli-mirage` and add the following config to your UI project:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
mirage: {
|
'ember-cli-mirage': {
|
||||||
enabled: true
|
directory: '../../addons/api/mirage'
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Include `miragejs` and any api addon `peerDependencies` used by the mirage as dev dependencies in the consuming app,
|
|
||||||
eg: `@faker-js/faker`, otherwise mirage handler code might fail with an error.
|
|
||||||
|
|
||||||
To have mirage start and intercept requests when the application starts:
|
|
||||||
1. Add the `@embroider/macros` dependency to your application
|
|
||||||
2. Configure `@embroider/macros` with `startMirageWithApp` based on app's config within `ember-cli-build.js`:
|
|
||||||
|
|
||||||
```js
|
|
||||||
// ember-cli-build.js
|
|
||||||
module.exports = async function (defaults) {
|
|
||||||
// load the app's config
|
|
||||||
const { EMBER_ENV } = process.env;
|
|
||||||
var config = require('./config/environment')(EMBER_ENV);
|
|
||||||
|
|
||||||
const app = new EmberApp(defaults, {
|
|
||||||
'@embroider/macros': {
|
|
||||||
setOwnConfig: {
|
|
||||||
startMirageWithApp: config.mirage?.enabled ?? false
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Finally, use the `@embroider/macros` config value for `startMirageWithApp` in `app/app.js` to conditionally start mirage:
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { macroCondition, importSync, getOwnConfig, isTesting } from '@embroider/macros';
|
|
||||||
|
|
||||||
if (macroCondition(getOwnConfig().startMirageWithApp && !isTesting())) {
|
|
||||||
const startServer = importSync('[name of host app]/mirage/config').default;
|
|
||||||
startServer({});
|
|
||||||
}
|
|
||||||
```
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
See monorepo README for installation instructions.
|
See monorepo README for installation instructions.
|
||||||
|
|
||||||
When manually installing addon, ensure `ember-data-fragments@5.0.0-beta.*` is installed to use api models with data fragments.
|
When manually installing addon, ensure `ember-data-fragments@5.0.0-beta.*` is installed to use api models with data fragments.
|
||||||
|
|
||||||
## Pnpm Commands
|
## Yarn Commands
|
||||||
|
|
||||||
List of available project commands. `pnpm run <command-name>`
|
List of available project commands. `yarn run <command-name>`
|
||||||
|
|
||||||
| Command | Description |
|
| Command | Description |
|
||||||
| ------- | ----------- |
|
| ------- | ----------- |
|
||||||
| build:development | Builds the dummy app in development mode. |
|
| build:development | Builds the dummy app in development mode. |
|
||||||
| build | Builds the dummy app for production. |
|
| build | Builds the dummy app for production. |
|
||||||
| lint | Runs all lint commands. |
|
| 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 | Lints `js` files. |
|
||||||
| lint:js:fix | Runs automatic lint fixes for `js` files. |
|
|
||||||
| format | Runs all auto-formatters. |
|
| format | Runs all auto-formatters. |
|
||||||
| format:js | Auto-formats `js` files using Prettier. |
|
| format:js | Auto-formats `js` files using Prettier. |
|
||||||
| start | Runs the dummy app local server. |
|
| start | Runs the dummy app local server. |
|
||||||
| test | Runs all tests. |
|
| test | Runs all tests. |
|
||||||
| test:ember-compatibility | Runs tests across multiple Ember versions with ember-try. |
|
| test:all | Runs tests across multiple Ember versions with ember-try. |
|
||||||
| precommit | Runs all lint and format. |
|
|
||||||
| doc:toc | Automatically generates a table of contents for this README file. |
|
| doc:toc | Automatically generates a table of contents for this README file. |
|
||||||
|
|
||||||
Additional commands in the monorepo package may affect this projects.
|
Additional commands in the monorepo package may affect this projects.
|
||||||
|
|
||||||
## Linting
|
## Linting
|
||||||
|
|
||||||
* `pnpm lint:fix`
|
* `yarn lint:hbs`
|
||||||
* `pnpm lint:hbs`
|
* `yarn lint:js`
|
||||||
* `pnpm lint:hbs:fix`
|
* `yarn lint:js --fix`
|
||||||
* `pnpm lint:js`
|
|
||||||
* `pnpm lint:js:fix`
|
|
||||||
|
|
||||||
## Formatting
|
## Formatting
|
||||||
|
|
||||||
Before submitting your work, be sure to run auto-formatters
|
Before submitting your work, be sure to run auto-formatters
|
||||||
(see commands above). This helps to ensure consistency among authors.
|
(see commands above). This helps to ensure consistency among authors.
|
||||||
|
|
||||||
* `pnpm format`
|
* `yarn format`
|
||||||
|
|
||||||
## Running tests
|
## Running tests
|
||||||
|
|
||||||
* `pnpm test` – Runs the test suite on the current Ember version
|
* `yarn test` – Runs the test suite on the current Ember version
|
||||||
* `pnpm test --server` – Runs the test suite in "watch mode"
|
* `yarn test --server` – Runs the test suite in "watch mode"
|
||||||
* `pnpm test:all` – Runs the test suite against multiple Ember versions
|
* `yarn test:all` – Runs the test suite against multiple Ember versions
|
||||||
|
|
||||||
## Running the dummy application
|
## Running the dummy application
|
||||||
|
|
||||||
* `pnpm start`
|
* `yarn start`
|
||||||
* Visit the dummy application at [http://localhost:4200](http://localhost:4200).
|
* Visit the dummy application at [http://localhost:4200](http://localhost:4200).
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
@@ -128,5 +88,5 @@ See monorepo README for more contribution instructions.
|
|||||||
### Building ToC
|
### Building ToC
|
||||||
|
|
||||||
To autogenerate a ToC (table of contents) for this README,
|
To autogenerate a ToC (table of contents) for this README,
|
||||||
run `pnpm doc:toc`. Please update the ToC whenever editing the structure
|
run `yarn doc:toc`. Please update the ToC whenever editing the structure
|
||||||
of README.
|
of README.
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import sinon from 'sinon';
|
|
||||||
import { typeOf } from '@ember/utils';
|
|
||||||
import { resourceNames } from 'api/handlers/cache-daemon-handler';
|
|
||||||
import { singularize } from 'ember-inflector';
|
|
||||||
import { underscore } from '@ember/string';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This test helper can be used to help setup your sinon stubs in your tests.
|
|
||||||
* Must be called after setupMirage and setupDesktopContextBridgeApiMock in tests.
|
|
||||||
*
|
|
||||||
* ```js
|
|
||||||
* import setupStubs from 'api/test-support/handlers/cache-daemon-search';
|
|
||||||
*
|
|
||||||
* module('Acceptance | my test', function(hooks) {
|
|
||||||
* setupApplicationTest(hooks);
|
|
||||||
* setupMirage(hooks);
|
|
||||||
* setupDesktopContextBridgeApiMock(hooks);
|
|
||||||
* setupStubs(hooks);
|
|
||||||
*
|
|
||||||
* // add your actual tests here
|
|
||||||
* });
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* This will setup a stub for window.desktop.daemon.searchCacheDaemon and include
|
|
||||||
* helper methods to help setup what the cache daemon search command returns.
|
|
||||||
*
|
|
||||||
* @module Test Helpers
|
|
||||||
* @public
|
|
||||||
*/
|
|
||||||
export default function setupStubs(hooks) {
|
|
||||||
let stubTypes = [];
|
|
||||||
|
|
||||||
hooks.beforeEach(function () {
|
|
||||||
/**
|
|
||||||
* We aim to still use mirage data when stubbing out the cache daemon
|
|
||||||
* search. However, the handler expects the search data to be raw JSON from
|
|
||||||
* the API which will get serialized. We add back the scope object for it to
|
|
||||||
* get correctly normalized and other fields such as "attributes" from the
|
|
||||||
* API will already be hoisted and will not be re-normalized from mirage data.
|
|
||||||
*
|
|
||||||
* This convenience method can take in multiple types,
|
|
||||||
* e.g. this.stubCacheDaemonSearch('targets', 'sessions').
|
|
||||||
* This will have sinon stub out each call so the first call to search will
|
|
||||||
* provide all the models from the first parameter you specify,
|
|
||||||
* the second call will provide all the models from the second argument, etc.
|
|
||||||
* @param types
|
|
||||||
*/
|
|
||||||
this.stubCacheDaemonSearch = (...types) => {
|
|
||||||
stubTypes = types;
|
|
||||||
|
|
||||||
types.forEach((type, i) => {
|
|
||||||
this.searchCacheDaemonStub.onCall(i).callsFake(() => {
|
|
||||||
let models;
|
|
||||||
let resourceName;
|
|
||||||
if (typeOf(type) === 'object') {
|
|
||||||
models = type.func();
|
|
||||||
resourceName = type.resource;
|
|
||||||
} else {
|
|
||||||
models = this.server.schema[type].all().models;
|
|
||||||
resourceName = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
[underscore(resourceNames[singularize(resourceName)])]: models.map(
|
|
||||||
(model) => {
|
|
||||||
// Use internal serializer to serialize the model correctly
|
|
||||||
// according to our mirage serializers
|
|
||||||
const modelData =
|
|
||||||
this.server.serializerOrRegistry.serialize(model);
|
|
||||||
|
|
||||||
// Serialize the data properly to standard JSON as that is what
|
|
||||||
// we're expecting from the cache daemon response
|
|
||||||
return JSON.parse(JSON.stringify(modelData));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
hooks.afterEach(function () {
|
|
||||||
// Verify the number of mocks we set up match with how
|
|
||||||
// many times the cache daemon was called with
|
|
||||||
sinon.assert.callCount(this.searchCacheDaemonStub, stubTypes.length);
|
|
||||||
|
|
||||||
stubTypes.forEach((type, i) => {
|
|
||||||
// Assert that the stub was called with the resource we're trying to mock
|
|
||||||
// so we don't mistakenly mock the wrong resource
|
|
||||||
const call = this.searchCacheDaemonStub.getCall(i);
|
|
||||||
let resource = type;
|
|
||||||
if (typeOf(type) === 'object') {
|
|
||||||
resource = type.resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
const mappedResourceName = resourceNames[singularize(resource)];
|
|
||||||
sinon.assert.match(call.args[0], { resource: mappedResourceName });
|
|
||||||
});
|
|
||||||
|
|
||||||
sinon.restore();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { settled } from '@ember/test-helpers';
|
|
||||||
|
|
||||||
export function createSetupMirage(startMirage) {
|
|
||||||
return function setupMirage(hooks) {
|
|
||||||
hooks.beforeEach(function () {
|
|
||||||
if (!this.owner) {
|
|
||||||
throw new Error(
|
|
||||||
'Must call one of the ember-qunit setupTest() / setupRenderingTest() / setupApplicationTest() first',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// the environment property here is configuration to the mirage server:
|
|
||||||
// https://github.com/miragejs/miragejs/blob/7ff4f3f6fe56bf0cb1648f5af3f5210fcb07e20b/types/index.d.ts#L383
|
|
||||||
// It is not related to ember's build environment. In this case for mirage the "test" environment does
|
|
||||||
// not load the default scenario:
|
|
||||||
// https://github.com/miragejs/miragejs/blob/7ff4f3f6fe56bf0cb1648f5af3f5210fcb07e20b/lib/server.js#L302
|
|
||||||
this.server = startMirage({ environment: 'test' });
|
|
||||||
});
|
|
||||||
|
|
||||||
hooks.afterEach(function () {
|
|
||||||
return settled().then(() => {
|
|
||||||
if (this.server) {
|
|
||||||
this.server.shutdown();
|
|
||||||
delete this.server;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This test helper can help set up and cleanup the database in your tests.
|
|
||||||
*
|
|
||||||
* ```js
|
|
||||||
* import { setupSqlite } from 'api/test-support/helpers/sqlite';
|
|
||||||
*
|
|
||||||
* module('Acceptance | my test', function(hooks) {
|
|
||||||
* setupApplicationTest(hooks);
|
|
||||||
* setupSqlite(hooks);
|
|
||||||
*
|
|
||||||
* // add your actual tests here
|
|
||||||
* });
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @param hooks
|
|
||||||
*/
|
|
||||||
export function setupSqlite(hooks) {
|
|
||||||
hooks.beforeEach(async function () {
|
|
||||||
const sqliteDb = this.owner.lookup('service:sqlite');
|
|
||||||
await sqliteDb.setup(`test-sqlite-${uuidv4()}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
hooks.afterEach(async function () {
|
|
||||||
const sqliteDb = this.owner.lookup('service:sqlite');
|
|
||||||
|
|
||||||
await sqliteDb.deleteDatabase();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export default setupSqlite;
|
|
||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ModelAbility from './model';
|
import ModelAbility from './model';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -11,30 +6,6 @@ import ModelAbility from './model';
|
|||||||
export default class AccountAbility extends ModelAbility {
|
export default class AccountAbility extends ModelAbility {
|
||||||
// =permissions
|
// =permissions
|
||||||
|
|
||||||
/**
|
|
||||||
* Only "known" account types may be read.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canRead() {
|
|
||||||
return !this.model.isUnknown && this.hasAuthorizedAction('read');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only "known" account types may be updated.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canUpdate() {
|
|
||||||
return !this.model.isUnknown && this.hasAuthorizedAction('update');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only "known" account types may be deleted.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canDelete() {
|
|
||||||
return !this.model.isUnknown && this.hasAuthorizedAction('delete');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ModelAbility from './model';
|
|
||||||
/**
|
|
||||||
* Provides abilities for auth method.
|
|
||||||
*/
|
|
||||||
export default class AuthMethodAbility extends ModelAbility {
|
|
||||||
// =permissions
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only "known" auth method types may be read.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canRead() {
|
|
||||||
return !this.model.isUnknown && this.hasAuthorizedAction('read');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only "known" auth method types may be updated.
|
|
||||||
*/
|
|
||||||
get canUpdate() {
|
|
||||||
return !this.model.isUnknown && this.hasAuthorizedAction('update');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only "known" auth method types may be deleted.
|
|
||||||
*/
|
|
||||||
get canDelete() {
|
|
||||||
return !this.model.isUnknown && this.hasAuthorizedAction('delete');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ModelAbility from './model';
|
|
||||||
import { service } from '@ember/service';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides abilities for channel recordings.
|
|
||||||
*/
|
|
||||||
export default class ChannelRecordingAbility extends ModelAbility {
|
|
||||||
// =services
|
|
||||||
@service abilities;
|
|
||||||
|
|
||||||
// =permissions
|
|
||||||
get canGetAsciicast() {
|
|
||||||
const sessionRecording = this.model.connection_recording.session_recording;
|
|
||||||
const sessionRecordingAbility = this.abilities.abilityFor(
|
|
||||||
'session-recording',
|
|
||||||
sessionRecording,
|
|
||||||
);
|
|
||||||
|
|
||||||
return this.model.isAsciicast && sessionRecordingAbility.canDownload;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ModelAbility from './model';
|
|
||||||
/**
|
|
||||||
* Provides abilities for credential.
|
|
||||||
*/
|
|
||||||
export default class CredentialLibraryAbility extends ModelAbility {
|
|
||||||
// =permissions
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only "known" credential library types may be read.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canRead() {
|
|
||||||
return !this.model.isUnknown && this.hasAuthorizedAction('read');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ModelAbility from './model';
|
|
||||||
import { service } from '@ember/service';
|
|
||||||
/**
|
|
||||||
* Provides abilities for credential store.
|
|
||||||
*/
|
|
||||||
export default class CredentialStoreAbility extends ModelAbility {
|
|
||||||
// =services
|
|
||||||
|
|
||||||
@service features;
|
|
||||||
|
|
||||||
// =permissions
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only "known" credential store types may be read.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canRead() {
|
|
||||||
return this.features.isEnabled('static-credentials')
|
|
||||||
? this.hasAuthorizedAction('read')
|
|
||||||
: !this.model.isStatic && this.hasAuthorizedAction('read');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ModelAbility from './model';
|
|
||||||
/**
|
|
||||||
* Provides abilities for credential.
|
|
||||||
*/
|
|
||||||
export default class CredentialAbility extends ModelAbility {
|
|
||||||
// =permissions
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only "known" credential types may be read.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canRead() {
|
|
||||||
return !this.model.isUnknown && this.hasAuthorizedAction('read');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ModelAbility from './model';
|
import ModelAbility from './model';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ModelAbility from './model';
|
import ModelAbility from './model';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ModelAbility from './model';
|
import ModelAbility from './model';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides abilities for host sets.
|
* Provides abilities for host sets.
|
||||||
*/
|
*/
|
||||||
export default class HostSetAbility extends ModelAbility {
|
export default class UserAbility extends ModelAbility {
|
||||||
// =permissions
|
// =permissions
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -24,11 +19,4 @@ export default class HostSetAbility extends ModelAbility {
|
|||||||
get canRemoveHosts() {
|
get canRemoveHosts() {
|
||||||
return this.hasAuthorizedAction('remove-hosts');
|
return this.hasAuthorizedAction('remove-hosts');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canRead() {
|
|
||||||
return !this.model.isUnknown && this.hasAuthorizedAction('read');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ModelAbility from './model';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides abilities for managed groups.
|
|
||||||
*/
|
|
||||||
export default class ManagedGroupAbility extends ModelAbility {
|
|
||||||
// no op
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Ability } from 'ember-can';
|
import { Ability } from 'ember-can';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ModelAbility from './model';
|
|
||||||
import { service } from '@ember/service';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides abilities for storage policies.
|
|
||||||
*/
|
|
||||||
export default class PolicyAbility extends ModelAbility {
|
|
||||||
// =services
|
|
||||||
@service features;
|
|
||||||
// =permissions
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This ensures that storage policies may be read only if the
|
|
||||||
* session-recording feature flag is enabled.
|
|
||||||
*/
|
|
||||||
get canRead() {
|
|
||||||
return this.features.isEnabled('ssh-session-recording')
|
|
||||||
? super.canRead
|
|
||||||
: false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This ensures that storage policies may be updated only if the
|
|
||||||
* session-recording feature flag is enabled.
|
|
||||||
*/
|
|
||||||
get canUpdate() {
|
|
||||||
return this.features.isEnabled('ssh-session-recording')
|
|
||||||
? super.canUpdate
|
|
||||||
: false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This ensures that storage policies may be deleted only if the
|
|
||||||
* session-recording feature flag is enabled.
|
|
||||||
*/
|
|
||||||
get canDelete() {
|
|
||||||
return this.features.isEnabled('ssh-session-recording')
|
|
||||||
? super.canDelete
|
|
||||||
: false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +1,9 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ModelAbility from './model';
|
import ModelAbility from './model';
|
||||||
import { service } from '@ember/service';
|
|
||||||
|
|
||||||
class InvalidRolePrincipalTypeError extends Error {
|
|
||||||
name = 'InvalidRolePrincipalTypeError';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides abilities for roles.
|
* Provides abilities for roles.
|
||||||
*/
|
*/
|
||||||
export default class RoleAbility extends ModelAbility {
|
export default class RoleAbility extends ModelAbility {
|
||||||
// =services
|
|
||||||
|
|
||||||
@service abilities;
|
|
||||||
|
|
||||||
// =permissions
|
// =permissions
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -27,13 +13,6 @@ export default class RoleAbility extends ModelAbility {
|
|||||||
return this.hasAuthorizedAction('set-grants');
|
return this.hasAuthorizedAction('set-grants');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canSetGrantScopes() {
|
|
||||||
return this.hasAuthorizedAction('set-grant-scopes');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
@@ -47,23 +26,4 @@ export default class RoleAbility extends ModelAbility {
|
|||||||
get canRemovePrincipals() {
|
get canRemovePrincipals() {
|
||||||
return this.hasAuthorizedAction('remove-principals');
|
return this.hasAuthorizedAction('remove-principals');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the ability check for a principal model instance.
|
|
||||||
* Valid role principal models are: User, Group, and ManagedGroup.
|
|
||||||
* Throws an error if the principal type is invalid.
|
|
||||||
* @type {boolean}
|
|
||||||
* @throws {InvalidRolePrincipalTypeError}
|
|
||||||
*/
|
|
||||||
get canReadPrincipal() {
|
|
||||||
const type = this.model.constructor.modelName;
|
|
||||||
const typeIsValid =
|
|
||||||
type === 'user' || type === 'group' || type === 'managed-group';
|
|
||||||
if (!typeIsValid) {
|
|
||||||
throw new InvalidRolePrincipalTypeError(
|
|
||||||
`Expected a role principal of type 'user', 'group', or 'managed-group'. Got '${type}'.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return this.abilities.can(`read ${type}`, this.model);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ModelAbility from './model';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides abilities for scopes.
|
|
||||||
*/
|
|
||||||
export default class ScopeAbility extends ModelAbility {
|
|
||||||
// =permissions
|
|
||||||
/**
|
|
||||||
* Permission that checks whether a policy can be attached to a scope
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canAttachStoragePolicy() {
|
|
||||||
return this.hasAuthorizedAction('attach-storage-policy');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Permission that checks whether a policy can be detached to a scope
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canDetachStoragePolicy() {
|
|
||||||
return this.hasAuthorizedAction('detach-storage-policy');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ModelAbility from './model';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides abilities for session recordings.
|
|
||||||
*/
|
|
||||||
export default class SessionRecordingAbility extends ModelAbility {
|
|
||||||
// =services
|
|
||||||
|
|
||||||
// =permissions
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only "known" session recording types may be read.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canRead() {
|
|
||||||
return !this.model.isUnknown && super.canRead;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only "known" session recording types may be deleted.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canDelete() {
|
|
||||||
return !this.model.isUnknown && super.canDelete && this.model.isAvailable;
|
|
||||||
}
|
|
||||||
|
|
||||||
get canDownload() {
|
|
||||||
return this.hasAuthorizedAction('download');
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Permission that checks whether a policy can be reapplied to a session recording
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canReapplyStoragePolicy() {
|
|
||||||
return this.hasAuthorizedAction('reapply-storage-policy');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ModelAbility from './model';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides abilities for sessions.
|
|
||||||
*/
|
|
||||||
export default class SessionAbility extends ModelAbility {
|
|
||||||
// =services
|
|
||||||
|
|
||||||
// =permissions
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only available sessions may be read.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canRead() {
|
|
||||||
return (
|
|
||||||
this.model.isAvailable &&
|
|
||||||
(this.hasAuthorizedAction('read:self') || super.canRead)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only available sessions may be canceled.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canCancel() {
|
|
||||||
return (
|
|
||||||
this.model.isAvailable &&
|
|
||||||
(this.hasAuthorizedAction('cancel:self') ||
|
|
||||||
this.hasAuthorizedAction('cancel'))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ModelAbility from './model';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides abilities for storage buckets.
|
|
||||||
*/
|
|
||||||
export default class StorageBucketAbility extends ModelAbility {
|
|
||||||
// =services
|
|
||||||
|
|
||||||
// =permissions
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only "known" storage bucket types may be read.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canRead() {
|
|
||||||
return !this.model.isUnknown && super.canRead;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only "known" storage bucket types may be updated.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canUpdate() {
|
|
||||||
return !this.model.isUnknown && super.canUpdate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only "known" storage bucket types may be deleted.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canDelete() {
|
|
||||||
return !this.model.isUnknown && super.canDelete;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ModelAbility from './model';
|
import ModelAbility from './model';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -35,19 +30,10 @@ export default class TargetAbility extends ModelAbility {
|
|||||||
/**
|
/**
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
get canAddBrokeredCredentialSources() {
|
get canAddCredentialSources() {
|
||||||
return this.hasAuthorizedAction('add-credential-sources');
|
return this.hasAuthorizedAction('add-credential-sources');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canAddInjectedApplicationCredentialSources() {
|
|
||||||
return (
|
|
||||||
(this.model.isSSH || this.model.isRDP) &&
|
|
||||||
this.hasAuthorizedAction('add-credential-sources')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ModelAbility from './model';
|
import ModelAbility from './model';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -24,20 +19,4 @@ export default class UserAbility extends ModelAbility {
|
|||||||
get canRemoveAccounts() {
|
get canRemoveAccounts() {
|
||||||
return this.hasAuthorizedAction('remove-accounts');
|
return this.hasAuthorizedAction('remove-accounts');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canAddAccount() {
|
|
||||||
const { account, canAddAccounts } = this;
|
|
||||||
return canAddAccounts && !account.isUnknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canRemoveAccount() {
|
|
||||||
const { account, canRemoveAccounts } = this;
|
|
||||||
return canRemoveAccounts && !account.isUnknown;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ModelAbility from './model';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides abilities for workers.
|
|
||||||
*/
|
|
||||||
export default class WorkerAbility extends ModelAbility {
|
|
||||||
// =permissions
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canCreateWorkerLed() {
|
|
||||||
return this.hasAuthorizedCollectionAction('create:worker-led');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canSetWorkerTags() {
|
|
||||||
return this.hasAuthorizedAction('set-worker-tags');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get canRemoveTags() {
|
|
||||||
return this.hasAuthorizedAction('remove-worker-tags');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import RESTAdapter from '@ember-data/adapter/rest';
|
import RESTAdapter from '@ember-data/adapter/rest';
|
||||||
import { serializeIntoHash } from '@ember-data/adapter/-private';
|
import { serializeIntoHash } from '@ember-data/adapter/-private';
|
||||||
/* eslint-disable-next-line ember/no-mixins */
|
/* eslint-disable-next-line ember/no-mixins */
|
||||||
@@ -45,7 +40,7 @@ function prenormalizeArrayResponse(response) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class ApplicationAdapter extends RESTAdapter.extend(
|
export default class ApplicationAdapter extends RESTAdapter.extend(
|
||||||
AdapterBuildURLMixin,
|
AdapterBuildURLMixin
|
||||||
) {
|
) {
|
||||||
// =attributes
|
// =attributes
|
||||||
|
|
||||||
@@ -108,66 +103,22 @@ export default class ApplicationAdapter extends RESTAdapter.extend(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Intercepts "empty" responses and adds an empty `items` array.
|
* Intercepts "empty" responses and adds an empty `items` array.
|
||||||
* This query method now supports pagination by checking the responseType and
|
* @override
|
||||||
* passing in the list token if the responseType indicates more data
|
* @method findAll
|
||||||
|
* @return {Promise} promise
|
||||||
|
*/
|
||||||
|
findAll() {
|
||||||
|
return super.findAll(...arguments).then(prenormalizeArrayResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intercepts "empty" responses and adds an empty `items` array.
|
||||||
* @override
|
* @override
|
||||||
* @method query
|
* @method query
|
||||||
* @return {Promise} promise
|
* @return {Promise} promise
|
||||||
*/
|
*/
|
||||||
async query(store, schema, query) {
|
query() {
|
||||||
const { batchLimit, ...queryObject } = query;
|
return super.query(...arguments).then(prenormalizeArrayResponse);
|
||||||
let result;
|
|
||||||
let data = [];
|
|
||||||
|
|
||||||
// If the query has a page_size, we skip the pagination logic
|
|
||||||
// and return the initial result. This is being used to determine
|
|
||||||
// if the controller supports pagination
|
|
||||||
if (query.page_size) {
|
|
||||||
result = await super.query(store, schema, query);
|
|
||||||
return prenormalizeArrayResponse(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run this loop as long as the response_type is delta,
|
|
||||||
// which indicates that there are more items in the list
|
|
||||||
// or the batch size has not been reached
|
|
||||||
do {
|
|
||||||
try {
|
|
||||||
result = await super.query(store, schema, queryObject);
|
|
||||||
} catch (e) {
|
|
||||||
// If we hit a rate limit mid-pagination, return whatever
|
|
||||||
// data has been accumulated so far rather than throwing and leaving
|
|
||||||
// the user stuck with nothing to show.
|
|
||||||
// Without a list_token this is the very first request with nothing to
|
|
||||||
// show, so rethrow and let normal error handling apply.
|
|
||||||
if (e?.errors?.[0]?.isRateLimited && queryObject.list_token) {
|
|
||||||
result ??= {};
|
|
||||||
result.items = data;
|
|
||||||
result.response_type = 'complete';
|
|
||||||
result.meta = {
|
|
||||||
...result.meta,
|
|
||||||
rateLimitWarning: { retryAfter: e.errors[0].retryAfter },
|
|
||||||
};
|
|
||||||
return prenormalizeArrayResponse(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
// For all other errors (or a 429 on the very first request with
|
|
||||||
// no data yet), rethrow so normal error handling applies.
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the result items to a data array
|
|
||||||
if (result && result.items) {
|
|
||||||
data.push(...result.items);
|
|
||||||
// Pass in the list token for subsequent calls to fetch the remaining list items
|
|
||||||
queryObject.list_token = result.list_token;
|
|
||||||
}
|
|
||||||
} while (
|
|
||||||
result?.response_type === 'delta' &&
|
|
||||||
(!batchLimit || data.length < batchLimit)
|
|
||||||
);
|
|
||||||
|
|
||||||
result.items = data;
|
|
||||||
return prenormalizeArrayResponse(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -191,7 +142,7 @@ export default class ApplicationAdapter extends RESTAdapter.extend(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides default ajax method by rewriting PUT requests as PATCH.
|
* Overrides default ajax method by rewritting PUT requests as PATCH.
|
||||||
* PATCH is the request method used by our API for updates.
|
* PATCH is the request method used by our API for updates.
|
||||||
*
|
*
|
||||||
* @override
|
* @override
|
||||||
@@ -240,10 +191,7 @@ export default class ApplicationAdapter extends RESTAdapter.extend(
|
|||||||
handleResponse(status, headers, payload, requestData) {
|
handleResponse(status, headers, payload, requestData) {
|
||||||
if (this.isInvalid(status, headers, payload)) {
|
if (this.isInvalid(status, headers, payload)) {
|
||||||
const detailedMessage = this.generatedDetailedMessage(...arguments);
|
const detailedMessage = this.generatedDetailedMessage(...arguments);
|
||||||
const transformedPayload = this.transformValidationErrors(
|
const transformedPayload = this.transformValidationErrors(payload);
|
||||||
payload,
|
|
||||||
status,
|
|
||||||
);
|
|
||||||
return new InvalidError(transformedPayload.errors, detailedMessage);
|
return new InvalidError(transformedPayload.errors, detailedMessage);
|
||||||
}
|
}
|
||||||
return super.handleResponse(status, headers, payload, requestData);
|
return super.handleResponse(status, headers, payload, requestData);
|
||||||
@@ -260,7 +208,6 @@ export default class ApplicationAdapter extends RESTAdapter.extend(
|
|||||||
* - `403 isForbidden`: the session is authenticated but does not have
|
* - `403 isForbidden`: the session is authenticated but does not have
|
||||||
* permission to perform the requested action
|
* permission to perform the requested action
|
||||||
* - `404 isNotFound`: the requested resource could not be found
|
* - `404 isNotFound`: the requested resource could not be found
|
||||||
* - `429 isRateLimited`: the client has exceeded the rate limit
|
|
||||||
* - `500 isServer`: an internal server error occurred
|
* - `500 isServer`: an internal server error occurred
|
||||||
* - `isUnknown`: an error occurred, but we don't know which or
|
* - `isUnknown`: an error occurred, but we don't know which or
|
||||||
* we don't distinguish it yet
|
* we don't distinguish it yet
|
||||||
@@ -272,7 +219,7 @@ export default class ApplicationAdapter extends RESTAdapter.extend(
|
|||||||
* @param {Object} payload
|
* @param {Object} payload
|
||||||
* @return {Array} errors payload
|
* @return {Array} errors payload
|
||||||
*/
|
*/
|
||||||
normalizeErrorResponse(status, headers /*, payload*/) {
|
normalizeErrorResponse(/*status, headers, payload*/) {
|
||||||
const errors = super.normalizeErrorResponse(...arguments);
|
const errors = super.normalizeErrorResponse(...arguments);
|
||||||
if (isArray(errors)) {
|
if (isArray(errors)) {
|
||||||
errors.forEach((error) => {
|
errors.forEach((error) => {
|
||||||
@@ -286,14 +233,6 @@ export default class ApplicationAdapter extends RESTAdapter.extend(
|
|||||||
case 404:
|
case 404:
|
||||||
error.isNotFound = true;
|
error.isNotFound = true;
|
||||||
break;
|
break;
|
||||||
case 429:
|
|
||||||
error.isRateLimited = true;
|
|
||||||
// Attach rate-limit metadata from response headers so downstream
|
|
||||||
// error handlers can inform the user when they may retry.
|
|
||||||
error.retryAfter = Number(
|
|
||||||
headers['Retry-After'] ?? headers['retry-after'],
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case 500:
|
case 500:
|
||||||
error.isServer = true;
|
error.isServer = true;
|
||||||
break;
|
break;
|
||||||
@@ -310,30 +249,50 @@ export default class ApplicationAdapter extends RESTAdapter.extend(
|
|||||||
* error format.
|
* error format.
|
||||||
*
|
*
|
||||||
* @param {object} payload
|
* @param {object} payload
|
||||||
* @param status
|
|
||||||
* @return {object}
|
* @return {object}
|
||||||
*/
|
*/
|
||||||
transformValidationErrors(payload, status) {
|
transformValidationErrors(payload) {
|
||||||
const fieldErrors = get(payload, 'details.request_fields') || [];
|
const fieldErrors = get(payload, 'details.request_fields') || [];
|
||||||
// Normalize the primary error message into "base", which is an error
|
// Normalize the primary error message into "base", which is an error
|
||||||
// that applies to the whole model instance
|
// that applies to the whole model instance
|
||||||
const baseError = {
|
const baseError = {
|
||||||
isInvalid: true,
|
isInvalid: true,
|
||||||
status,
|
status: payload.source,
|
||||||
code: payload?.kind,
|
code: payload.code,
|
||||||
detail: payload?.message,
|
detail: payload.message,
|
||||||
source: { pointer: '/data' },
|
source: { pointer: '/data' },
|
||||||
};
|
};
|
||||||
// Normalize field-specific errors, if any.
|
// Normalize field-specific errors, if any.
|
||||||
const errors = fieldErrors.map((error) => ({
|
const errors = fieldErrors.flatMap((error) => {
|
||||||
detail: error.description,
|
const newValue = [
|
||||||
// Going forward, nested attributes will be hoisted. Thus "attributes."
|
{
|
||||||
// must be stripped from the error name key.
|
detail: error.description,
|
||||||
source: {
|
// Ember Data cannot handle errors on nested attributes, so these are
|
||||||
pointer: `/data/attributes/${error.name.replace('attributes.', '')}`,
|
// flattened (e.g. `attributes.foobar` becomes `attributes_foobar`).
|
||||||
},
|
// To capture these errors, add read-only fields on the model
|
||||||
}));
|
// corresponding to the underscored field name.
|
||||||
|
source: {
|
||||||
|
pointer: `/data/attributes/${error.name.replace('.', '_')}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
if (error.name.includes('attributes.')) {
|
||||||
|
newValue.push({
|
||||||
|
detail: error.description,
|
||||||
|
// Going forward, nested attributes will be hoisted. Thus "attributes."
|
||||||
|
// must be stripped from the error name key. Until all models are
|
||||||
|
// transitioned away from model fragments, however, both this and the
|
||||||
|
// prior error key mappings are necessary.
|
||||||
|
source: {
|
||||||
|
pointer: `/data/attributes/${error.name.replace(
|
||||||
|
'attributes.',
|
||||||
|
''
|
||||||
|
)}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return newValue;
|
||||||
|
});
|
||||||
// Return a list of JSON API errors rooted under the `errors` key.
|
// Return a list of JSON API errors rooted under the `errors` key.
|
||||||
return {
|
return {
|
||||||
errors: [baseError, ...errors],
|
errors: [baseError, ...errors],
|
||||||
@@ -354,6 +313,6 @@ export default class ApplicationAdapter extends RESTAdapter.extend(
|
|||||||
* @return {String} detailed error message
|
* @return {String} detailed error message
|
||||||
*/
|
*/
|
||||||
generatedDetailedMessage(status, headers, payload /*, requestData*/) {
|
generatedDetailedMessage(status, headers, payload /*, requestData*/) {
|
||||||
return payload?.message;
|
return payload.message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ApplicationAdapter from './application';
|
import ApplicationAdapter from './application';
|
||||||
|
|
||||||
export default class HostCatalogAdapter extends ApplicationAdapter {
|
export default class HostCatalogAdapter extends ApplicationAdapter {
|
||||||
@@ -20,12 +15,8 @@ export default class HostCatalogAdapter extends ApplicationAdapter {
|
|||||||
buildURL(modelName, id, snapshot, requestType) {
|
buildURL(modelName, id, snapshot, requestType) {
|
||||||
let url = super.buildURL(...arguments);
|
let url = super.buildURL(...arguments);
|
||||||
if (requestType === 'createRecord') {
|
if (requestType === 'createRecord') {
|
||||||
try {
|
const pluginName = snapshot.attr('plugin')?.name;
|
||||||
const pluginName = snapshot.attr('plugin')?.name;
|
if (pluginName) url = `${url}?plugin_name=${pluginName}`;
|
||||||
if (pluginName) url = `${url}?plugin_name=${pluginName}`;
|
|
||||||
} catch {
|
|
||||||
// Ignore any adapter errors here
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,74 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ApplicationAdapter from './application';
|
|
||||||
import { MIME_TYPE_ASCIICAST } from 'api/models/channel-recording';
|
|
||||||
|
|
||||||
export default class SessionRecordingAdapter extends ApplicationAdapter {
|
|
||||||
/**
|
|
||||||
* Overrides the default `buildURL` such that for custom download methods,
|
|
||||||
* URLs will get the query parameters. All other request types behave as normal.
|
|
||||||
*
|
|
||||||
* @param modelName {string}
|
|
||||||
* @param id {string}
|
|
||||||
* @param snapshot {object}
|
|
||||||
* @param requestType {string}
|
|
||||||
* @param query {object}
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
buildURL(modelName, id, snapshot, requestType, query) {
|
|
||||||
let url = super.buildURL(...arguments);
|
|
||||||
let method;
|
|
||||||
try {
|
|
||||||
method = snapshot?.adapterOptions?.method;
|
|
||||||
} catch {
|
|
||||||
// Ignore any adapter errors here
|
|
||||||
}
|
|
||||||
if (method === 'download') {
|
|
||||||
const queryParams = new URLSearchParams(query).toString();
|
|
||||||
if (queryParams) url = `${url}?${queryParams}`;
|
|
||||||
}
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the download recording for recordings. Takes in a mime type for the
|
|
||||||
* type or recording to return.
|
|
||||||
* The ID can be the session ID, session recording ID,
|
|
||||||
* connection recording ID, or the channel recording ID.
|
|
||||||
* @param id {string}
|
|
||||||
* @param mimeType {string}
|
|
||||||
* @returns {Promise<string>}
|
|
||||||
*/
|
|
||||||
async getRecordingDownload({ id, mimeType }) {
|
|
||||||
const options = { adapterOptions: { method: 'download' } };
|
|
||||||
const url = this.buildURL('session-recording', id, options, 'findRecord', {
|
|
||||||
mime_type: mimeType,
|
|
||||||
});
|
|
||||||
|
|
||||||
const response = await fetch(url, { headers: this.headers });
|
|
||||||
if (response?.ok) {
|
|
||||||
return response.text();
|
|
||||||
} else {
|
|
||||||
throw this.handleResponse(
|
|
||||||
response.status,
|
|
||||||
response.headers,
|
|
||||||
await response.text(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an ascii cast recording.
|
|
||||||
* @param id
|
|
||||||
* @returns {Promise<string>}
|
|
||||||
*/
|
|
||||||
getAsciicast(id) {
|
|
||||||
return this.getRecordingDownload({
|
|
||||||
id,
|
|
||||||
mimeType: MIME_TYPE_ASCIICAST,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ApplicationAdapter from './application';
|
|
||||||
|
|
||||||
export default class StorageBucketAdapter extends ApplicationAdapter {
|
|
||||||
/**
|
|
||||||
* Overrides the default `buildURL` such that on _create_, URLs for records of
|
|
||||||
* type `plugin` get an extra query parameter `?plugin_name`. All other
|
|
||||||
* request types behave as normal.
|
|
||||||
*
|
|
||||||
* @override
|
|
||||||
* @param {string} modelName
|
|
||||||
* @param {string} id
|
|
||||||
* @return {string} url
|
|
||||||
* @return {string} requestType
|
|
||||||
*/
|
|
||||||
buildURL(modelName, id, snapshot, requestType) {
|
|
||||||
let url = super.buildURL(...arguments);
|
|
||||||
let pluginName;
|
|
||||||
try {
|
|
||||||
pluginName = snapshot?.attr('plugin')?.name;
|
|
||||||
} catch {
|
|
||||||
// Ignore any adapter errors here
|
|
||||||
}
|
|
||||||
if (requestType === 'createRecord' && pluginName) {
|
|
||||||
url = `${url}?plugin_name=${pluginName}`;
|
|
||||||
}
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import BaseModel from '../../models/base';
|
import BaseModel from '../../models/base';
|
||||||
import { attr } from '@ember-data/model';
|
import { attr } from '@ember-data/model';
|
||||||
|
|
||||||
@@ -48,39 +43,4 @@ export default class GeneratedAccountModel extends BaseModel {
|
|||||||
description: 'Current version number of this resource.',
|
description: 'Current version number of this resource.',
|
||||||
})
|
})
|
||||||
version;
|
version;
|
||||||
|
|
||||||
// =attributes (password and LDAP)
|
|
||||||
@attr('string', {
|
|
||||||
for: ['password', 'ldap'],
|
|
||||||
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;
|
|
||||||
|
|
||||||
// =attributes (OIDC and LDAP)
|
|
||||||
@attr('string', {
|
|
||||||
for: ['oidc', 'ldap'],
|
|
||||||
isNestedAttribute: true,
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
email;
|
|
||||||
@attr('string', {
|
|
||||||
for: ['oidc', 'ldap'],
|
|
||||||
isNestedAttribute: true,
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
full_name;
|
|
||||||
|
|
||||||
// =attributes (LDAP)
|
|
||||||
@attr('string', { for: 'ldap', isNestedAttribute: true, readOnly: true }) dn;
|
|
||||||
@attr('string-array', {
|
|
||||||
for: 'ldap',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
member_of_groups;
|
|
||||||
}
|
}
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import BaseModel from '../../models/base';
|
|
||||||
import { attr } from '@ember-data/model';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Alias contains all fields related to an Alias resource
|
|
||||||
*/
|
|
||||||
export default class GeneratedAliasModel extends BaseModel {
|
|
||||||
// =attributes
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description: 'The type of the resource, to help differentiate schemas',
|
|
||||||
})
|
|
||||||
type;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description: 'Optional name for identification purposes.',
|
|
||||||
})
|
|
||||||
name;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description: 'Optional user-set description for identification purposes.',
|
|
||||||
})
|
|
||||||
description;
|
|
||||||
|
|
||||||
@attr('date', {
|
|
||||||
description: 'The time this resource was created\nOutput only.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
created_time;
|
|
||||||
|
|
||||||
@attr('date', {
|
|
||||||
description: 'The time this resource was last updated\nOutput only.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
updated_time;
|
|
||||||
|
|
||||||
@attr('number', {
|
|
||||||
description: 'Current version number of this resource.',
|
|
||||||
})
|
|
||||||
version;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description:
|
|
||||||
'This is the value referenced by the user that is resolved to the destination id.',
|
|
||||||
})
|
|
||||||
value;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description: 'This is the id of the resource that this Alias points to.',
|
|
||||||
})
|
|
||||||
destination_id;
|
|
||||||
|
|
||||||
@attr('object', {
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description:
|
|
||||||
'This contains a host_id which is the id of the host that the session will be authorized for.',
|
|
||||||
})
|
|
||||||
authorize_session_arguments;
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import BaseModel from '../../models/base';
|
import BaseModel from '../../models/base';
|
||||||
import { attr } from '@ember-data/model';
|
import { attr } from '@ember-data/model';
|
||||||
|
|
||||||
@@ -54,267 +49,4 @@ export default class GeneratedAuthMethodModel extends BaseModel {
|
|||||||
description: 'Current version number of this resource.',
|
description: 'Current version number of this resource.',
|
||||||
})
|
})
|
||||||
version;
|
version;
|
||||||
|
|
||||||
// =attributes(oidc, ldap)
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: ['oidc', 'ldap'],
|
|
||||||
readOnly: true,
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
state;
|
|
||||||
|
|
||||||
// =attributes(oidc)
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'oidc',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
issuer;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'oidc',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
client_id;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'oidc',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
isSecret: true,
|
|
||||||
})
|
|
||||||
client_secret;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'oidc',
|
|
||||||
readOnly: true,
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
client_secret_hmac;
|
|
||||||
|
|
||||||
@attr('number', {
|
|
||||||
for: 'oidc',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
max_age;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'oidc',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
api_url_prefix;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'oidc',
|
|
||||||
readOnly: true,
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
callback_url;
|
|
||||||
|
|
||||||
@attr('boolean', {
|
|
||||||
for: 'oidc',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
disable_discovered_config_validation;
|
|
||||||
|
|
||||||
@attr('boolean', {
|
|
||||||
for: 'oidc',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
dry_run;
|
|
||||||
|
|
||||||
@attr('string-array', {
|
|
||||||
for: 'oidc',
|
|
||||||
emptyArrayIfMissing: true,
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
claims_scopes;
|
|
||||||
|
|
||||||
@attr('string-array', {
|
|
||||||
for: 'oidc',
|
|
||||||
emptyArrayIfMissing: true,
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
signing_algorithms;
|
|
||||||
|
|
||||||
@attr('string-array', {
|
|
||||||
for: 'oidc',
|
|
||||||
emptyArrayIfMissing: true,
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
allowed_audiences;
|
|
||||||
|
|
||||||
@attr('string-array', {
|
|
||||||
for: 'oidc',
|
|
||||||
emptyArrayIfMissing: true,
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
idp_ca_certs;
|
|
||||||
|
|
||||||
@attr('account-value-map-array', {
|
|
||||||
for: 'oidc',
|
|
||||||
emptyArrayIfMissing: true,
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
account_claim_maps;
|
|
||||||
|
|
||||||
@attr('string-array', {
|
|
||||||
for: 'oidc',
|
|
||||||
emptyArrayIfMissing: true,
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
prompts;
|
|
||||||
|
|
||||||
// =attributes(ldap)
|
|
||||||
|
|
||||||
@attr('boolean', {
|
|
||||||
for: 'ldap',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
start_tls;
|
|
||||||
|
|
||||||
@attr('boolean', {
|
|
||||||
for: 'ldap',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
insecure_tls;
|
|
||||||
|
|
||||||
@attr('boolean', {
|
|
||||||
for: 'ldap',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
discover_dn;
|
|
||||||
|
|
||||||
@attr('boolean', {
|
|
||||||
for: 'ldap',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
anon_group_search;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'ldap',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
upn_domain;
|
|
||||||
|
|
||||||
@attr('string-array', {
|
|
||||||
for: 'ldap',
|
|
||||||
emptyArrayIfMissing: true,
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
urls;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'ldap',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
user_dn;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'ldap',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
user_attr;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'ldap',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
user_filter;
|
|
||||||
|
|
||||||
@attr('boolean', {
|
|
||||||
for: 'ldap',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
enable_groups;
|
|
||||||
|
|
||||||
@attr('boolean', {
|
|
||||||
for: 'ldap',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
use_token_groups;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'ldap',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
group_dn;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'ldap',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
group_attr;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'ldap',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
group_filter;
|
|
||||||
|
|
||||||
@attr('string-array', {
|
|
||||||
for: 'ldap',
|
|
||||||
emptyArrayIfMissing: true,
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
certificates;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'ldap',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
client_certificate;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'ldap',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
isSecret: true,
|
|
||||||
})
|
|
||||||
client_certificate_key;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'ldap',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
client_certificate_key_hmac;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'ldap',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
bind_dn;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'ldap',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
isSecret: true,
|
|
||||||
})
|
|
||||||
bind_password;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'ldap',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
bind_password_hmac;
|
|
||||||
|
|
||||||
@attr('account-value-map-array', {
|
|
||||||
for: 'ldap',
|
|
||||||
emptyArrayIfMissing: true,
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
account_attribute_maps;
|
|
||||||
|
|
||||||
@attr('number', {
|
|
||||||
for: 'ldap',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
maximum_page_size;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'ldap',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
dereference_aliases;
|
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import BaseModel from '../../models/base';
|
import BaseModel from '../../models/base';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import BaseModel from '../../models/base';
|
|
||||||
import { attr } from '@ember-data/model';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A channel contains data for a single channel within a connection.
|
|
||||||
*/
|
|
||||||
export default class GeneratedChannelRecordingModel extends BaseModel {
|
|
||||||
// =attributes
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description:
|
|
||||||
'The total number of bytes uploaded from the client in this Channel.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
bytes_up;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description:
|
|
||||||
'The total number of bytes downloaded to the client in this Channel.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
bytes_down;
|
|
||||||
|
|
||||||
@attr('number', {
|
|
||||||
description:
|
|
||||||
'The total number of errors that occurred during the use of this Channel.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
errors_number;
|
|
||||||
|
|
||||||
@attr('date', {
|
|
||||||
description: 'The time the Channel started.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
start_time;
|
|
||||||
|
|
||||||
@attr('date', {
|
|
||||||
description: 'The time the Channel finished.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
end_time;
|
|
||||||
|
|
||||||
@attr({
|
|
||||||
description: 'The array of mime types that this recording will support.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
mime_types;
|
|
||||||
|
|
||||||
@attr('duration', {
|
|
||||||
description: 'The duration of this channel recording in ms.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
duration;
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import BaseModel from '../../models/base';
|
|
||||||
import { attr } from '@ember-data/model';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A connection contains data for a boundary connection within a session.
|
|
||||||
*/
|
|
||||||
export default class GeneratedConnectionRecordingModel extends BaseModel {
|
|
||||||
// =attributes
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description:
|
|
||||||
'The ID of the Connection which this Connection Recording recorded.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
connection_id;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description:
|
|
||||||
'The total number of bytes uploaded from the client in this Connection.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
bytes_up;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description:
|
|
||||||
'The total number of bytes downloaded to the client in this Connection.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
bytes_down;
|
|
||||||
|
|
||||||
@attr('number', {
|
|
||||||
description:
|
|
||||||
'The total number of errors that occurred during the use of this Connection.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
errors_number;
|
|
||||||
|
|
||||||
@attr('date', {
|
|
||||||
description: 'The time the Connection started.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
start_time;
|
|
||||||
|
|
||||||
@attr('date', {
|
|
||||||
description: 'The time the Connection finished.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
end_time;
|
|
||||||
|
|
||||||
@attr({
|
|
||||||
description: 'The array of mime types that this recording will support.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
mime_types;
|
|
||||||
|
|
||||||
@attr('duration', {
|
|
||||||
description: 'The duration of this connection recording in ms.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
duration;
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import BaseModel from '../../models/base';
|
import BaseModel from '../../models/base';
|
||||||
import { attr } from '@ember-data/model';
|
import { attr } from '@ember-data/model';
|
||||||
|
|
||||||
@@ -49,95 +44,4 @@ export default class GeneratedCredentialLibraryModel extends BaseModel {
|
|||||||
description: 'Current version number of this resource.',
|
description: 'Current version number of this resource.',
|
||||||
})
|
})
|
||||||
version;
|
version;
|
||||||
|
|
||||||
//= attributes (vault)
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'vault-generic',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description:
|
|
||||||
'The HTTP method the library uses when requesting credentials from Vault.',
|
|
||||||
defaultValue: () => 'GET',
|
|
||||||
})
|
|
||||||
http_method;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'vault-generic',
|
|
||||||
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;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'vault-generic',
|
|
||||||
description: 'It indicates the type of credential the library returns.',
|
|
||||||
})
|
|
||||||
credential_type;
|
|
||||||
|
|
||||||
@attr('object', {
|
|
||||||
for: 'vault-generic',
|
|
||||||
description: 'It indicates the credential mapping overrides.',
|
|
||||||
emptyObjectIfMissing: true,
|
|
||||||
})
|
|
||||||
credential_mapping_overrides;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'vault-ssh-certificate',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description: 'The username to use when making an SSH connection.',
|
|
||||||
})
|
|
||||||
username;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'vault-ssh-certificate',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description: 'The desired key type to use when generating a private key.',
|
|
||||||
})
|
|
||||||
key_type;
|
|
||||||
|
|
||||||
@attr('number', {
|
|
||||||
for: 'vault-ssh-certificate',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description:
|
|
||||||
'Specifies the number of bits used when generating the private key. Not used if key type is ed25519',
|
|
||||||
})
|
|
||||||
key_bits;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'vault-ssh-certificate',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description: 'Specifies the requested time to live for the certificate.',
|
|
||||||
})
|
|
||||||
ttl;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'vault-ssh-certificate',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description:
|
|
||||||
'Specifies the key id that the created certificate should have.',
|
|
||||||
})
|
|
||||||
key_id;
|
|
||||||
|
|
||||||
@attr('object-as-array', {
|
|
||||||
for: 'vault-ssh-certificate',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description:
|
|
||||||
'Specifies a map of the critical options that the certificate should be signed for.',
|
|
||||||
})
|
|
||||||
critical_options;
|
|
||||||
|
|
||||||
@attr('object-as-array', {
|
|
||||||
for: 'vault-ssh-certificate',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description:
|
|
||||||
'Specifies a map of the extensions that the certificate should be signed for.',
|
|
||||||
})
|
|
||||||
extensions;
|
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import BaseModel from '../../models/base';
|
import BaseModel from '../../models/base';
|
||||||
import { attr } from '@ember-data/model';
|
import { attr } from '@ember-data/model';
|
||||||
|
|
||||||
@@ -44,91 +39,4 @@ export default class GeneratedCredentialStoreModel extends BaseModel {
|
|||||||
description: 'Current version number of this resource.',
|
description: 'Current version number of this resource.',
|
||||||
})
|
})
|
||||||
version;
|
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,
|
|
||||||
isSecret: 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;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'vault',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description:
|
|
||||||
'Filters to the worker(s) who can handle Vault requests for this cred store.',
|
|
||||||
})
|
|
||||||
worker_filter;
|
|
||||||
}
|
}
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import BaseModel from '../../models/base';
|
|
||||||
import { attr } from '@ember-data/model';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A credential is a data structure containing one or more secrets that binds an
|
|
||||||
* identity to a set of permissions or capabilities on a host for a session.
|
|
||||||
*/
|
|
||||||
export default class GeneratedCredentialModel extends BaseModel {
|
|
||||||
// =attributes
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description:
|
|
||||||
'The ID of the Credential Store of which this Credential is a part.',
|
|
||||||
})
|
|
||||||
credential_store_id;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description: 'The type of the resource, to help differentiate schemas',
|
|
||||||
})
|
|
||||||
type;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description: 'Optional name for identification purposes',
|
|
||||||
})
|
|
||||||
name;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description: 'Optional user-set description for identification purposes',
|
|
||||||
})
|
|
||||||
description;
|
|
||||||
|
|
||||||
@attr('date', {
|
|
||||||
description: 'The time this resource was created\nOutput only.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
created_time;
|
|
||||||
|
|
||||||
@attr('date', {
|
|
||||||
description: 'The time this resource was last updated\nOutput only.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
updated_time;
|
|
||||||
|
|
||||||
@attr('number', {
|
|
||||||
description: 'Current version number of this resource.',
|
|
||||||
})
|
|
||||||
version;
|
|
||||||
|
|
||||||
// =attributes (username_password, ssh_private_key, username_password_domain)
|
|
||||||
@attr('string', {
|
|
||||||
for: ['username_password', 'ssh_private_key', 'username_password_domain'],
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description: 'The username for credential.',
|
|
||||||
})
|
|
||||||
username;
|
|
||||||
|
|
||||||
// =attributes (username_password, username_password_domain, password)
|
|
||||||
@attr('string', {
|
|
||||||
for: ['username_password', 'username_password_domain', 'password'],
|
|
||||||
isNestedAttribute: true,
|
|
||||||
isSecret: true,
|
|
||||||
description: 'The password for credential.',
|
|
||||||
})
|
|
||||||
password;
|
|
||||||
|
|
||||||
// =attributes (ssh_private_key)
|
|
||||||
@attr('string', {
|
|
||||||
for: 'ssh_private_key',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
isSecret: true,
|
|
||||||
description: 'The private key for credential.',
|
|
||||||
})
|
|
||||||
private_key;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'ssh_private_key',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
isSecret: true,
|
|
||||||
description: 'The private key passphrase for credential.',
|
|
||||||
})
|
|
||||||
private_key_passphrase;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'json',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
isSecret: true,
|
|
||||||
description: 'The secret associated with credential.',
|
|
||||||
})
|
|
||||||
json_object;
|
|
||||||
|
|
||||||
// =attributes (username_password_domain)
|
|
||||||
@attr('string', {
|
|
||||||
for: 'username_password_domain',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description: 'The domain for credential.',
|
|
||||||
})
|
|
||||||
domain;
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import BaseModel from '../../models/base';
|
import BaseModel from '../../models/base';
|
||||||
import { attr } from '@ember-data/model';
|
import { attr } from '@ember-data/model';
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import BaseModel from '../../models/base';
|
import BaseModel from '../../models/base';
|
||||||
import { attr } from '@ember-data/model';
|
import { attr } from '@ember-data/model';
|
||||||
|
|
||||||
@@ -55,224 +50,63 @@ export default class GeneratedHostCatalogModel extends BaseModel {
|
|||||||
})
|
})
|
||||||
plugin;
|
plugin;
|
||||||
|
|
||||||
// AWS, Azure & GCP
|
// AWS & Azure
|
||||||
|
|
||||||
@attr('boolean', {
|
@attr('boolean', {
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: ['aws', 'azure', 'gcp'],
|
|
||||||
},
|
|
||||||
isNestedAttribute: true,
|
isNestedAttribute: true,
|
||||||
description: '',
|
description: '',
|
||||||
})
|
})
|
||||||
disable_credential_rotation;
|
disable_credential_rotation;
|
||||||
|
|
||||||
// AWS and GCP specific
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: ['aws', 'azure', 'gcp'],
|
|
||||||
},
|
|
||||||
description:
|
|
||||||
'An expression used to filter the workers that have network access to a service that is hosting the external object store.',
|
|
||||||
})
|
|
||||||
worker_filter;
|
|
||||||
|
|
||||||
// AWS specific
|
// AWS specific
|
||||||
|
|
||||||
@attr('string', {
|
@attr('string', {
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: 'aws',
|
|
||||||
},
|
|
||||||
isNestedAttribute: true,
|
isNestedAttribute: true,
|
||||||
description: '',
|
description: '',
|
||||||
})
|
})
|
||||||
region;
|
region;
|
||||||
|
|
||||||
// AWS static credentials
|
|
||||||
@attr('string', {
|
@attr('string', {
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: 'aws',
|
|
||||||
credentialType: 'static-credential',
|
|
||||||
},
|
|
||||||
isNestedSecret: true,
|
isNestedSecret: true,
|
||||||
description: '',
|
description: '',
|
||||||
})
|
})
|
||||||
access_key_id;
|
access_key_id;
|
||||||
|
|
||||||
@attr('string', {
|
@attr('string', {
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: 'aws',
|
|
||||||
credentialType: 'static-credential',
|
|
||||||
},
|
|
||||||
isNestedSecret: true,
|
isNestedSecret: true,
|
||||||
description: '',
|
description: '',
|
||||||
})
|
})
|
||||||
secret_access_key;
|
secret_access_key;
|
||||||
|
|
||||||
// AWS dynamic credentials
|
|
||||||
@attr('string', {
|
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: 'aws',
|
|
||||||
credentialType: 'dynamic-credential',
|
|
||||||
},
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description: 'The role ARN to use.',
|
|
||||||
})
|
|
||||||
role_arn;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: 'aws',
|
|
||||||
credentialType: 'dynamic-credential',
|
|
||||||
},
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description: 'The role external ID to use.',
|
|
||||||
})
|
|
||||||
role_external_id;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: 'aws',
|
|
||||||
credentialType: 'dynamic-credential',
|
|
||||||
},
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description: 'The role session to use.',
|
|
||||||
})
|
|
||||||
role_session_name;
|
|
||||||
|
|
||||||
@attr('object-as-array', {
|
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: 'aws',
|
|
||||||
credentialType: 'dynamic-credential',
|
|
||||||
},
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description: 'The role tags to use.',
|
|
||||||
})
|
|
||||||
role_tags;
|
|
||||||
|
|
||||||
// Azure specific
|
// Azure specific
|
||||||
|
|
||||||
@attr('string', {
|
@attr('string', {
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: 'azure',
|
|
||||||
},
|
|
||||||
isNestedAttribute: true,
|
isNestedAttribute: true,
|
||||||
description: '',
|
description: '',
|
||||||
})
|
})
|
||||||
tenant_id;
|
tenant_id;
|
||||||
|
|
||||||
@attr('string', {
|
@attr('string', {
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: 'azure',
|
|
||||||
},
|
|
||||||
isNestedAttribute: true,
|
isNestedAttribute: true,
|
||||||
description: '',
|
description: '',
|
||||||
})
|
})
|
||||||
client_id;
|
client_id;
|
||||||
|
|
||||||
@attr('string', {
|
@attr('string', {
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: 'azure',
|
|
||||||
},
|
|
||||||
isNestedAttribute: true,
|
isNestedAttribute: true,
|
||||||
description: '',
|
description: '',
|
||||||
})
|
})
|
||||||
subscription_id;
|
subscription_id;
|
||||||
|
|
||||||
@attr('string', {
|
@attr('string', {
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: 'azure',
|
|
||||||
},
|
|
||||||
isNestedSecret: true,
|
isNestedSecret: true,
|
||||||
description: '',
|
description: '',
|
||||||
})
|
})
|
||||||
secret_id;
|
secret_id;
|
||||||
|
|
||||||
@attr('string', {
|
@attr('string', {
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: 'azure',
|
|
||||||
},
|
|
||||||
isNestedSecret: true,
|
isNestedSecret: true,
|
||||||
description: '',
|
description: '',
|
||||||
})
|
})
|
||||||
secret_value;
|
secret_value;
|
||||||
|
|
||||||
// GCP specific
|
|
||||||
@attr('string', {
|
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: 'gcp',
|
|
||||||
},
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description: 'The project ID associated with the service account.',
|
|
||||||
})
|
|
||||||
project_id;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: 'gcp',
|
|
||||||
},
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description: 'The deployment area within a region.',
|
|
||||||
})
|
|
||||||
zone;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: 'gcp',
|
|
||||||
},
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description:
|
|
||||||
'The email address associated with the service account. The email address used to uniquely identify the service account. It is required for authentication and authorization.',
|
|
||||||
})
|
|
||||||
client_email;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: 'gcp',
|
|
||||||
},
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description:
|
|
||||||
'The unique identifier for the service account that will be impersonated.',
|
|
||||||
})
|
|
||||||
target_service_account_id;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: 'gcp',
|
|
||||||
},
|
|
||||||
description:
|
|
||||||
'The ID of the private key used to sign the JWT and authentication.',
|
|
||||||
isNestedSecret: true,
|
|
||||||
})
|
|
||||||
private_key_id;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: 'gcp',
|
|
||||||
},
|
|
||||||
description:
|
|
||||||
'The private key used to sign the JWT and obtain a OAuth 2.0 access token.',
|
|
||||||
isNestedSecret: true,
|
|
||||||
})
|
|
||||||
private_key;
|
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import BaseModel from '../../models/base';
|
import BaseModel from '../../models/base';
|
||||||
import { attr } from '@ember-data/model';
|
import { attr } from '@ember-data/model';
|
||||||
|
|
||||||
@@ -63,54 +58,15 @@ export default class GeneratedHostSetModel extends BaseModel {
|
|||||||
plugin;
|
plugin;
|
||||||
|
|
||||||
@attr('number', {
|
@attr('number', {
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: ['aws', 'azure', 'gcp'],
|
|
||||||
},
|
|
||||||
description:
|
description:
|
||||||
"The number of seconds between the time boundary syncs the hosts in this set using this host set's plugin. If not provided a system determined default is used",
|
"The number of seconds between the time boundary syncs the hosts in this set using this host set's plugin. If not provided a system determined default is used",
|
||||||
})
|
})
|
||||||
sync_interval_seconds;
|
sync_interval_seconds;
|
||||||
|
|
||||||
/**
|
// Azure specific
|
||||||
* Host IDs are read-only under normal circumstances. But these can
|
|
||||||
* be persisted via a dedicated call to `addHosts()`.
|
|
||||||
*/
|
|
||||||
@attr({
|
|
||||||
readOnly: true,
|
|
||||||
emptyArrayIfMissing: true,
|
|
||||||
})
|
|
||||||
host_ids;
|
|
||||||
|
|
||||||
@attr('string-array', {
|
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: ['aws', 'azure', 'gcp'],
|
|
||||||
},
|
|
||||||
emptyArrayIfMissing: true,
|
|
||||||
trimWhitespace: true,
|
|
||||||
})
|
|
||||||
preferred_endpoints;
|
|
||||||
|
|
||||||
// AWS & GCP specific
|
|
||||||
@attr('string-array', {
|
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: ['aws', 'gcp'],
|
|
||||||
},
|
|
||||||
isNestedAttribute: true,
|
|
||||||
emptyArrayIfMissing: true,
|
|
||||||
})
|
|
||||||
filters;
|
|
||||||
|
|
||||||
// Azure specific, comes in from API as "filter". This is to avoid collisions with filter
|
|
||||||
@attr('string', {
|
@attr('string', {
|
||||||
for: {
|
|
||||||
type: 'plugin',
|
|
||||||
name: 'azure',
|
|
||||||
},
|
|
||||||
description: '',
|
description: '',
|
||||||
isNestedAttribute: true,
|
isNestedAttribute: true,
|
||||||
})
|
})
|
||||||
filter_string;
|
filter;
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import BaseModel from '../../models/base';
|
import BaseModel from '../../models/base';
|
||||||
import { attr } from '@ember-data/model';
|
import { attr } from '@ember-data/model';
|
||||||
|
|
||||||
@@ -54,10 +49,4 @@ export default class GeneratedHostModel extends BaseModel {
|
|||||||
readOnly: true,
|
readOnly: true,
|
||||||
})
|
})
|
||||||
plugin;
|
plugin;
|
||||||
|
|
||||||
@attr({
|
|
||||||
emptyArrayIfMissing: true,
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
host_set_ids;
|
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import BaseModel from '../../models/base';
|
import BaseModel from '../../models/base';
|
||||||
import { attr } from '@ember-data/model';
|
import { attr } from '@ember-data/model';
|
||||||
|
|
||||||
@@ -49,23 +44,4 @@ export default class GeneratedManagedGroupModel extends BaseModel {
|
|||||||
'The ID of the Auth Method that is associated with this ManagedGroup',
|
'The ID of the Auth Method that is associated with this ManagedGroup',
|
||||||
})
|
})
|
||||||
auth_method_id;
|
auth_method_id;
|
||||||
|
|
||||||
// =attributes (OIDC)
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
for: 'oidc',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description:
|
|
||||||
'The boolean expression filter to use to determine membership. Comes in from API as "filter".',
|
|
||||||
})
|
|
||||||
filter_string;
|
|
||||||
|
|
||||||
// =attributes (LDAP)
|
|
||||||
|
|
||||||
@attr('string-array', {
|
|
||||||
for: 'ldap',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description: 'The list of groups that make up the ManagedGroup',
|
|
||||||
})
|
|
||||||
group_names;
|
|
||||||
}
|
}
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import BaseModel from '../../models/base';
|
|
||||||
import { attr } from '@ember-data/model';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Storage Policy is a resource that manages the lifecycle of Session Recordings,
|
|
||||||
* particularly to meet compliance frameworks.
|
|
||||||
*/
|
|
||||||
export default class GeneratedPolicyModel extends BaseModel {
|
|
||||||
// =attributes
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description: 'The type of the resource, to help differentiate schemas',
|
|
||||||
})
|
|
||||||
type;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description: 'Optional name for identification purposes.',
|
|
||||||
})
|
|
||||||
name;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description: 'Optional user-set description for identification purposes.',
|
|
||||||
})
|
|
||||||
description;
|
|
||||||
|
|
||||||
@attr('date', {
|
|
||||||
description: 'The time this resource was created\nOutput only.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
created_time;
|
|
||||||
|
|
||||||
@attr('date', {
|
|
||||||
description: 'The time this resource was last updated\nOutput only.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
updated_time;
|
|
||||||
|
|
||||||
@attr('number', {
|
|
||||||
description: 'Current version number of this resource.',
|
|
||||||
})
|
|
||||||
version;
|
|
||||||
|
|
||||||
@attr('object', {
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description:
|
|
||||||
'Days is the number of days for which a session recording will be retained.',
|
|
||||||
})
|
|
||||||
retain_for;
|
|
||||||
|
|
||||||
@attr('object', {
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description:
|
|
||||||
'Days is the number of days for which a session recording will be automatically deleted.',
|
|
||||||
})
|
|
||||||
delete_after;
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import BaseModel from '../../models/base';
|
import BaseModel from '../../models/base';
|
||||||
import { attr } from '@ember-data/model';
|
import { attr } from '@ember-data/model';
|
||||||
|
|
||||||
@@ -22,12 +17,11 @@ export default class GeneratedRoleModel extends BaseModel {
|
|||||||
})
|
})
|
||||||
description;
|
description;
|
||||||
|
|
||||||
@attr('array', {
|
@attr('string', {
|
||||||
emptyArrayIfMissing: true,
|
|
||||||
description:
|
description:
|
||||||
"The scopes to which this role applies. Defaults to the role's scope.",
|
"The scope to which this role applies. Defaults to the role's scope.",
|
||||||
})
|
})
|
||||||
grant_scope_ids;
|
grant_scope_id;
|
||||||
|
|
||||||
@attr('date', {
|
@attr('date', {
|
||||||
description: 'The time this resource was created\nOutput only.',
|
description: 'The time this resource was created\nOutput only.',
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import BaseModel from '../../models/base';
|
import BaseModel from '../../models/base';
|
||||||
import { attr } from '@ember-data/model';
|
import { attr } from '@ember-data/model';
|
||||||
|
|
||||||
@@ -49,9 +44,4 @@ export default class GeneratedScopeModel extends BaseModel {
|
|||||||
description: 'Current version number of this resource.',
|
description: 'Current version number of this resource.',
|
||||||
})
|
})
|
||||||
version;
|
version;
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description: 'The ID of the associated storage policy',
|
|
||||||
})
|
|
||||||
storage_policy_id;
|
|
||||||
}
|
}
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import BaseModel from '../../models/base';
|
|
||||||
import { attr } from '@ember-data/model';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A session recording contains all data related to session recordings
|
|
||||||
*/
|
|
||||||
export default class GeneratedSessionRecordingModel extends BaseModel {
|
|
||||||
// =attributes
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description: 'The type of the resource, to help differentiate schemas.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
type;
|
|
||||||
|
|
||||||
@attr('date', {
|
|
||||||
description:
|
|
||||||
'The time the Session Recording was created in the controller.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
created_time;
|
|
||||||
|
|
||||||
@attr('date', {
|
|
||||||
description: 'The time of the most recent update to the Session Recording.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
updated_time;
|
|
||||||
|
|
||||||
@attr({
|
|
||||||
description:
|
|
||||||
'Contains the values of related fields at the time this Session Recording was created',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
create_time_values;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description: 'The ID of the Session which this Session Recording recorded.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
session_id;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description:
|
|
||||||
'The ID of the Storage Bucket for the Target of this Session Recording',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
storage_bucket_id;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description:
|
|
||||||
'The total number of bytes uploaded from the client in the Session.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
bytes_up;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description:
|
|
||||||
'The total number of bytes downloaded to the client in the Session.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
bytes_down;
|
|
||||||
|
|
||||||
@attr('number', {
|
|
||||||
description:
|
|
||||||
'The total number of errors that occurred during the use of the Session.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
errors_number;
|
|
||||||
|
|
||||||
@attr('date', {
|
|
||||||
description: 'The time the Session started.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
start_time;
|
|
||||||
|
|
||||||
@attr('date', {
|
|
||||||
description: 'The time the Session finished.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
end_time;
|
|
||||||
|
|
||||||
@attr({
|
|
||||||
description: 'The array of mime types that this recording will support.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
mime_types;
|
|
||||||
|
|
||||||
@attr('duration', {
|
|
||||||
description: 'The duration of this session recording in ms.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
duration;
|
|
||||||
|
|
||||||
@attr({
|
|
||||||
description:
|
|
||||||
'The detailed state of the session recording. This contains storage_state, syncing_error_details, and verification_error_details.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
recording_state;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description:
|
|
||||||
'The availability of the session recording. One of "available" or "not available".',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
availability;
|
|
||||||
|
|
||||||
@attr('date', {
|
|
||||||
description: 'The time until a session recording is required to be stored.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
retain_until;
|
|
||||||
|
|
||||||
@attr('date', {
|
|
||||||
description:
|
|
||||||
'The time a session recording is scheduled to be automatically deleted.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
delete_after;
|
|
||||||
|
|
||||||
// Deprecated: These two fields should be removed once support for RDP is added.
|
|
||||||
@attr('string', {
|
|
||||||
description:
|
|
||||||
'The current state of the session recording. One of "started", "available" and "unknown".',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
state;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description:
|
|
||||||
'Any error seen during the closing of the session recording. Currently only set if state is "unknown".',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
error_details;
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import BaseModel from '../../models/base';
|
import BaseModel from '../../models/base';
|
||||||
import { attr } from '@ember-data/model';
|
import { attr } from '@ember-data/model';
|
||||||
|
|
||||||
@@ -32,13 +27,6 @@ export default class GeneratedSessionModel extends BaseModel {
|
|||||||
})
|
})
|
||||||
updated_time;
|
updated_time;
|
||||||
|
|
||||||
@attr('date', {
|
|
||||||
description:
|
|
||||||
'After this time the connection will be expired, e.g. forcefully terminated.\nOutput only.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
expiration_time;
|
|
||||||
|
|
||||||
@attr('number', {
|
@attr('number', {
|
||||||
description: 'Current version number of this resource.',
|
description: 'Current version number of this resource.',
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,134 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import BaseModel from '../../models/base';
|
|
||||||
import { attr } from '@ember-data/model';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A storage bucket is a resource that that represents a bucket in an external object store.
|
|
||||||
*/
|
|
||||||
export default class GeneratedStorageBucketModel extends BaseModel {
|
|
||||||
// =attributes
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description: 'The type of the resource, to help differentiate schemas',
|
|
||||||
})
|
|
||||||
type;
|
|
||||||
|
|
||||||
@attr({
|
|
||||||
description: 'Plugin information for this resource.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
plugin;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description: 'Optional name for identification purposes.',
|
|
||||||
})
|
|
||||||
name;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description: 'Optional user-set description for identification purposes.',
|
|
||||||
})
|
|
||||||
description;
|
|
||||||
|
|
||||||
@attr('date', {
|
|
||||||
description: 'The time this resource was created\nOutput only.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
created_time;
|
|
||||||
|
|
||||||
@attr('date', {
|
|
||||||
description: 'The time this resource was last updated\nOutput only.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
updated_time;
|
|
||||||
|
|
||||||
@attr('number', {
|
|
||||||
description: 'Current version number of this resource.',
|
|
||||||
})
|
|
||||||
version;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description: 'The name of the bucket in the external object store.',
|
|
||||||
})
|
|
||||||
bucket_name;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description:
|
|
||||||
'The base path where session recordings will be stored in the external object store.',
|
|
||||||
})
|
|
||||||
bucket_prefix;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description:
|
|
||||||
'An expression used to filter the workers that have network access to a service that is hosting the external object store.',
|
|
||||||
})
|
|
||||||
worker_filter;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description: 'The AWS region to use.',
|
|
||||||
trimWhitespace: true,
|
|
||||||
})
|
|
||||||
region;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description: 'The MinIO location server.',
|
|
||||||
})
|
|
||||||
endpoint_url;
|
|
||||||
|
|
||||||
//this field is not used in the UI, but this is kept here to replicate the API
|
|
||||||
@attr('string', {
|
|
||||||
readOnly: true,
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
secrets_hmac;
|
|
||||||
|
|
||||||
@attr('boolean', {
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description: 'If set to `true`, credential rotation is not performed.',
|
|
||||||
})
|
|
||||||
disable_credential_rotation;
|
|
||||||
|
|
||||||
// =attributes (static credentials)
|
|
||||||
@attr('string', {
|
|
||||||
isNestedSecret: true,
|
|
||||||
description: 'The AWS access key ID to use.',
|
|
||||||
})
|
|
||||||
access_key_id;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
isNestedSecret: true,
|
|
||||||
description: 'The secret access key to use.',
|
|
||||||
})
|
|
||||||
secret_access_key;
|
|
||||||
|
|
||||||
// =attributes (dynamic credentials)
|
|
||||||
@attr('string', {
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description: 'The role ARN to use.',
|
|
||||||
trimWhitespace: true,
|
|
||||||
})
|
|
||||||
role_arn;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description: 'The role external ID to use.',
|
|
||||||
})
|
|
||||||
role_external_id;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description: 'The role session to use.',
|
|
||||||
})
|
|
||||||
role_session_name;
|
|
||||||
|
|
||||||
@attr('object-as-array', {
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description: 'The role tags to use.',
|
|
||||||
})
|
|
||||||
role_tags;
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import BaseModel from '../../models/base';
|
import BaseModel from '../../models/base';
|
||||||
import { attr } from '@ember-data/model';
|
import { attr } from '@ember-data/model';
|
||||||
|
|
||||||
@@ -35,21 +30,10 @@ export default class GeneratedTargetModel extends BaseModel {
|
|||||||
|
|
||||||
@attr('number', {
|
@attr('number', {
|
||||||
description: '',
|
description: '',
|
||||||
|
defaultValue: 1,
|
||||||
})
|
})
|
||||||
session_connection_limit;
|
session_connection_limit;
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description:
|
|
||||||
'Optional boolean expressions to filter the egress workers that are allowed to satisfy this request.',
|
|
||||||
})
|
|
||||||
egress_worker_filter;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description:
|
|
||||||
'Optional boolean expressions to filter the ingress workers that are allowed to satisfy this request.',
|
|
||||||
})
|
|
||||||
ingress_worker_filter;
|
|
||||||
|
|
||||||
@attr('date', {
|
@attr('date', {
|
||||||
description: 'The time this resource was created\nOutput only.',
|
description: 'The time this resource was created\nOutput only.',
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
@@ -71,48 +55,4 @@ export default class GeneratedTargetModel extends BaseModel {
|
|||||||
description: 'Current version number of this resource.',
|
description: 'Current version number of this resource.',
|
||||||
})
|
})
|
||||||
version;
|
version;
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description:
|
|
||||||
'An IP address or DNS name for the session to connect to. Cannot be used in conjunction with host sources.',
|
|
||||||
})
|
|
||||||
address;
|
|
||||||
|
|
||||||
@attr('number', {
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description: 'The default port a target should use if present.',
|
|
||||||
})
|
|
||||||
default_port;
|
|
||||||
|
|
||||||
@attr('number', {
|
|
||||||
isNestedAttribute: true,
|
|
||||||
description:
|
|
||||||
"The default port that will be listened on by the client's local proxy.",
|
|
||||||
})
|
|
||||||
default_client_port;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description: 'The storage bucket associated with this target.',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
storage_bucket_id;
|
|
||||||
|
|
||||||
@attr('boolean', {
|
|
||||||
description: 'Whether session recording is enabled on the target.',
|
|
||||||
isNestedAttribute: true,
|
|
||||||
})
|
|
||||||
enable_session_recording;
|
|
||||||
|
|
||||||
@attr('array', {
|
|
||||||
description:
|
|
||||||
'with_aliases specify the aliases that should be created when the target is created. ',
|
|
||||||
})
|
|
||||||
with_aliases;
|
|
||||||
|
|
||||||
@attr('array', {
|
|
||||||
readOnly: true,
|
|
||||||
description:
|
|
||||||
'with_aliases specify the aliases that should be created when the target is created. ',
|
|
||||||
})
|
|
||||||
aliases;
|
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import BaseModel from '../../models/base';
|
import BaseModel from '../../models/base';
|
||||||
import { attr } from '@ember-data/model';
|
import { attr } from '@ember-data/model';
|
||||||
|
|
||||||
|
|||||||
@@ -1,98 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import BaseModel from '../../models/base';
|
|
||||||
import { attr } from '@ember-data/model';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Worker contains all fields related to a worker resource
|
|
||||||
*/
|
|
||||||
export default class GeneratedWorkerModel extends BaseModel {
|
|
||||||
// =attributes
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description: 'Optional name for identification purposes.',
|
|
||||||
})
|
|
||||||
name;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description: 'Optional user-set description for identification purposes.',
|
|
||||||
})
|
|
||||||
description;
|
|
||||||
|
|
||||||
@attr('date', {
|
|
||||||
description: 'The time this resource was created\nOutput only.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
created_time;
|
|
||||||
|
|
||||||
@attr('date', {
|
|
||||||
description: 'The time this resource was last updated\nOutput only.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
updated_time;
|
|
||||||
|
|
||||||
@attr('number', {
|
|
||||||
description: 'Current version number of this resource.',
|
|
||||||
})
|
|
||||||
version;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description: 'The address that this worker is reachable at.\nOutput only.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
address;
|
|
||||||
|
|
||||||
@attr('date', {
|
|
||||||
description:
|
|
||||||
'The time this worker was last reported its status.\nOutput only.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
last_status_time;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description:
|
|
||||||
'The version of the Boundary binary the worker is running.\nOutput only.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
release_version;
|
|
||||||
|
|
||||||
@attr('number', {
|
|
||||||
description:
|
|
||||||
'The number of connections that this worker is currently handling.\nOutput only.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
active_connection_count;
|
|
||||||
|
|
||||||
@attr('string', {
|
|
||||||
description:
|
|
||||||
'The type of the worker, denoted by how it authenticates: pki or kms.\nOutput only.',
|
|
||||||
readOnly: true,
|
|
||||||
})
|
|
||||||
type;
|
|
||||||
|
|
||||||
@attr({
|
|
||||||
description:
|
|
||||||
'The deduplicated union of the tags reported by the worker ' +
|
|
||||||
'from its configuration and any tags added through other means.\nOutput only.',
|
|
||||||
readOnly: true,
|
|
||||||
emptyObjectIfMissing: true,
|
|
||||||
})
|
|
||||||
canonical_tags;
|
|
||||||
|
|
||||||
@attr({
|
|
||||||
description:
|
|
||||||
"The tags set in the worker's configuration file.\nOutput only.",
|
|
||||||
readOnly: true,
|
|
||||||
emptyObjectIfMissing: true,
|
|
||||||
})
|
|
||||||
config_tags;
|
|
||||||
|
|
||||||
@attr({
|
|
||||||
description: 'The api tags set for the worker.\nOutput only.',
|
|
||||||
emptyObjectIfMissing: true,
|
|
||||||
})
|
|
||||||
api_tags;
|
|
||||||
}
|
|
||||||
@@ -1,192 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { service } from '@ember/service';
|
|
||||||
import { getOwner, setOwner } from '@ember/application';
|
|
||||||
import { generateMQLExpression } from '../utils/mql-query';
|
|
||||||
import { paginateResults } from '../utils/paginate-results';
|
|
||||||
import { underscore } from '@ember/string';
|
|
||||||
|
|
||||||
const { __electronLog } = globalThis;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Not all types are yet supported by the cache daemon so we'll
|
|
||||||
* just whitelist the ones we need to start with. Keys are the resource
|
|
||||||
* types and the values are the fields that are searchable by the client.
|
|
||||||
* @type {{session: string[], alias: string[], target: string[]}}
|
|
||||||
*/
|
|
||||||
const supportedTypes = {
|
|
||||||
target: ['id', 'name', 'description', 'address', 'scope_id'],
|
|
||||||
session: ['id', 'type', 'status', 'endpoint', 'scope_id', 'target_id'],
|
|
||||||
alias: ['id', 'type', 'value', 'destination_id'],
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Map the model resource name to the cache daemon resource name
|
|
||||||
* @type {{session: string, alias: string, target: string}}
|
|
||||||
*/
|
|
||||||
export const resourceNames = {
|
|
||||||
target: 'targets',
|
|
||||||
session: 'sessions',
|
|
||||||
alias: 'resolvable-aliases',
|
|
||||||
};
|
|
||||||
|
|
||||||
const fetchControllerData = async (context, next) => {
|
|
||||||
const { data } = context.request;
|
|
||||||
const { query: originalQuery } = data;
|
|
||||||
// remove cache daemon specific query params
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
const { query, page, pageSize, ...remainingQuery } = originalQuery;
|
|
||||||
|
|
||||||
// If we get an error or cache daemon is unavailable, fall back to calling the API
|
|
||||||
context.request.data.query = remainingQuery;
|
|
||||||
const results = await next(context.request);
|
|
||||||
|
|
||||||
// As a result of https://rfcs.emberjs.com/id/0846-ember-data-deprecate-proxies/ we cannot use proxy array methods like .toArray
|
|
||||||
// use slice() instead as indicated in the RFC.
|
|
||||||
const models = results.content.slice();
|
|
||||||
|
|
||||||
const paginatedResult = paginateResults(models, page, pageSize);
|
|
||||||
paginatedResult.meta = { totalItems: models.length };
|
|
||||||
return paginatedResult;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler to sit in front of the API request layer
|
|
||||||
* so we can request from the daemon first
|
|
||||||
*/
|
|
||||||
export default class CacheDaemonHandler {
|
|
||||||
@service session;
|
|
||||||
|
|
||||||
constructor(context) {
|
|
||||||
setOwner(this, getOwner(context));
|
|
||||||
}
|
|
||||||
|
|
||||||
async request(context, next) {
|
|
||||||
switch (context.request.op) {
|
|
||||||
case 'query': {
|
|
||||||
const { store, data } = context.request;
|
|
||||||
const { type, query, options: { pushToStore = true } = {} } = data;
|
|
||||||
const isCacheDaemonRunning =
|
|
||||||
await window.desktop.daemon.isCacheDaemonRunning();
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
let { recursive, scope_id, page, pageSize, ...remainingQuery } = query;
|
|
||||||
let searchQuery = '';
|
|
||||||
|
|
||||||
if (
|
|
||||||
!Object.keys(supportedTypes).includes(type) ||
|
|
||||||
!isCacheDaemonRunning
|
|
||||||
) {
|
|
||||||
return fetchControllerData(context, next);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (remainingQuery.query) {
|
|
||||||
const { search, filters } = remainingQuery.query;
|
|
||||||
|
|
||||||
searchQuery = generateMQLExpression({
|
|
||||||
search: {
|
|
||||||
text: search,
|
|
||||||
fields: supportedTypes[type],
|
|
||||||
},
|
|
||||||
filters,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const sessionData = this.session.data?.authenticated;
|
|
||||||
const auth_token_id = sessionData?.id;
|
|
||||||
const token = sessionData?.token;
|
|
||||||
const resourceName = resourceNames[type];
|
|
||||||
|
|
||||||
if (remainingQuery.query?.sort) {
|
|
||||||
const { attribute, direction } = remainingQuery.query.sort;
|
|
||||||
if (attribute && direction) {
|
|
||||||
remainingQuery.sort_by = attribute;
|
|
||||||
remainingQuery.sort_direction = direction;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
remainingQuery = {
|
|
||||||
...remainingQuery,
|
|
||||||
query: searchQuery,
|
|
||||||
auth_token_id,
|
|
||||||
token,
|
|
||||||
resource: resourceName,
|
|
||||||
};
|
|
||||||
|
|
||||||
let cacheDaemonResults = {};
|
|
||||||
try {
|
|
||||||
cacheDaemonResults =
|
|
||||||
await window.desktop.daemon.searchCacheDaemon(remainingQuery);
|
|
||||||
} catch (e) {
|
|
||||||
// If we got a 403, most likely the cache daemon was restarted and our token is no longer valid
|
|
||||||
// I'm not sure if we can get a 401 since we always send a token but we'll handle it in the same way
|
|
||||||
if (e.statusCode === 403 || e.statusCode === 401) {
|
|
||||||
try {
|
|
||||||
await window.desktop.daemon.addTokenToDaemons({
|
|
||||||
tokenId: auth_token_id,
|
|
||||||
token,
|
|
||||||
});
|
|
||||||
cacheDaemonResults =
|
|
||||||
await window.desktop.daemon.searchCacheDaemon(remainingQuery);
|
|
||||||
} catch (err) {
|
|
||||||
// If it fails again just fall back to fetching controller data
|
|
||||||
__electronLog?.error(
|
|
||||||
'Failed to add token to daemons',
|
|
||||||
err.message,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
__electronLog?.error(
|
|
||||||
`Failed to search cache daemon for ${resourceName}. Error:`,
|
|
||||||
e.message,
|
|
||||||
);
|
|
||||||
|
|
||||||
return fetchControllerData(context, next);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const results = cacheDaemonResults[underscore(resourceName)];
|
|
||||||
const payload = { items: paginateResults(results, page, pageSize) };
|
|
||||||
|
|
||||||
const schema = store.modelFor(type);
|
|
||||||
const serializer = store.serializerFor(type);
|
|
||||||
const normalizedPayload = serializer.normalizeResponse(
|
|
||||||
store,
|
|
||||||
schema,
|
|
||||||
payload,
|
|
||||||
null,
|
|
||||||
'query',
|
|
||||||
);
|
|
||||||
|
|
||||||
// Return the raw data if we don't push to the store.
|
|
||||||
let records = normalizedPayload.data.map((record) => ({
|
|
||||||
...record.attributes,
|
|
||||||
id: record.id,
|
|
||||||
}));
|
|
||||||
if (pushToStore) {
|
|
||||||
records = store.push(normalizedPayload);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set a meta property on the array to store the total items of the results.
|
|
||||||
// This isn't conventional but is better than returning an ArrayProxy
|
|
||||||
// or EmberArray since the ember store query method asserts it has to be an array
|
|
||||||
// so we can't just return an object.
|
|
||||||
// Also include whether the results are incomplete or is still refreshing
|
|
||||||
// as part of the response
|
|
||||||
records.meta = {
|
|
||||||
totalItems: results?.length ?? 0,
|
|
||||||
isLoadIncomplete: cacheDaemonResults.incomplete ?? false,
|
|
||||||
// Sometimes the refresh status returns an error status if it takes too long but it's still refreshing
|
|
||||||
isCacheRefreshing:
|
|
||||||
cacheDaemonResults.refresh_status !== 'not-refreshing',
|
|
||||||
};
|
|
||||||
|
|
||||||
return records;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return next(context.request);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,308 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { getOwner, setOwner } from '@ember/owner';
|
|
||||||
import { service } from '@ember/service';
|
|
||||||
import { modelMapping } from 'api/services/sqlite';
|
|
||||||
import { get } from '@ember/object';
|
|
||||||
import { typeOf } from '@ember/utils';
|
|
||||||
import { hashCode } from '../utils/hash-code';
|
|
||||||
import { generateSQLExpressions } from '../utils/sqlite-query';
|
|
||||||
|
|
||||||
const isISODateString = (str) =>
|
|
||||||
typeOf(str) === 'string' &&
|
|
||||||
/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z?$/.test(str);
|
|
||||||
|
|
||||||
export default class SqliteHandler {
|
|
||||||
@service sqlite;
|
|
||||||
|
|
||||||
batchLimit = 5_000;
|
|
||||||
|
|
||||||
constructor(context) {
|
|
||||||
setOwner(this, getOwner(context));
|
|
||||||
}
|
|
||||||
|
|
||||||
async request(context, next) {
|
|
||||||
switch (context.request.op) {
|
|
||||||
case 'query': {
|
|
||||||
const { store, data } = context.request;
|
|
||||||
const {
|
|
||||||
type,
|
|
||||||
query,
|
|
||||||
options: {
|
|
||||||
pushToStore = true,
|
|
||||||
peekDb = false,
|
|
||||||
storeToken = true,
|
|
||||||
} = {},
|
|
||||||
} = data;
|
|
||||||
const supportedModels = Object.keys(modelMapping);
|
|
||||||
|
|
||||||
// Go through normal flow if we don't yet support the model
|
|
||||||
// or if we don't have a sqlite db instance
|
|
||||||
if (!supportedModels.includes(type) || !this.sqlite.worker) {
|
|
||||||
return next(context.request);
|
|
||||||
}
|
|
||||||
|
|
||||||
const adapter = store.adapterFor(type);
|
|
||||||
const schema = store.modelFor(type);
|
|
||||||
const serializer = store.serializerFor(type);
|
|
||||||
|
|
||||||
let {
|
|
||||||
page,
|
|
||||||
pageSize,
|
|
||||||
select,
|
|
||||||
query: queryObj,
|
|
||||||
...remainingQuery
|
|
||||||
} = query;
|
|
||||||
let payload,
|
|
||||||
listToken,
|
|
||||||
writeToDbPromise,
|
|
||||||
totalInsert = 0,
|
|
||||||
rateLimitWarning;
|
|
||||||
|
|
||||||
if (!peekDb) {
|
|
||||||
let tokenKey = `${type}-${hashCode(remainingQuery)}`;
|
|
||||||
// The global token key represents a recursive query from global scope,
|
|
||||||
// which pulls back every resource of this type.
|
|
||||||
const globalTokenKey = `${type}-${hashCode({ scope_id: 'global', recursive: true })}`;
|
|
||||||
if (storeToken) {
|
|
||||||
// Always prefer the global token when it exists for
|
|
||||||
// any more fine-grained query. The global query already fetched every
|
|
||||||
// item for this resource type, so we should just re-use it.
|
|
||||||
if (tokenKey !== globalTokenKey) {
|
|
||||||
const [globalTokenObj] = await this.sqlite.fetchResource({
|
|
||||||
...generateSQLExpressions('token', {
|
|
||||||
filters: { id: [{ equals: globalTokenKey }] },
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
if (globalTokenObj?.token) {
|
|
||||||
tokenKey = globalTokenKey;
|
|
||||||
listToken = globalTokenObj.token;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only look up the specific token if no global token was found.
|
|
||||||
if (!listToken) {
|
|
||||||
const [tokenObj] = await this.sqlite.fetchResource({
|
|
||||||
...generateSQLExpressions('token', {
|
|
||||||
filters: { id: [{ equals: tokenKey }] },
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
listToken = tokenObj?.token;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// This is a temporary fix of clearing the DB (specifically for auth-methods)
|
|
||||||
// since we are not storing the token we do not get back a list of removed_ids
|
|
||||||
// from the API call and we do not want deleted items from showing in list view.
|
|
||||||
await this.sqlite.deleteResource(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
try {
|
|
||||||
payload = await adapter.query(store, schema, {
|
|
||||||
...remainingQuery,
|
|
||||||
list_token: listToken,
|
|
||||||
batchLimit: this.batchLimit,
|
|
||||||
});
|
|
||||||
totalInsert += payload.items?.length ?? 0;
|
|
||||||
|
|
||||||
// Propagate any rate-limit warning the adapter attached
|
|
||||||
if (payload.meta?.rateLimitWarning) {
|
|
||||||
rateLimitWarning = payload.meta.rateLimitWarning;
|
|
||||||
}
|
|
||||||
|
|
||||||
// await the previous writeToDbPromise before writing to db again
|
|
||||||
if (writeToDbPromise) {
|
|
||||||
await writeToDbPromise;
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
payload = await this.retryQueryFailure({
|
|
||||||
err,
|
|
||||||
type,
|
|
||||||
adapter,
|
|
||||||
store,
|
|
||||||
schema,
|
|
||||||
remainingQuery,
|
|
||||||
});
|
|
||||||
totalInsert += payload.items?.length ?? 0;
|
|
||||||
}
|
|
||||||
listToken = payload.list_token;
|
|
||||||
|
|
||||||
writeToDbPromise = this.writeToDb(
|
|
||||||
payload,
|
|
||||||
storeToken,
|
|
||||||
tokenKey,
|
|
||||||
pushToStore,
|
|
||||||
serializer,
|
|
||||||
store,
|
|
||||||
schema,
|
|
||||||
type,
|
|
||||||
);
|
|
||||||
} while (payload.response_type === 'delta');
|
|
||||||
|
|
||||||
await writeToDbPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (totalInsert > 0) {
|
|
||||||
// If there were any inserts, let sqlite handle running analyze on the DB
|
|
||||||
await this.sqlite.analyzeDatabase();
|
|
||||||
}
|
|
||||||
|
|
||||||
const { sql, parameters } = generateSQLExpressions(type, queryObj, {
|
|
||||||
page,
|
|
||||||
pageSize,
|
|
||||||
select: select ?? [{ field: 'data' }],
|
|
||||||
});
|
|
||||||
|
|
||||||
const rows = await this.sqlite.fetchResource({
|
|
||||||
sql,
|
|
||||||
parameters,
|
|
||||||
});
|
|
||||||
|
|
||||||
const { sql: countSql, parameters: countParams } =
|
|
||||||
generateSQLExpressions(type, queryObj, {
|
|
||||||
select: [{ field: '*', isCount: true, alias: 'total' }],
|
|
||||||
});
|
|
||||||
const count = await this.sqlite.fetchResource({
|
|
||||||
sql: countSql,
|
|
||||||
parameters: countParams,
|
|
||||||
});
|
|
||||||
|
|
||||||
const results = rows.map((item) =>
|
|
||||||
JSON.parse(item.data, (key, value) =>
|
|
||||||
// Reviver function to convert any ISO strings back to date objects
|
|
||||||
// as we had to initially convert them to strings when stored in SQLite
|
|
||||||
isISODateString(value) ? new Date(value) : value,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
// If we are not pushing to the store, use the raw data with id property
|
|
||||||
const records = pushToStore
|
|
||||||
? store.push({ data: results })
|
|
||||||
: results.map((record) => ({
|
|
||||||
...record.attributes,
|
|
||||||
id: record.id,
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Set a meta property on the array to store the total items of the results.
|
|
||||||
// This isn't conventional but is better than returning an ArrayProxy
|
|
||||||
// or EmberArray since the ember store query method asserts it has to be an array
|
|
||||||
// so we can't just return an object.
|
|
||||||
records.meta = {
|
|
||||||
totalItems: count[0].total,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (rateLimitWarning) {
|
|
||||||
records.meta.rateLimitWarning = rateLimitWarning;
|
|
||||||
}
|
|
||||||
|
|
||||||
return records;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return next(context.request);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async retryQueryFailure({
|
|
||||||
err,
|
|
||||||
type,
|
|
||||||
adapter,
|
|
||||||
store,
|
|
||||||
schema,
|
|
||||||
remainingQuery,
|
|
||||||
}) {
|
|
||||||
// If we get an invalid list token, we'll delete the token and
|
|
||||||
// clear the DB and try again without a token.
|
|
||||||
if (
|
|
||||||
err?.errors?.[0].status === 400 &&
|
|
||||||
err?.errors?.[0].code === 'invalid list token'
|
|
||||||
) {
|
|
||||||
await this.sqlite.deleteResource(type);
|
|
||||||
// Delete all tokens of the same resource type so we don't keep clearing the DB.
|
|
||||||
// Even if other tokens may still be valid, we might have cleared data that they
|
|
||||||
// depended on so we should clear all tokens of the same type when clearing the DB.
|
|
||||||
const { sql, parameters } = generateSQLExpressions('token', {
|
|
||||||
filters: { id: [{ contains: type }] },
|
|
||||||
});
|
|
||||||
const tokenRows = await this.sqlite.fetchResource({
|
|
||||||
sql,
|
|
||||||
parameters,
|
|
||||||
});
|
|
||||||
const tokenIds = tokenRows.map((row) => row.id);
|
|
||||||
|
|
||||||
if (tokenIds.length > 0) {
|
|
||||||
await this.sqlite.deleteResource('token', tokenIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await adapter.query(store, schema, {
|
|
||||||
...remainingQuery,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async writeToDb(
|
|
||||||
payload,
|
|
||||||
storeToken,
|
|
||||||
tokenKey,
|
|
||||||
pushToStore,
|
|
||||||
serializer,
|
|
||||||
store,
|
|
||||||
schema,
|
|
||||||
type,
|
|
||||||
) {
|
|
||||||
if (payload.list_token && storeToken) {
|
|
||||||
await this.sqlite.insertResource('token', [
|
|
||||||
[tokenKey, payload.list_token],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
const normalizedPayload = serializer.normalizeResponse(
|
|
||||||
store,
|
|
||||||
schema,
|
|
||||||
payload,
|
|
||||||
null,
|
|
||||||
'query',
|
|
||||||
);
|
|
||||||
|
|
||||||
const { data: payloadData } = normalizedPayload;
|
|
||||||
|
|
||||||
// Remove any records from the DB if the API indicates they've been deleted
|
|
||||||
// Additionally remove deleted records from ember data store for symmetry
|
|
||||||
if (payload.removed_ids?.length > 0) {
|
|
||||||
await this.sqlite.deleteResource(type, payload.removed_ids);
|
|
||||||
|
|
||||||
if (pushToStore) {
|
|
||||||
payload.removed_ids.forEach((id) => {
|
|
||||||
const record = store.peekRecord(type, id);
|
|
||||||
store.unloadRecord(record);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store the new data we just got back from the API refresh
|
|
||||||
const items = payloadData.map((datum) => {
|
|
||||||
const params = Object.values(modelMapping[type]).map((key) => {
|
|
||||||
let value;
|
|
||||||
|
|
||||||
if (key === 'id') {
|
|
||||||
value = datum.id;
|
|
||||||
} else {
|
|
||||||
value = get(datum, `attributes.${key}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeOf(value) === 'date') {
|
|
||||||
return value.toISOString();
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
});
|
|
||||||
|
|
||||||
return [...params, JSON.stringify(datum)];
|
|
||||||
});
|
|
||||||
|
|
||||||
await this.sqlite.insertResource(type, items);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
// app/initializers/fragment-serializer.js
|
||||||
|
import FragmentAuthMethodAttributesAccountClaimMapSerializer from '../serializers/fragment-auth-method-attributes-account-claim-map';
|
||||||
|
|
||||||
|
export function initialize(application) {
|
||||||
|
application.register(
|
||||||
|
'serializer:fragment-auth-method-attributes-account-claim-map',
|
||||||
|
FragmentAuthMethodAttributesAccountClaimMapSerializer
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fragment serializers must be manually registered
|
||||||
|
export default {
|
||||||
|
name: 'fragment-auth-method-attributes-account-claim-map',
|
||||||
|
initialize: initialize,
|
||||||
|
};
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// app/initializers/fragment-serializer.js
|
||||||
|
import FragmentStringSerializer from '../serializers/fragment-string';
|
||||||
|
|
||||||
|
export function initialize(application) {
|
||||||
|
application.register('serializer:fragment-string', FragmentStringSerializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fragment serializers must be manually registered
|
||||||
|
export default {
|
||||||
|
name: 'fragment-string',
|
||||||
|
initialize: initialize,
|
||||||
|
};
|
||||||
@@ -1,12 +1,7 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import Mixin from '@ember/object/mixin';
|
import Mixin from '@ember/object/mixin';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides URL-building methods in an adapter for greater flexibility.
|
* Overrides URL-building methods in an adpater for greater flexibility.
|
||||||
* Specifically enhances calls to `urlPrefix` with `modelName`, `id`, and
|
* Specifically enhances calls to `urlPrefix` with `modelName`, `id`, and
|
||||||
* `snapshot`, which aren't normally passed. And adds support for a
|
* `snapshot`, which aren't normally passed. And adds support for a
|
||||||
* `urlSuffix` method, the return value of which is appended to the end of
|
* `urlSuffix` method, the return value of which is appended to the end of
|
||||||
@@ -22,7 +17,7 @@ export default Mixin.create({
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This override behaves identically to the default method by default.
|
* This override behaves identically to the default method by default.
|
||||||
* It exists only to document the additional parameters to the method.
|
* It exists only to document the additional paramters to the method.
|
||||||
* @override
|
* @override
|
||||||
* @param {string} path
|
* @param {string} path
|
||||||
* @param {string} parentURL
|
* @param {string} parentURL
|
||||||
|
|||||||
@@ -1,54 +1,35 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import GeneratedAccountModel from '../generated/models/account';
|
import GeneratedAccountModel from '../generated/models/account';
|
||||||
import {
|
import { fragment } from 'ember-data-model-fragments/attributes';
|
||||||
TYPE_AUTH_METHOD_PASSWORD,
|
import { computed } from '@ember/object';
|
||||||
TYPE_AUTH_METHOD_OIDC,
|
import { equal } from '@ember/object/computed';
|
||||||
TYPE_AUTH_METHOD_LDAP,
|
|
||||||
TYPES_AUTH_METHOD,
|
|
||||||
} from './auth-method';
|
|
||||||
|
|
||||||
export default class AccountModel extends GeneratedAccountModel {
|
export default class AccountModel extends GeneratedAccountModel {
|
||||||
// =attributes
|
// =attributes
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {boolean}
|
* Attributes of this resource, if any, represented as a JSON fragment.
|
||||||
|
* @type {FragmentAccountAttributesModel}
|
||||||
*/
|
*/
|
||||||
get isPassword() {
|
@fragment('fragment-account-attributes', { defaultValue: {} }) attributes;
|
||||||
return this.type === TYPE_AUTH_METHOD_PASSWORD;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
get isOIDC() {
|
@equal('type', 'password') isPassword;
|
||||||
return this.type === TYPE_AUTH_METHOD_OIDC;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
get isLDAP() {
|
@equal('type', 'oidc') isOIDC;
|
||||||
return this.type === TYPE_AUTH_METHOD_LDAP;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get isUnknown() {
|
|
||||||
return !TYPES_AUTH_METHOD.includes(this.type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience for getting username in account.
|
* Convenience for getting username in account.
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
|
@computed('attributes.{email,full_name,login_name}')
|
||||||
get accountName() {
|
get accountName() {
|
||||||
const { email, full_name, login_name, subject } = this;
|
const { email, full_name, login_name } = this.attributes;
|
||||||
return email || full_name || login_name || subject;
|
return email || full_name || login_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =methods
|
// =methods
|
||||||
@@ -87,7 +68,7 @@ export default class AccountModel extends GeneratedAccountModel {
|
|||||||
changePassword(
|
changePassword(
|
||||||
currentPassword,
|
currentPassword,
|
||||||
newPassword,
|
newPassword,
|
||||||
options = { adapterOptions: {} },
|
options = { adapterOptions: {} }
|
||||||
) {
|
) {
|
||||||
const defaultAdapterOptions = {
|
const defaultAdapterOptions = {
|
||||||
method: 'change-password',
|
method: 'change-password',
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import GeneratedAliasModel from '../generated/models/alias';
|
|
||||||
|
|
||||||
export const TYPE_ALIAS_TARGET = 'target';
|
|
||||||
export const TYPES_ALIAS = Object.freeze([TYPE_ALIAS_TARGET]);
|
|
||||||
export default class AliasModel extends GeneratedAliasModel {}
|
|
||||||
@@ -1,26 +1,12 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import GeneratedAuthMethodModel from '../generated/models/auth-method';
|
import GeneratedAuthMethodModel from '../generated/models/auth-method';
|
||||||
|
import { attr } from '@ember-data/model';
|
||||||
|
import { fragment } from 'ember-data-model-fragments/attributes';
|
||||||
import { equal } from '@ember/object/computed';
|
import { equal } from '@ember/object/computed';
|
||||||
|
|
||||||
export const TYPE_AUTH_METHOD_PASSWORD = 'password';
|
|
||||||
export const TYPE_AUTH_METHOD_OIDC = 'oidc';
|
|
||||||
export const TYPE_AUTH_METHOD_LDAP = 'ldap';
|
|
||||||
|
|
||||||
export const TYPES_AUTH_METHOD = Object.freeze([
|
|
||||||
TYPE_AUTH_METHOD_PASSWORD,
|
|
||||||
TYPE_AUTH_METHOD_OIDC,
|
|
||||||
TYPE_AUTH_METHOD_LDAP,
|
|
||||||
]);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum options per auth method type and field.
|
* Enum options per auth method type and field.
|
||||||
*/
|
*/
|
||||||
export const options = {
|
export const options = {
|
||||||
state: ['inactive', 'active-private', 'active-public'],
|
|
||||||
oidc: {
|
oidc: {
|
||||||
signing_algorithms: [
|
signing_algorithms: [
|
||||||
'RS256',
|
'RS256',
|
||||||
@@ -34,27 +20,42 @@ export const options = {
|
|||||||
'PS512',
|
'PS512',
|
||||||
'EdDSA',
|
'EdDSA',
|
||||||
],
|
],
|
||||||
|
state: ['inactive', 'active-private', 'active-public'],
|
||||||
account_claim_maps: {
|
account_claim_maps: {
|
||||||
to: ['sub', 'name', 'email'],
|
to: ['sub', 'name', 'email'],
|
||||||
},
|
},
|
||||||
prompts: ['consent', 'select_account', 'login'],
|
|
||||||
},
|
|
||||||
ldap: {
|
|
||||||
account_attribute_maps: {
|
|
||||||
to: ['fullName', 'email'],
|
|
||||||
},
|
|
||||||
dereference_aliases: {
|
|
||||||
NeverDerefAliases: 'never',
|
|
||||||
DerefInSearching: 'searching',
|
|
||||||
DerefFindingBaseObj: 'finding',
|
|
||||||
DerefAlways: 'always',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class AuthMethodModel extends GeneratedAuthMethodModel {
|
export default class AuthMethodModel extends GeneratedAuthMethodModel {
|
||||||
|
// =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_state;
|
||||||
|
@attr('string', { readOnly: true }) attributes_issuer;
|
||||||
|
@attr('string', { readOnly: true }) attributes_client_id;
|
||||||
|
@attr('string', { readOnly: true }) attributes_client_secret;
|
||||||
|
@attr('string', { readOnly: true }) attributes_max_age;
|
||||||
|
@attr('string', { readOnly: true }) attributes_api_url_prefix;
|
||||||
|
@attr('string', { readOnly: true })
|
||||||
|
attributes_disable_discovered_config_validation;
|
||||||
|
@attr('string', { readOnly: true }) attributes_dry_run;
|
||||||
|
@attr('string', { readOnly: true }) attributes_account_claim_maps;
|
||||||
|
@attr('string', { readOnly: true }) attributes_claims_scopes;
|
||||||
|
@attr('string', { readOnly: true }) attributes_signing_algorithms;
|
||||||
|
@attr('string', { readOnly: true }) attributes_allowed_audiences;
|
||||||
|
@attr('string', { readOnly: true }) attributes_idp_ca_certs;
|
||||||
|
|
||||||
// =attributes
|
// =attributes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attributes of this resource, if any, represented as a JSON fragment.
|
||||||
|
* @type {FragmentAuthMethodAttributesModel}
|
||||||
|
*/
|
||||||
|
@fragment('fragment-auth-method-attributes', { defaultValue: {} }) attributes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
@@ -66,57 +67,43 @@ export default class AuthMethodModel extends GeneratedAuthMethodModel {
|
|||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
get isPassword() {
|
get isPassword() {
|
||||||
return this.type === TYPE_AUTH_METHOD_PASSWORD;
|
return this.type === 'password';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
get isOIDC() {
|
get isOIDC() {
|
||||||
return this.type === TYPE_AUTH_METHOD_OIDC;
|
return this.type === 'oidc';
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get isLDAP() {
|
|
||||||
return this.type === TYPE_AUTH_METHOD_LDAP;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get isUnknown() {
|
|
||||||
return !TYPES_AUTH_METHOD.includes(this.type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
get isInactive() {
|
get isInactive() {
|
||||||
return this.state === 'inactive';
|
return this.attributes.state === 'inactive';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
get isPrivate() {
|
get isPrivate() {
|
||||||
return this.state === 'active-private';
|
return this.attributes.state === 'active-private';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
get isPublic() {
|
get isPublic() {
|
||||||
return this.state === 'active-public';
|
return this.attributes.state === 'active-public';
|
||||||
}
|
}
|
||||||
|
|
||||||
// =methods
|
// =methods
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change the active and visibility state of an OIDC and LDAP auth method
|
* Change the active and visibility state of an OIDC auth method
|
||||||
* given its ID.
|
* given its ID.
|
||||||
* For OIDC and LDAP auth methods only.
|
* For OIDC auth methods only.
|
||||||
* @param {[string]} state
|
* @param {[string]} state
|
||||||
* @param {object} options
|
* @param {object} options
|
||||||
* @param {object} options.adapterOptions
|
* @param {object} options.adapterOptions
|
||||||
@@ -124,11 +111,9 @@ export default class AuthMethodModel extends GeneratedAuthMethodModel {
|
|||||||
*/
|
*/
|
||||||
changeState(state, options = { adapterOptions: {} }) {
|
changeState(state, options = { adapterOptions: {} }) {
|
||||||
const defaultAdapterOptions = {
|
const defaultAdapterOptions = {
|
||||||
|
method: 'change-state',
|
||||||
state,
|
state,
|
||||||
};
|
};
|
||||||
if (this.isOIDC) {
|
|
||||||
defaultAdapterOptions.method = 'change-state';
|
|
||||||
}
|
|
||||||
return this.save({
|
return this.save({
|
||||||
...options,
|
...options,
|
||||||
adapterOptions: {
|
adapterOptions: {
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import GeneratedAuthTokenModel from '../generated/models/auth-token';
|
import GeneratedAuthTokenModel from '../generated/models/auth-token';
|
||||||
|
|
||||||
export default class AuthTokenModel extends GeneratedAuthTokenModel {}
|
export default class AuthTokenModel extends GeneratedAuthTokenModel {}
|
||||||
@@ -1,12 +1,7 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import Model from '@ember-data/model';
|
import Model from '@ember-data/model';
|
||||||
import { attr } from '@ember-data/model';
|
import { attr } from '@ember-data/model';
|
||||||
|
import { fragment } from 'ember-data-model-fragments/attributes';
|
||||||
import { computed } from '@ember/object';
|
import { computed } from '@ember/object';
|
||||||
import { service } from '@ember/service';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base model class provides common functionality for all models.
|
* Base model class provides common functionality for all models.
|
||||||
@@ -31,16 +26,13 @@ import { service } from '@ember/service';
|
|||||||
* 2) Or as an ID: `record.scopeID`.
|
* 2) Or as an ID: `record.scopeID`.
|
||||||
*/
|
*/
|
||||||
export default class BaseModel extends Model {
|
export default class BaseModel extends Model {
|
||||||
// =services
|
|
||||||
|
|
||||||
@service store;
|
|
||||||
|
|
||||||
// =relationships
|
// =relationships
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scope of this resource, if any, represented as a JSON fragment.
|
* Scope of this resource, if any, represented as a JSON fragment.
|
||||||
|
* @type {FragmentScope}
|
||||||
*/
|
*/
|
||||||
@attr() scope;
|
@fragment('fragment-scope') scope;
|
||||||
|
|
||||||
// =attributes
|
// =attributes
|
||||||
|
|
||||||
@@ -57,20 +49,12 @@ export default class BaseModel extends Model {
|
|||||||
|
|
||||||
get scopeModel() {
|
get scopeModel() {
|
||||||
const id = this.scopeID;
|
const id = this.scopeID;
|
||||||
return id ? this.store.peekRecord('scope', id) : null;
|
return this.store.peekRecord('scope', id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ember seems to have a bug with its internals and can't correctly set
|
|
||||||
// the `scopeModel` when passed in as part of the `inputProperties`
|
|
||||||
// of a `createRecord` call
|
|
||||||
set scopeModel(model) {
|
set scopeModel(model) {
|
||||||
if (model) {
|
if (model) {
|
||||||
const json = model.serialize();
|
const json = model.serialize();
|
||||||
json.scope_id = model.id;
|
json.scope_id = model.id;
|
||||||
json.type = model.type;
|
|
||||||
json.isGlobal = model.isGlobal;
|
|
||||||
json.isOrg = model.isOrg;
|
|
||||||
json.isProject = model.isProject;
|
|
||||||
this.scope = json;
|
this.scope = json;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,6 +85,7 @@ export default class BaseModel extends Model {
|
|||||||
/**
|
/**
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
|
@computed('hasDirtyAttributes', 'isSaving')
|
||||||
get canSave() {
|
get canSave() {
|
||||||
return this.hasDirtyAttributes && !this.isSaving;
|
return this.hasDirtyAttributes && !this.isSaving;
|
||||||
}
|
}
|
||||||
@@ -108,6 +93,7 @@ export default class BaseModel extends Model {
|
|||||||
/**
|
/**
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
|
@computed('canSave')
|
||||||
get cannotSave() {
|
get cannotSave() {
|
||||||
return !this.canSave;
|
return !this.canSave;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import GeneratedChannelRecordingModel from '../generated/models/channel-recording';
|
|
||||||
import { belongsTo } from '@ember-data/model';
|
|
||||||
|
|
||||||
export const MIME_TYPE_ASCIICAST = 'application/x-asciicast';
|
|
||||||
|
|
||||||
export default class ChannelRecordingModel extends GeneratedChannelRecordingModel {
|
|
||||||
@belongsTo('connection-recording', {
|
|
||||||
async: false,
|
|
||||||
inverse: 'channel_recordings',
|
|
||||||
})
|
|
||||||
connection_recording;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* True if the channel supports asciicast.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get isAsciicast() {
|
|
||||||
return this.mime_types?.includes(MIME_TYPE_ASCIICAST) ?? false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Download the ascii cast recording for this channel.
|
|
||||||
* @returns {Promise<string>}
|
|
||||||
*/
|
|
||||||
getAsciicast() {
|
|
||||||
const adapter = this.store.adapterFor('session-recording');
|
|
||||||
return adapter.getAsciicast(this.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import GeneratedConnectionRecordingModel from '../generated/models/connection-recording';
|
|
||||||
import { belongsTo, hasMany } from '@ember-data/model';
|
|
||||||
|
|
||||||
export default class ConnectionRecordingModel extends GeneratedConnectionRecordingModel {
|
|
||||||
@belongsTo('session-recording', {
|
|
||||||
async: false,
|
|
||||||
inverse: 'connection_recordings',
|
|
||||||
})
|
|
||||||
session_recording;
|
|
||||||
@hasMany('channel-recording', {
|
|
||||||
async: false,
|
|
||||||
inverse: 'connection_recording',
|
|
||||||
})
|
|
||||||
channel_recordings;
|
|
||||||
}
|
|
||||||
@@ -1,101 +1,30 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import GeneratedCredentialLibraryModel from '../generated/models/credential-library';
|
import GeneratedCredentialLibraryModel from '../generated/models/credential-library';
|
||||||
import {
|
import { attr } from '@ember-data/model';
|
||||||
TYPE_CREDENTIAL_SSH_PRIVATE_KEY,
|
import { fragment } from 'ember-data-model-fragments/attributes';
|
||||||
TYPE_CREDENTIAL_USERNAME_PASSWORD_DOMAIN,
|
|
||||||
TYPE_CREDENTIAL_USERNAME_PASSWORD,
|
|
||||||
TYPE_CREDENTIAL_PASSWORD,
|
|
||||||
} from 'api/models/credential';
|
|
||||||
/**
|
/**
|
||||||
* Enum options for credential library.
|
* Enum options for credential library.
|
||||||
*/
|
*/
|
||||||
export const options = {
|
export const options = {
|
||||||
http_method: ['GET', 'POST'],
|
http_method: ['GET', 'POST'],
|
||||||
key_type: ['ed25519', 'ecdsa', 'rsa'],
|
|
||||||
credential_types: [
|
|
||||||
TYPE_CREDENTIAL_SSH_PRIVATE_KEY,
|
|
||||||
TYPE_CREDENTIAL_USERNAME_PASSWORD,
|
|
||||||
TYPE_CREDENTIAL_USERNAME_PASSWORD_DOMAIN,
|
|
||||||
TYPE_CREDENTIAL_PASSWORD,
|
|
||||||
],
|
|
||||||
mapping_overrides: {
|
|
||||||
username_password: ['username_attribute', 'password_attribute'],
|
|
||||||
ssh_private_key: [
|
|
||||||
'private_key_attribute',
|
|
||||||
'private_key_passphrase_attribute',
|
|
||||||
'username_attribute',
|
|
||||||
],
|
|
||||||
username_password_domain: [
|
|
||||||
'username_attribute',
|
|
||||||
'password_attribute',
|
|
||||||
'domain_attribute',
|
|
||||||
],
|
|
||||||
password: ['password_attribute'],
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC = 'vault-generic';
|
|
||||||
export const TYPE_CREDENTIAL_LIBRARY_VAULT_SSH_CERTIFICATE =
|
|
||||||
'vault-ssh-certificate';
|
|
||||||
export const TYPE_CREDENTIAL_LIBRARY_VAULT_LDAP = 'vault-ldap';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Supported Credential Library types.
|
|
||||||
*/
|
|
||||||
export const TYPES_CREDENTIAL_LIBRARY = Object.freeze([
|
|
||||||
TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC,
|
|
||||||
TYPE_CREDENTIAL_LIBRARY_VAULT_SSH_CERTIFICATE,
|
|
||||||
TYPE_CREDENTIAL_LIBRARY_VAULT_LDAP,
|
|
||||||
]);
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if credential is an unknown type.
|
* Attributes of this resource, if any, represented as a JSON fragment.
|
||||||
* @type {boolean}
|
* @type {FragmentCredentialLibraryAttributesModel}
|
||||||
*/
|
*/
|
||||||
get isUnknown() {
|
@fragment('fragment-credential-library-attributes', { defaultValue: {} })
|
||||||
return !TYPES_CREDENTIAL_LIBRARY.includes(this.type);
|
attributes;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* True if credential is a vault type.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get isVault() {
|
|
||||||
return (
|
|
||||||
this.type === TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC ||
|
|
||||||
this.type === TYPE_CREDENTIAL_LIBRARY_VAULT_SSH_CERTIFICATE ||
|
|
||||||
this.type === TYPE_CREDENTIAL_LIBRARY_VAULT_LDAP
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* True if credential is a generic vault type.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get isVaultGeneric() {
|
|
||||||
return this.type === TYPE_CREDENTIAL_LIBRARY_VAULT_GENERIC;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* True if credential is a vault ssh cert type.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get isVaultSSHCertificate() {
|
|
||||||
return this.type === TYPE_CREDENTIAL_LIBRARY_VAULT_SSH_CERTIFICATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* True if credential is a vault ldap type.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get isVaultLDAP() {
|
|
||||||
return this.type === TYPE_CREDENTIAL_LIBRARY_VAULT_LDAP;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,29 +1,34 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import GeneratedCredentialStoreModel from '../generated/models/credential-store';
|
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';
|
import { equal } from '@ember/object/computed';
|
||||||
|
|
||||||
export const TYPE_CREDENTIAL_STORE_STATIC = 'static';
|
|
||||||
export const TYPE_CREDENTIAL_STORE_VAULT = 'vault';
|
|
||||||
|
|
||||||
export const TYPES_CREDENTIAL_STORE = Object.freeze([
|
|
||||||
TYPE_CREDENTIAL_STORE_STATIC,
|
|
||||||
TYPE_CREDENTIAL_STORE_VAULT,
|
|
||||||
]);
|
|
||||||
|
|
||||||
export default class CredentialStoreModel extends GeneratedCredentialStoreModel {
|
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
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attributes of this resource, if any, represented as a JSON fragment.
|
||||||
|
* @type {FragmentAuthMethodAttributesModel}
|
||||||
|
*/
|
||||||
|
@fragment('fragment-credential-store-attributes', { defaultValue: {} })
|
||||||
|
attributes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
@equal('type', 'vault') isVault;
|
@equal('type', 'vault') isVault;
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
@equal('type', 'static') isStatic;
|
|
||||||
}
|
}
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright IBM Corp. 2021, 2026
|
|
||||||
* SPDX-License-Identifier: BUSL-1.1
|
|
||||||
*/
|
|
||||||
|
|
||||||
import GeneratedCredentialModel from '../generated/models/credential';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Supported Credential types.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export const TYPE_CREDENTIAL_USERNAME_PASSWORD = 'username_password';
|
|
||||||
export const TYPE_CREDENTIAL_SSH_PRIVATE_KEY = 'ssh_private_key';
|
|
||||||
export const TYPE_CREDENTIAL_JSON = 'json';
|
|
||||||
export const TYPE_CREDENTIAL_USERNAME_PASSWORD_DOMAIN =
|
|
||||||
'username_password_domain';
|
|
||||||
export const TYPE_CREDENTIAL_PASSWORD = 'password';
|
|
||||||
|
|
||||||
export const TYPES_CREDENTIAL = Object.freeze([
|
|
||||||
TYPE_CREDENTIAL_USERNAME_PASSWORD,
|
|
||||||
TYPE_CREDENTIAL_SSH_PRIVATE_KEY,
|
|
||||||
TYPE_CREDENTIAL_USERNAME_PASSWORD_DOMAIN,
|
|
||||||
TYPE_CREDENTIAL_JSON,
|
|
||||||
TYPE_CREDENTIAL_PASSWORD,
|
|
||||||
]);
|
|
||||||
|
|
||||||
export default class CredentialModel extends GeneratedCredentialModel {
|
|
||||||
// =attributes
|
|
||||||
/**
|
|
||||||
* All Credentials are prefixed with "cred" and are considered
|
|
||||||
* static due to their relation with Static Credential Stores.
|
|
||||||
*
|
|
||||||
* True if credential starts with the "cred" prefix.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get isStatic() {
|
|
||||||
return this.id.startsWith('cred');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* True if type is `json`.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get isJSON() {
|
|
||||||
return this.type === TYPE_CREDENTIAL_JSON;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* True if credential is an unknown type.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
get isUnknown() {
|
|
||||||
return !TYPES_CREDENTIAL.includes(this.type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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,9 @@
|
|||||||
|
import Fragment from 'ember-data-model-fragments/fragment';
|
||||||
|
import { attr } from '@ember-data/model';
|
||||||
|
|
||||||
|
export default class FragmentAuthMethodAttributesAccountClaimMapModel extends Fragment {
|
||||||
|
// =attributes (OIDC)
|
||||||
|
|
||||||
|
@attr('string') from;
|
||||||
|
@attr('string') to;
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import Fragment from 'ember-data-model-fragments/fragment';
|
||||||
|
import { attr } from '@ember-data/model';
|
||||||
|
import { fragmentArray } from 'ember-data-model-fragments/attributes';
|
||||||
|
|
||||||
|
export default class FragmentAuthMethodAttributesModel extends Fragment {
|
||||||
|
// =attributes (OIDC)
|
||||||
|
|
||||||
|
@attr('string', { readOnly: true }) state;
|
||||||
|
@attr('string') issuer;
|
||||||
|
@attr('string') client_id;
|
||||||
|
@attr('string') client_secret;
|
||||||
|
@attr('string', { readOnly: true }) client_secret_hmac;
|
||||||
|
@attr('number') max_age;
|
||||||
|
@attr('string') api_url_prefix;
|
||||||
|
@attr('string', { readOnly: true }) callback_url;
|
||||||
|
@attr('boolean') disable_discovered_config_validation;
|
||||||
|
@attr('boolean') dry_run;
|
||||||
|
|
||||||
|
@fragmentArray('fragment-auth-method-attributes-account-claim-map', {
|
||||||
|
emptyArrayIfMissing: true,
|
||||||
|
})
|
||||||
|
account_claim_maps;
|
||||||
|
|
||||||
|
@fragmentArray('fragment-string', {
|
||||||
|
emptyArrayIfMissing: true,
|
||||||
|
})
|
||||||
|
claims_scopes;
|
||||||
|
|
||||||
|
@fragmentArray('fragment-string', {
|
||||||
|
emptyArrayIfMissing: true,
|
||||||
|
})
|
||||||
|
signing_algorithms;
|
||||||
|
|
||||||
|
@fragmentArray('fragment-string', {
|
||||||
|
emptyArrayIfMissing: true,
|
||||||
|
})
|
||||||
|
allowed_audiences;
|
||||||
|
|
||||||
|
@fragmentArray('fragment-string', { emptyArrayIfMissing: true }) idp_ca_certs;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
Loaded 100 of 3065 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user