@fixedwidthtable/fixedwidthtable 0.0.1-security → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of @fixedwidthtable/fixedwidthtable might be problematic. Click here for more details.
- package/.eslintignore +2 -0
- package/.eslintrc.js +8 -0
- package/.github/dependabot.yml +24 -0
- package/.github/workflows/audit.yml +14 -0
- package/.github/workflows/ci.yml +53 -0
- package/.github/workflows/release.yml +31 -0
- package/.github/workflows/reusable-audit.yml +41 -0
- package/.github/workflows/reusable-lint.yml +33 -0
- package/CODEOWNERS +1 -0
- package/LICENSE.md +18 -0
- package/README.md +12 -3
- package/e2e/browser/test/e2e.playwright.ts +67 -0
- package/e2e/browser/test/globalSetup.ts +30 -0
- package/e2e/browser/test-app/.eslintrc.js +6 -0
- package/e2e/browser/test-app/README.md +46 -0
- package/e2e/browser/test-app/components/appContainer/index.tsx +109 -0
- package/e2e/browser/test-app/components/solidClient/index.tsx +149 -0
- package/e2e/browser/test-app/next-env.d.ts +5 -0
- package/e2e/browser/test-app/next.config.js +6 -0
- package/e2e/browser/test-app/package-lock.json +1982 -0
- package/e2e/browser/test-app/package.json +25 -0
- package/e2e/browser/test-app/pages/_app.tsx +28 -0
- package/e2e/browser/test-app/pages/index.tsx +36 -0
- package/e2e/browser/test-app/tsconfig.json +20 -0
- package/eslint-configs/README.md +75 -0
- package/eslint-configs/eslint-config-base/README.md +29 -0
- package/eslint-configs/eslint-config-base/index.js +159 -0
- package/eslint-configs/eslint-config-base/license-header.js +20 -0
- package/eslint-configs/eslint-config-base/package.json +41 -0
- package/eslint-configs/eslint-config-lib/README.md +51 -0
- package/eslint-configs/eslint-config-lib/index.js +83 -0
- package/eslint-configs/eslint-config-lib/package.json +29 -0
- package/eslint-configs/eslint-config-react/README.md +97 -0
- package/eslint-configs/eslint-config-react/index.js +75 -0
- package/eslint-configs/eslint-config-react/package.json +32 -0
- package/lerna.json +4 -0
- package/package.json +45 -3
- package/packages/base-rollup-config/README.md +22 -0
- package/packages/base-rollup-config/index.mjs +59 -0
- package/packages/base-rollup-config/package.json +25 -0
- package/packages/internal-playwright-helpers/README.md +30 -0
- package/packages/internal-playwright-helpers/package.json +29 -0
- package/packages/internal-playwright-helpers/rollup.config.mjs +57 -0
- package/packages/internal-playwright-helpers/src/fixtures.ts +51 -0
- package/packages/internal-playwright-helpers/src/flows/auth.ts +93 -0
- package/packages/internal-playwright-helpers/src/index.ts +26 -0
- package/packages/internal-playwright-helpers/src/pages/cognito.ts +48 -0
- package/packages/internal-playwright-helpers/src/pages/open-id.ts +56 -0
- package/packages/internal-playwright-helpers/src/pages/testPage.ts +74 -0
- package/packages/internal-playwright-helpers/tsconfig.json +8 -0
- package/packages/internal-playwright-testids/package.json +22 -0
- package/packages/internal-playwright-testids/rollup.config.mjs +56 -0
- package/packages/internal-playwright-testids/src/index.ts +35 -0
- package/packages/internal-playwright-testids/tsconfig.json +8 -0
- package/packages/internal-test-env/README.md +44 -0
- package/packages/internal-test-env/env/.env.example +36 -0
- package/packages/internal-test-env/index.ts +474 -0
- package/packages/internal-test-env/package.json +30 -0
- package/packages/internal-test-env/rollup.config.mjs +80 -0
- package/packages/internal-test-env/tsconfig.json +20 -0
- package/packages/internal-test-env/utils.ts +31 -0
- package/packages/jest-jsdom-polyfills/README.md +21 -0
- package/packages/jest-jsdom-polyfills/index.js +80 -0
- package/packages/jest-jsdom-polyfills/package.json +36 -0
- package/playwright.config.ts +76 -0
- package/scripts/index.js +1 -0
- package/scripts/prepare-release.sh +32 -0
- package/scripts/release.sh +36 -0
- package/tsconfig.base.json +17 -0
package/.eslintignore
ADDED
package/.eslintrc.js
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
version: 2
|
2
|
+
updates:
|
3
|
+
# We use "/" as the directory, as this repository is managed by npm workspaces,
|
4
|
+
# and that's where the package-lock.json is located
|
5
|
+
- package-ecosystem: npm
|
6
|
+
directory: "/"
|
7
|
+
schedule:
|
8
|
+
interval: "weekly"
|
9
|
+
# The following is required for workspaces to be updated: see https://github.com/dependabot/dependabot-core/issues/5226.
|
10
|
+
versioning-strategy: increase
|
11
|
+
open-pull-requests-limit: 10
|
12
|
+
- package-ecosystem: npm
|
13
|
+
directory: "/eslint-configs/*"
|
14
|
+
schedule:
|
15
|
+
interval: "weekly"
|
16
|
+
open-pull-requests-limit: 10
|
17
|
+
- package-ecosystem: "github-actions"
|
18
|
+
directory: "/"
|
19
|
+
schedule:
|
20
|
+
interval: "weekly"
|
21
|
+
- package-ecosystem: npm
|
22
|
+
directory: "e2e/browser/test-app"
|
23
|
+
schedule:
|
24
|
+
interval: "weekly"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
name: Audit
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
schedule:
|
6
|
+
- cron: "40 10 * * *"
|
7
|
+
concurrency:
|
8
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
9
|
+
cancel-in-progress: true
|
10
|
+
jobs:
|
11
|
+
audit:
|
12
|
+
uses: ./.github/workflows/reusable-audit.yml
|
13
|
+
secrets:
|
14
|
+
WEBHOOK_E2E_FAILURE: ${{ secrets.WEBHOOK_E2E_FAILURE }}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on: [push]
|
4
|
+
|
5
|
+
env:
|
6
|
+
CI: true
|
7
|
+
jobs:
|
8
|
+
lint:
|
9
|
+
uses: ./.github/workflows/reusable-lint.yml
|
10
|
+
with:
|
11
|
+
build: true
|
12
|
+
|
13
|
+
build:
|
14
|
+
runs-on: ${{ matrix.os }}
|
15
|
+
environment:
|
16
|
+
name: ${{ matrix.environment-name }}
|
17
|
+
strategy:
|
18
|
+
fail-fast: true
|
19
|
+
matrix:
|
20
|
+
environment-name: ["ESS PodSpaces"]
|
21
|
+
os: [ubuntu-latest]
|
22
|
+
# Workspaces support was added from npm 7, so Node 14 isn't supported to
|
23
|
+
# build this library.
|
24
|
+
node-version: ["16", "18", "20"]
|
25
|
+
steps:
|
26
|
+
- uses: actions/checkout@v4
|
27
|
+
- uses: actions/setup-node@v3
|
28
|
+
with:
|
29
|
+
node-version: ${{ matrix.node-version }}
|
30
|
+
cache: npm
|
31
|
+
registry-url: "https://registry.npmjs.org"
|
32
|
+
- run: npm ci --workspaces
|
33
|
+
# Running top-level ci should happen after workspaces level, running these
|
34
|
+
# the other way around results in top-level dependencies (namely, lerna)
|
35
|
+
# not being installed.
|
36
|
+
- run: npm ci
|
37
|
+
- run: npm run build
|
38
|
+
- run: npx playwright install --with-deps
|
39
|
+
- run: npm run e2e:test:setup
|
40
|
+
- # Dependabot cannot access secrets, so it doesn't have a token to authenticate to ESS.
|
41
|
+
# We want jobs in this workflow to be gating PRs, so the whole matrix must
|
42
|
+
# run even for dependabot so that the matrixed jobs are skipped, instead
|
43
|
+
# of the whole pipeline.
|
44
|
+
if: ${{ github.actor != 'dependabot[bot]' }}
|
45
|
+
run: npm t
|
46
|
+
env:
|
47
|
+
E2E_DEMO_CLIENT_APP_URL: http://localhost:3001
|
48
|
+
E2E_TEST_USER: ${{ secrets.E2E_TEST_USER }}
|
49
|
+
E2E_TEST_PASSWORD: ${{ secrets.E2E_TEST_PASSWORD }}
|
50
|
+
E2E_TEST_IDP: ${{ secrets.E2E_TEST_IDP }}
|
51
|
+
E2E_TEST_OWNER_CLIENT_ID: ${{ secrets.E2E_TEST_OWNER_CLIENT_ID }}
|
52
|
+
E2E_TEST_OWNER_CLIENT_SECRET: ${{ secrets.E2E_TEST_OWNER_CLIENT_SECRET }}
|
53
|
+
E2E_TEST_ENVIRONMENT: ${{ matrix.environment-name }}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
name: Release
|
2
|
+
|
3
|
+
on:
|
4
|
+
pull_request:
|
5
|
+
branches:
|
6
|
+
- main
|
7
|
+
types: [closed]
|
8
|
+
|
9
|
+
env:
|
10
|
+
CI: true
|
11
|
+
jobs:
|
12
|
+
release-new-version:
|
13
|
+
if: ${{ github.event.pull_request.merged && startsWith(github.head_ref, 'release/') }}
|
14
|
+
runs-on: ubuntu-latest
|
15
|
+
steps:
|
16
|
+
- uses: actions/checkout@v4
|
17
|
+
- uses: actions/setup-node@v3
|
18
|
+
with:
|
19
|
+
node-version: 20
|
20
|
+
cache: npm
|
21
|
+
registry-url: "https://registry.npmjs.org"
|
22
|
+
- run: npm ci --workspaces
|
23
|
+
# Running top-level ci should happen after workspaces level, running these
|
24
|
+
# the other way around results in top-level dependencies (namely, lerna)
|
25
|
+
# not being installed.
|
26
|
+
- run: npm ci
|
27
|
+
- run: npm run build
|
28
|
+
- run: npm run release
|
29
|
+
env:
|
30
|
+
NODE_AUTH_TOKEN: ${{ secrets.INRUPT_NPM_TOKEN }}
|
31
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
@@ -0,0 +1,41 @@
|
|
1
|
+
name: Reusable Audit Workflow
|
2
|
+
|
3
|
+
on:
|
4
|
+
workflow_call:
|
5
|
+
secrets:
|
6
|
+
WEBHOOK_E2E_FAILURE:
|
7
|
+
required: true
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
audit:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
steps:
|
13
|
+
- uses: actions/checkout@v4
|
14
|
+
- uses: actions/setup-node@v3
|
15
|
+
with:
|
16
|
+
node-version: "20"
|
17
|
+
registry-url: "https://registry.npmjs.org"
|
18
|
+
cache: "npm"
|
19
|
+
# Install dependencies so license-checker actually checks them:
|
20
|
+
- run: npm ci
|
21
|
+
# We check the dependency licenses as part of the audit job, as a
|
22
|
+
# misconfigured or inappropriate dependency license is in the same
|
23
|
+
# category of issues as an npm audit security failure: we consider
|
24
|
+
# bad licenses a vulnerability.
|
25
|
+
- run: npx license-checker --production --failOn "AGPL-1.0-only; AGPL-1.0-or-later; AGPL-3.0-only; AGPL-3.0-or-later; Beerware; CC-BY-NC-1.0; CC-BY-NC-2.0; CC-BY-NC-2.5; CC-BY-NC-3.0; CC-BY-NC-4.0; CC-BY-NC-ND-1.0; CC-BY-NC-ND-2.0; CC-BY-NC-ND-2.5; CC-BY-NC-ND-3.0; CC-BY-NC-ND-4.0; CC-BY-NC-SA-1.0; CC-BY-NC-SA-2.0; CC-BY-NC-SA-2.5; CC-BY-NC-SA-3.0; CC-BY-NC-SA-4.0; CPAL-1.0; EUPL-1.0; EUPL-1.1; EUPL-1.1; GPL-1.0-only; GPL-1.0-or-later; GPL-2.0-only; GPL-2.0-or-later; GPL-3.0; GPL-3.0-only; GPL-3.0-or-later; SISSL; SISSL-1.2; WTFPL"
|
26
|
+
# Run the audit and capture the results
|
27
|
+
- run: npm audit --audit-level=moderate --omit=dev --json true | tee audit.json
|
28
|
+
# Run the audit to check the signatures
|
29
|
+
- run: npm audit signatures
|
30
|
+
- name: Archive audit report
|
31
|
+
uses: actions/upload-artifact@v3
|
32
|
+
continue-on-error: true
|
33
|
+
with:
|
34
|
+
name: audit.json
|
35
|
+
path: audit.json
|
36
|
+
# Publishes a notification to a slack channel:
|
37
|
+
- name: Send a notification that the audit has failed
|
38
|
+
if: failure() && github.event_name == 'schedule'
|
39
|
+
run: "curl -X POST -H Content-type: 'application/json' --data \"{\\\"text\\\":\\\"Automated npm audit --audit-level=moderate failed. View <https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID|the execution log> for more details.\\\"}\" $WEBHOOK_E2E_FAILURE"
|
40
|
+
env:
|
41
|
+
WEBHOOK_E2E_FAILURE: ${{ secrets.WEBHOOK_E2E_FAILURE }}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
name: Reusable Lint Workflow
|
2
|
+
|
3
|
+
on:
|
4
|
+
workflow_call:
|
5
|
+
inputs:
|
6
|
+
usePackageCheck:
|
7
|
+
required: false
|
8
|
+
default: false
|
9
|
+
type: boolean
|
10
|
+
build:
|
11
|
+
required: false
|
12
|
+
default: false
|
13
|
+
type: boolean
|
14
|
+
|
15
|
+
jobs:
|
16
|
+
lint:
|
17
|
+
runs-on: ubuntu-latest
|
18
|
+
steps:
|
19
|
+
- uses: actions/checkout@v4
|
20
|
+
- uses: actions/setup-node@v3
|
21
|
+
with:
|
22
|
+
node-version: "20"
|
23
|
+
cache: "npm"
|
24
|
+
# Check the package.json is correctly formed
|
25
|
+
- if: ${{inputs.usePackageCheck}}
|
26
|
+
run: npx @skypack/package-check
|
27
|
+
# Install dependencies:
|
28
|
+
- run: npm ci --ignore-scripts
|
29
|
+
# Build the package(s)
|
30
|
+
- if: ${{inputs.build}}
|
31
|
+
run: npm run build
|
32
|
+
# Run the linting command:
|
33
|
+
- run: npm run lint
|
package/CODEOWNERS
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
* @inrupt/sdk-owners
|
package/LICENSE.md
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Copyright 2020 Inrupt Inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal in
|
5
|
+
the Software without restriction, including without limitation the rights to use,
|
6
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
7
|
+
Software, and to permit persons to whom the Software is furnished to do so,
|
8
|
+
subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
14
|
+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
15
|
+
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
16
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
17
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
18
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
|
-
#
|
1
|
+
# FixedWidthTable
|
2
2
|
|
3
|
-
|
3
|
+
## Installation
|
4
4
|
|
5
|
-
|
5
|
+
```
|
6
|
+
yarn build # build target library
|
7
|
+
yarn test # run test
|
8
|
+
yarn doc:dev # run dev server of document
|
9
|
+
yarn doc # generate document site
|
10
|
+
```
|
11
|
+
|
12
|
+
## Dependencies
|
13
|
+
|
14
|
+
[react-component-tool](https://www.npmjs.com/package/@fixedwidthtable/fixedwidthtable)
|
@@ -0,0 +1,67 @@
|
|
1
|
+
//
|
2
|
+
// Copyright Inrupt Inc.
|
3
|
+
//
|
4
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
// of this software and associated documentation files (the "Software"), to deal in
|
6
|
+
// the Software without restriction, including without limitation the rights to use,
|
7
|
+
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
8
|
+
// Software, and to permit persons to whom the Software is furnished to do so,
|
9
|
+
// subject to the following conditions:
|
10
|
+
//
|
11
|
+
// The above copyright notice and this permission notice shall be included in
|
12
|
+
// all copies or substantial portions of the Software.
|
13
|
+
//
|
14
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
15
|
+
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
16
|
+
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
17
|
+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
18
|
+
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
19
|
+
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
|
+
//
|
21
|
+
|
22
|
+
/* eslint-disable jest/no-done-callback */
|
23
|
+
|
24
|
+
import { test, expect } from "@inrupt/internal-playwright-helpers";
|
25
|
+
|
26
|
+
test("creating and removing empty Containers", async ({ page, auth }) => {
|
27
|
+
await auth.login({ allow: true });
|
28
|
+
|
29
|
+
// The button is only shown once the app is ready.
|
30
|
+
await page.waitForSelector("button[data-testid=createContainer]");
|
31
|
+
|
32
|
+
// A root container should have been found.
|
33
|
+
await expect(page.getByTestId("parentContainerUrl")).toContainText(
|
34
|
+
/https:\/\//,
|
35
|
+
);
|
36
|
+
// No child container should be available yet.
|
37
|
+
await expect(page.getByTestId("childContainerUrl")).toContainText("None");
|
38
|
+
|
39
|
+
await Promise.all([
|
40
|
+
page.waitForRequest((request) => request.method() === "POST"),
|
41
|
+
page.waitForResponse((response) => response.status() === 201),
|
42
|
+
page.click("button[data-testid=createContainer]"),
|
43
|
+
]);
|
44
|
+
|
45
|
+
// The delete button is only shown once the state has been updated after creation.
|
46
|
+
await page.waitForSelector("button[data-testid=deleteContainer]");
|
47
|
+
|
48
|
+
// The child container should have been created under the parent
|
49
|
+
await expect(
|
50
|
+
page.locator("span[data-testid=childContainerUrl]"),
|
51
|
+
).toContainText(
|
52
|
+
await page.locator("span[data-testid=childContainerUrl]").allInnerTexts(),
|
53
|
+
);
|
54
|
+
|
55
|
+
await Promise.all([
|
56
|
+
page.waitForRequest((request) => request.method() === "DELETE"),
|
57
|
+
page.waitForResponse((response) => response.status() === 204),
|
58
|
+
page.click("button[data-testid=deleteContainer]"),
|
59
|
+
]);
|
60
|
+
|
61
|
+
await page.waitForSelector("button[data-testid=createContainer]");
|
62
|
+
|
63
|
+
// The child container should have been deleted.
|
64
|
+
await expect(
|
65
|
+
page.locator("span[data-testid=childContainerUrl]"),
|
66
|
+
).toContainText("None");
|
67
|
+
});
|
@@ -0,0 +1,30 @@
|
|
1
|
+
//
|
2
|
+
// Copyright Inrupt Inc.
|
3
|
+
//
|
4
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
// of this software and associated documentation files (the "Software"), to deal in
|
6
|
+
// the Software without restriction, including without limitation the rights to use,
|
7
|
+
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
8
|
+
// Software, and to permit persons to whom the Software is furnished to do so,
|
9
|
+
// subject to the following conditions:
|
10
|
+
//
|
11
|
+
// The above copyright notice and this permission notice shall be included in
|
12
|
+
// all copies or substantial portions of the Software.
|
13
|
+
//
|
14
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
15
|
+
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
16
|
+
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
17
|
+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
18
|
+
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
19
|
+
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
|
+
//
|
21
|
+
|
22
|
+
import { setupEnv } from "@inrupt/internal-test-env";
|
23
|
+
|
24
|
+
async function globalSetup() {
|
25
|
+
setupEnv();
|
26
|
+
// Return the teardown function.
|
27
|
+
return async () => {};
|
28
|
+
}
|
29
|
+
|
30
|
+
export default globalSetup;
|
@@ -0,0 +1,46 @@
|
|
1
|
+
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
|
2
|
+
|
3
|
+
## Getting Started
|
4
|
+
|
5
|
+
First, in the root of the project, run:
|
6
|
+
|
7
|
+
```bash
|
8
|
+
npm run build
|
9
|
+
```
|
10
|
+
|
11
|
+
Then, on the `test-app` directory, run:
|
12
|
+
|
13
|
+
```bash
|
14
|
+
npm ci
|
15
|
+
```
|
16
|
+
|
17
|
+
Then run the development server:
|
18
|
+
|
19
|
+
```bash
|
20
|
+
npm run dev
|
21
|
+
# or
|
22
|
+
yarn dev
|
23
|
+
```
|
24
|
+
|
25
|
+
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
26
|
+
|
27
|
+
You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file.
|
28
|
+
|
29
|
+
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
|
30
|
+
|
31
|
+
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
|
32
|
+
|
33
|
+
## Learn More
|
34
|
+
|
35
|
+
To learn more about Next.js, take a look at the following resources:
|
36
|
+
|
37
|
+
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
38
|
+
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
39
|
+
|
40
|
+
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
|
41
|
+
|
42
|
+
## Deploy on Vercel
|
43
|
+
|
44
|
+
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
45
|
+
|
46
|
+
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
@@ -0,0 +1,109 @@
|
|
1
|
+
//
|
2
|
+
// Copyright Inrupt Inc.
|
3
|
+
//
|
4
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
// of this software and associated documentation files (the "Software"), to deal in
|
6
|
+
// the Software without restriction, including without limitation the rights to use,
|
7
|
+
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
8
|
+
// Software, and to permit persons to whom the Software is furnished to do so,
|
9
|
+
// subject to the following conditions:
|
10
|
+
//
|
11
|
+
// The above copyright notice and this permission notice shall be included in
|
12
|
+
// all copies or substantial portions of the Software.
|
13
|
+
//
|
14
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
15
|
+
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
16
|
+
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
17
|
+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
18
|
+
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
19
|
+
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
|
+
//
|
21
|
+
|
22
|
+
// Disabling the following prevents from having to install before linting from
|
23
|
+
// the root.
|
24
|
+
// eslint-disable-next-line import/no-unresolved
|
25
|
+
import React, { useState, useEffect } from "react";
|
26
|
+
import {
|
27
|
+
login,
|
28
|
+
logout,
|
29
|
+
handleIncomingRedirect,
|
30
|
+
getDefaultSession,
|
31
|
+
ISessionInfo,
|
32
|
+
} from "@inrupt/solid-client-authn-browser";
|
33
|
+
import SolidClient from "../solidClient";
|
34
|
+
|
35
|
+
const REDIRECT_URL = window.location.href;
|
36
|
+
const APP_NAME = "Solid client browser-based tests app";
|
37
|
+
const DEFAULT_ISSUER = "https://login.inrupt.com/";
|
38
|
+
|
39
|
+
export default function AppContainer() {
|
40
|
+
const [sessionInfo, setSessionInfo] = useState<ISessionInfo>();
|
41
|
+
const [issuer, setIssuer] = useState<string>(DEFAULT_ISSUER);
|
42
|
+
|
43
|
+
useEffect(() => {
|
44
|
+
handleIncomingRedirect().then(setSessionInfo).catch(console.error);
|
45
|
+
}, []);
|
46
|
+
|
47
|
+
const handleLogin = async () => {
|
48
|
+
try {
|
49
|
+
// Login will redirect the user away so that they can log in the OIDC issuer,
|
50
|
+
// and back to the provided redirect URL (which should be controlled by your app).
|
51
|
+
await login({
|
52
|
+
redirectUrl: REDIRECT_URL,
|
53
|
+
oidcIssuer: issuer,
|
54
|
+
clientName: APP_NAME,
|
55
|
+
});
|
56
|
+
} catch (err) {
|
57
|
+
console.error(err);
|
58
|
+
}
|
59
|
+
};
|
60
|
+
|
61
|
+
const handleLogout = async () => {
|
62
|
+
await logout();
|
63
|
+
setSessionInfo(undefined);
|
64
|
+
};
|
65
|
+
|
66
|
+
return (
|
67
|
+
<>
|
68
|
+
<h1>{APP_NAME}</h1>
|
69
|
+
<p>
|
70
|
+
{sessionInfo?.isLoggedIn
|
71
|
+
? `Logged in as ${sessionInfo.webId}`
|
72
|
+
: "Not logged in yet"}
|
73
|
+
</p>
|
74
|
+
<form>
|
75
|
+
<input
|
76
|
+
data-testid="identityProviderInput"
|
77
|
+
type="text"
|
78
|
+
value={issuer}
|
79
|
+
onChange={(e) => {
|
80
|
+
setIssuer(e.target.value);
|
81
|
+
}}
|
82
|
+
/>
|
83
|
+
<button
|
84
|
+
data-testid="loginButton"
|
85
|
+
onClick={async (e) => {
|
86
|
+
e.preventDefault();
|
87
|
+
await handleLogin();
|
88
|
+
}}
|
89
|
+
>
|
90
|
+
Log In
|
91
|
+
</button>
|
92
|
+
<button
|
93
|
+
data-testid="logoutButton"
|
94
|
+
onClick={async (e) => {
|
95
|
+
e.preventDefault();
|
96
|
+
await handleLogout();
|
97
|
+
}}
|
98
|
+
>
|
99
|
+
Log Out
|
100
|
+
</button>
|
101
|
+
</form>
|
102
|
+
{sessionInfo?.isLoggedIn ? (
|
103
|
+
<SolidClient session={getDefaultSession()} />
|
104
|
+
) : (
|
105
|
+
<></>
|
106
|
+
)}
|
107
|
+
</>
|
108
|
+
);
|
109
|
+
}
|
@@ -0,0 +1,149 @@
|
|
1
|
+
//
|
2
|
+
// Copyright Inrupt Inc.
|
3
|
+
//
|
4
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
// of this software and associated documentation files (the "Software"), to deal in
|
6
|
+
// the Software without restriction, including without limitation the rights to use,
|
7
|
+
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
8
|
+
// Software, and to permit persons to whom the Software is furnished to do so,
|
9
|
+
// subject to the following conditions:
|
10
|
+
//
|
11
|
+
// The above copyright notice and this permission notice shall be included in
|
12
|
+
// all copies or substantial portions of the Software.
|
13
|
+
//
|
14
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
15
|
+
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
16
|
+
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
17
|
+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
18
|
+
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
19
|
+
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
|
+
//
|
21
|
+
|
22
|
+
// Disabling the following prevents from having to install before linting from
|
23
|
+
// the root.
|
24
|
+
// eslint-disable-next-line import/no-unresolved
|
25
|
+
import { useEffect, useState } from "react";
|
26
|
+
import {
|
27
|
+
createContainerInContainer,
|
28
|
+
getSourceIri,
|
29
|
+
deleteContainer,
|
30
|
+
getPodUrlAll,
|
31
|
+
} from "@inrupt/solid-client";
|
32
|
+
import { getDefaultSession, Session } from "@inrupt/solid-client-authn-browser";
|
33
|
+
|
34
|
+
interface CreateResourceButtonProps {
|
35
|
+
parentContainerUrl?: string;
|
36
|
+
handleCreateContainer: (containerUrl: string) => void;
|
37
|
+
}
|
38
|
+
|
39
|
+
const CreateResourceButton = ({
|
40
|
+
parentContainerUrl,
|
41
|
+
handleCreateContainer,
|
42
|
+
}: CreateResourceButtonProps) => {
|
43
|
+
return parentContainerUrl === undefined ? (
|
44
|
+
<></>
|
45
|
+
) : (
|
46
|
+
<button
|
47
|
+
onClick={async (e) => {
|
48
|
+
e.preventDefault();
|
49
|
+
handleCreateContainer(
|
50
|
+
getSourceIri(
|
51
|
+
await createContainerInContainer(parentContainerUrl, {
|
52
|
+
fetch: getDefaultSession().fetch,
|
53
|
+
}),
|
54
|
+
),
|
55
|
+
);
|
56
|
+
}}
|
57
|
+
data-testid="createContainer"
|
58
|
+
>
|
59
|
+
Create container
|
60
|
+
</button>
|
61
|
+
);
|
62
|
+
};
|
63
|
+
|
64
|
+
interface DeleteResourceButtonProps {
|
65
|
+
childContainerUrl?: string;
|
66
|
+
handleDeleteContainer: () => void;
|
67
|
+
}
|
68
|
+
|
69
|
+
const DeleteResourceButton = ({
|
70
|
+
childContainerUrl,
|
71
|
+
handleDeleteContainer,
|
72
|
+
}: DeleteResourceButtonProps) => {
|
73
|
+
return childContainerUrl === undefined ? (
|
74
|
+
<></>
|
75
|
+
) : (
|
76
|
+
<button
|
77
|
+
onClick={async (e) => {
|
78
|
+
e.preventDefault();
|
79
|
+
if (childContainerUrl !== undefined) {
|
80
|
+
await deleteContainer(childContainerUrl, {
|
81
|
+
fetch: getDefaultSession().fetch,
|
82
|
+
});
|
83
|
+
handleDeleteContainer();
|
84
|
+
}
|
85
|
+
}}
|
86
|
+
data-testid="deleteContainer"
|
87
|
+
>
|
88
|
+
Delete container
|
89
|
+
</button>
|
90
|
+
);
|
91
|
+
};
|
92
|
+
|
93
|
+
export default function SolidClient({ session }: { session: Session }) {
|
94
|
+
const [parentContainerUrl, setParentContainerUrl] = useState<string>();
|
95
|
+
const [childContainerUrl, setChildContainerUrl] = useState<
|
96
|
+
string | undefined
|
97
|
+
>();
|
98
|
+
|
99
|
+
const handleCreateContainer = (containerUrl: string) =>
|
100
|
+
setChildContainerUrl(containerUrl);
|
101
|
+
const handleDeleteContainer = () => setChildContainerUrl(undefined);
|
102
|
+
|
103
|
+
useEffect(() => {
|
104
|
+
if (session.info.webId !== undefined) {
|
105
|
+
getPodUrlAll(session.info.webId as string, {
|
106
|
+
fetch: session.fetch,
|
107
|
+
})
|
108
|
+
.then((pods) => {
|
109
|
+
if (pods.length === 0) {
|
110
|
+
throw new Error("No pod root in webid profile");
|
111
|
+
}
|
112
|
+
setParentContainerUrl(pods[0]);
|
113
|
+
})
|
114
|
+
.catch(console.error);
|
115
|
+
}
|
116
|
+
}, [session]);
|
117
|
+
|
118
|
+
return (
|
119
|
+
<>
|
120
|
+
<p>
|
121
|
+
Parent container:{" "}
|
122
|
+
<em>
|
123
|
+
<span data-testid="parentContainerUrl">
|
124
|
+
{parentContainerUrl ?? "None"}
|
125
|
+
</span>
|
126
|
+
</em>
|
127
|
+
</p>
|
128
|
+
<p>
|
129
|
+
Child container:{" "}
|
130
|
+
<em>
|
131
|
+
<span data-testid="childContainerUrl">
|
132
|
+
{childContainerUrl ?? "None"}
|
133
|
+
</span>
|
134
|
+
</em>
|
135
|
+
</p>
|
136
|
+
{childContainerUrl ? (
|
137
|
+
<DeleteResourceButton
|
138
|
+
childContainerUrl={childContainerUrl}
|
139
|
+
handleDeleteContainer={handleDeleteContainer}
|
140
|
+
/>
|
141
|
+
) : (
|
142
|
+
<CreateResourceButton
|
143
|
+
parentContainerUrl={parentContainerUrl}
|
144
|
+
handleCreateContainer={handleCreateContainer}
|
145
|
+
/>
|
146
|
+
)}
|
147
|
+
</>
|
148
|
+
);
|
149
|
+
}
|