├── .eslintignore ├── .eslintrc.js ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── codeql │ └── config.yml ├── dependabot.yml ├── pull_request_template.md └── workflows │ ├── audit.yml │ ├── ci.yml │ ├── codeql-analysis.yml │ ├── e2e-browser.yml │ ├── e2e-node.yml │ └── release.yml ├── .gitignore ├── .nvmrc ├── .prettierignore ├── ARCHITECTURE.md ├── CHANGELOG.md ├── CODE-OF-CONDUCT.md ├── CODEOWNERS ├── LICENSE ├── NOTICE-TEMPLATE ├── README.md ├── SECURITY.md ├── audit.json ├── documentation └── diagrams │ ├── README │ ├── auth_code_flow.pluml │ ├── auth_code_flow.svg │ ├── module_map.pluml │ ├── module_map.svg │ ├── refresh_flow.pluml │ └── refresh_flow.svg ├── e2e ├── browser │ ├── globalSetup.ts │ └── solid-client-authn-browser │ │ ├── test-app │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── layout.tsx │ │ │ └── page.tsx │ │ ├── components │ │ │ └── authenticatedFetch │ │ │ │ └── index.tsx │ │ ├── next-env.d.ts │ │ ├── next.config.js │ │ ├── package.json │ │ └── tsconfig.json │ │ └── test │ │ ├── e2e.playwright.ts │ │ ├── fixtures.ts │ │ ├── pageModels │ │ └── AppPage.ts │ │ └── scripts │ │ └── cleanup.ts ├── env │ └── .env.example └── node │ ├── jest.setup.ts │ ├── script │ └── e2e-test.spec.ts │ └── server │ ├── e2e-app-test.spec.ts │ ├── e2e-browser-script.spec.ts │ └── express.ts ├── jest.config.ts ├── jest.setup.ts ├── lerna.json ├── package-lock.json ├── package.json ├── packages ├── browser │ ├── .npmignore │ ├── .prettierignore │ ├── NOTICE │ ├── README.md │ ├── docs │ │ └── api │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── conf.py │ │ │ ├── redirects.txt │ │ │ └── source │ │ │ ├── functions.md │ │ │ └── index.rst │ ├── examples │ │ └── single │ │ │ ├── bundle │ │ │ ├── .babelrc │ │ │ ├── README.md │ │ │ ├── client-app-profile.jsonld │ │ │ ├── package.json │ │ │ ├── src │ │ │ │ ├── App.js │ │ │ │ ├── index.html │ │ │ │ └── index.js │ │ │ └── webpack.config.js │ │ │ └── script │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ └── server.mjs │ ├── package.json │ ├── rollup.config.mjs │ ├── sampleFlows │ │ ├── SolidAuthClientArchitecture.png │ │ ├── authorization-code-with-pkce.png │ │ ├── authorization-code-with-pkce.seqdiag │ │ ├── authorization-code.png │ │ ├── authorization-code.seqdiag │ │ ├── client-credentials.png │ │ ├── client-credentials.seqdiag │ │ ├── legacy-implicit-flow.png │ │ ├── legacy-implicit-flow.seqdiag │ │ ├── self-signed.png │ │ ├── self-signed.seqdiag │ │ ├── signatory-access-control.seqdiag │ │ └── signatory-access-control.svg │ ├── sonar-project.properties │ ├── src │ │ ├── ClientAuthentication.spec.ts │ │ ├── ClientAuthentication.ts │ │ ├── Session.spec.ts │ │ ├── Session.ts │ │ ├── __mocks__ │ │ │ └── ClientAuthentication.ts │ │ ├── constant.ts │ │ ├── defaultSession.spec.ts │ │ ├── defaultSession.ts │ │ ├── dependencies.node.spec.ts │ │ ├── dependencies.spec.ts │ │ ├── dependencies.ts │ │ ├── index.browser.spec.ts │ │ ├── index.browser.ts │ │ ├── index.spec.ts │ │ ├── index.ts │ │ ├── login │ │ │ ├── __mocks__ │ │ │ │ └── LoginHandler.ts │ │ │ └── oidc │ │ │ │ ├── AggregateOidcHandler.spec.ts │ │ │ │ ├── AggregateOidcHandler.ts │ │ │ │ ├── AggregateRedirectHandler.ts │ │ │ │ ├── ClientRegistrar.spec.ts │ │ │ │ ├── ClientRegistrar.ts │ │ │ │ ├── IssuerConfigFetcher.spec.ts │ │ │ │ ├── IssuerConfigFetcher.ts │ │ │ │ ├── OidcLoginHandler.spec.ts │ │ │ │ ├── OidcLoginHandler.ts │ │ │ │ ├── Redirector.spec.ts │ │ │ │ ├── Redirector.ts │ │ │ │ ├── __mocks__ │ │ │ │ ├── ClientRegistrar.ts │ │ │ │ ├── IOidcHandler.ts │ │ │ │ ├── IOidcOptions.ts │ │ │ │ ├── IssuerConfigFetcher.ts │ │ │ │ └── Redirector.ts │ │ │ │ ├── incomingRedirectHandler │ │ │ │ ├── AuthCodeRedirectHandler.spec.ts │ │ │ │ ├── AuthCodeRedirectHandler.ts │ │ │ │ ├── ErrorOidcHandler.spec.ts │ │ │ │ ├── ErrorOidcHandler.ts │ │ │ │ ├── FallbackRedirectHandler.spec.ts │ │ │ │ └── FallbackRedirectHandler.ts │ │ │ │ ├── oidcHandlers │ │ │ │ ├── AuthorizationCodeWithPkceOidcHandler.spec.ts │ │ │ │ ├── AuthorizationCodeWithPkceOidcHandler.ts │ │ │ │ └── OidcHandlerCanHandleTest.ts │ │ │ │ └── refresh │ │ │ │ ├── TokenRefresher.spec.ts │ │ │ │ ├── TokenRefresher.ts │ │ │ │ └── __mocks__ │ │ │ │ └── TokenRefresher.ts │ │ ├── logout │ │ │ └── buildRpInitiatedLogout.ts │ │ ├── sessionInfo │ │ │ ├── SessionInfoManager.spec.ts │ │ │ ├── SessionInfoManager.ts │ │ │ └── __mocks__ │ │ │ │ └── SessionInfoManager.ts │ │ ├── storage │ │ │ ├── BrowserStorage.spec.ts │ │ │ ├── BrowserStorage.ts │ │ │ ├── StorageUtility.ts │ │ │ └── __mocks__ │ │ │ │ └── LocalStorage.ts │ │ └── util │ │ │ ├── UUIDGenerator.spec.ts │ │ │ ├── UuidGenerator.ts │ │ │ └── __mocks__ │ │ │ └── UuidGenerator.ts │ └── tsconfig.json ├── core │ ├── .npmignore │ ├── .prettierignore │ ├── docs │ │ └── api │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── conf.py │ │ │ ├── redirects.txt │ │ │ └── source │ │ │ └── index.rst │ ├── package.json │ ├── rollup.config.mjs │ ├── sonar-project.properties │ ├── src │ │ ├── ClientAuthentication.ts │ │ ├── ILoginInputOptions.ts │ │ ├── Session.ts │ │ ├── SessionEventListener.ts │ │ ├── authenticatedFetch │ │ │ ├── dpopUtils.spec.ts │ │ │ ├── dpopUtils.ts │ │ │ ├── fetchFactory.spec.ts │ │ │ └── fetchFactory.ts │ │ ├── constant.ts │ │ ├── errors │ │ │ ├── ConfigurationError.ts │ │ │ ├── InvalidResponseError.ts │ │ │ ├── NotImplementedError.ts │ │ │ ├── OidcProviderError.ts │ │ │ └── errors.spec.ts │ │ ├── index.ts │ │ ├── login │ │ │ ├── ILoginHandler.ts │ │ │ ├── ILoginOptions.ts │ │ │ └── oidc │ │ │ │ ├── IClient.ts │ │ │ │ ├── IClientRegistrar.spec.ts │ │ │ │ ├── IClientRegistrar.ts │ │ │ │ ├── IIncomingRedirectHandler.ts │ │ │ │ ├── IIssuerConfig.ts │ │ │ │ ├── IIssuerConfigFetcher.ts │ │ │ │ ├── IOidcHandler.ts │ │ │ │ ├── IOidcOptions.ts │ │ │ │ ├── IRedirector.ts │ │ │ │ ├── __mocks__ │ │ │ │ ├── IncomingRedirectHandler.ts │ │ │ │ ├── IssuerConfig.ts │ │ │ │ └── IssuerConfigFetcher.ts │ │ │ │ ├── oidcHandlers │ │ │ │ └── AuthorizationCodeWithPkceOidcHandler.ts │ │ │ │ ├── redirectIriUtils.ts │ │ │ │ ├── redirectIriutils.spec.ts │ │ │ │ └── refresh │ │ │ │ ├── ITokenRefresher.ts │ │ │ │ └── __mocks__ │ │ │ │ └── TokenRefresher.ts │ │ ├── logout │ │ │ ├── GeneralLogoutHandler.spec.ts │ │ │ ├── GeneralLogoutHandler.ts │ │ │ ├── ILogoutHandler.ts │ │ │ ├── IWaterfallLogoutHandler.ts │ │ │ ├── RpLogoutHandler.spec.ts │ │ │ ├── RpLogoutHandler.ts │ │ │ ├── __mocks__ │ │ │ │ └── LogoutHandler.ts │ │ │ └── endSessionUrl.ts │ │ ├── mocks.spec.ts │ │ ├── mocks.ts │ │ ├── sessionInfo │ │ │ ├── ISessionInfo.spec.ts │ │ │ ├── ISessionInfo.ts │ │ │ ├── ISessionInfoManager.spec.ts │ │ │ ├── ISessionInfoManager.ts │ │ │ ├── SessionInfoManager.ts │ │ │ └── __mocks__ │ │ │ │ └── SessionInfoManager.ts │ │ ├── storage │ │ │ ├── IStorage.ts │ │ │ ├── IStorageUtility.ts │ │ │ ├── InMemoryStorage.spec.ts │ │ │ ├── InMemoryStorage.ts │ │ │ ├── StorageUtility.spec.ts │ │ │ ├── StorageUtility.ts │ │ │ └── __mocks__ │ │ │ │ └── StorageUtility.ts │ │ └── util │ │ │ ├── handlerPattern │ │ │ ├── AggregateHandler.spec.ts │ │ │ ├── AggregateHandler.ts │ │ │ └── IHandleable.ts │ │ │ ├── token.spec.ts │ │ │ └── token.ts │ └── tsconfig.json ├── node │ ├── .npmignore │ ├── .prettierignore │ ├── README.md │ ├── docs │ │ └── api │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── conf.py │ │ │ ├── redirects.txt │ │ │ └── source │ │ │ ├── functions.md │ │ │ └── index.rst │ ├── examples │ │ ├── script │ │ │ ├── .env.example │ │ │ ├── README.md │ │ │ ├── index.mjs │ │ │ └── package.json │ │ └── server │ │ │ ├── .env.example │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ └── src │ │ │ └── serverSideApp.mjs │ ├── package.json │ ├── rollup.config.mjs │ ├── sonar-project.properties │ ├── src │ │ ├── ClientAuthentication.spec.ts │ │ ├── ClientAuthentication.ts │ │ ├── Session.spec.ts │ │ ├── Session.static.spec.ts │ │ ├── Session.ts │ │ ├── __mocks__ │ │ │ └── ClientAuthentication.ts │ │ ├── authenticatedFetch │ │ │ └── headers │ │ │ │ ├── HeadersUtils.spec.ts │ │ │ │ └── HeadersUtils.ts │ │ ├── constant.ts │ │ ├── dependencies.spec.ts │ │ ├── dependencies.ts │ │ ├── index.spec.ts │ │ ├── index.ts │ │ ├── login │ │ │ ├── __mocks__ │ │ │ │ └── LoginHandler.ts │ │ │ └── oidc │ │ │ │ ├── AggregateIncomingRedirectHandler.ts │ │ │ │ ├── AggregateOidcHandler.spec.ts │ │ │ │ ├── AggregateOidcHandler.ts │ │ │ │ ├── ClientRegistrar.spec.ts │ │ │ │ ├── ClientRegistrar.ts │ │ │ │ ├── IssuerConfigFetcher.spec.ts │ │ │ │ ├── IssuerConfigFetcher.ts │ │ │ │ ├── OidcLoginHandler.spec.ts │ │ │ │ ├── OidcLoginHandler.ts │ │ │ │ ├── Redirector.spec.ts │ │ │ │ ├── Redirector.ts │ │ │ │ ├── TokenRequester.spec.ts │ │ │ │ ├── TokenRequester.ts │ │ │ │ ├── __mocks__ │ │ │ │ ├── ClientRegistrar.ts │ │ │ │ ├── IOidcHandler.ts │ │ │ │ ├── IOidcOptions.ts │ │ │ │ ├── IssuerConfigFetcher.ts │ │ │ │ └── Redirector.ts │ │ │ │ ├── incomingRedirectHandler │ │ │ │ ├── AuthCodeRedirectHandler.spec.ts │ │ │ │ ├── AuthCodeRedirectHandler.ts │ │ │ │ ├── FallbackRedirectHandler.spec.ts │ │ │ │ └── FallbackRedirectHandler.ts │ │ │ │ ├── oidcHandlers │ │ │ │ ├── AuthorizationCodeWithPkceOidcHandler.spec.ts │ │ │ │ ├── AuthorizationCodeWithPkceOidcHandler.ts │ │ │ │ ├── ClientCredentialsOidcHandler.spec.ts │ │ │ │ ├── ClientCredentialsOidcHandler.ts │ │ │ │ ├── OidcHandlerCanHandleTests.ts │ │ │ │ ├── RefreshTokenOidcHandler.spec.ts │ │ │ │ └── RefreshTokenOidcHandler.ts │ │ │ │ └── refresh │ │ │ │ ├── TokenRefresher.spec.ts │ │ │ │ ├── TokenRefresher.ts │ │ │ │ └── __mocks__ │ │ │ │ └── TokenRefresher.ts │ │ ├── multiSession.fromTokens.spec.ts │ │ ├── multiSession.spec.ts │ │ ├── multiSession.ts │ │ ├── multisession.fromTokens.ts │ │ ├── sessionInfo │ │ │ ├── SessionInfoManager.spec.ts │ │ │ ├── SessionInfoManager.ts │ │ │ └── __mocks__ │ │ │ │ └── SessionInfoManager.ts │ │ ├── storage │ │ │ └── StorageUtility.ts │ │ └── util │ │ │ ├── UuidGenerator.spec.ts │ │ │ ├── UuidGenerator.ts │ │ │ └── __mocks__ │ │ │ └── UuidGenerator.ts │ └── tsconfig.json └── oidc-browser │ ├── .npmignore │ ├── .prettierignore │ ├── README.md │ ├── package.json │ ├── rollup.config.mjs │ ├── sonar-project.properties │ ├── src │ ├── __mocks__ │ │ └── issuer.mocks.ts │ ├── cleanup │ │ ├── cleanup.spec.ts │ │ └── cleanup.ts │ ├── dcr │ │ ├── clientRegistrar.spec.ts │ │ └── clientRegistrar.ts │ ├── dpop │ │ ├── tokenExchange.spec.ts │ │ └── tokenExchange.ts │ ├── index.ts │ └── refresh │ │ ├── refreshGrant.spec.ts │ │ └── refreshGrant.ts │ └── tsconfig.json ├── playwright.client-authn.config.ts ├── playwright.client-authn.constants.json ├── playwright.shared.config.ts ├── tests └── environment │ └── customEnvironment.ts ├── tsconfig.build.json ├── tsconfig.json └── vercel.json /.eslintignore: -------------------------------------------------------------------------------- 1 | resources/ 2 | node_modules/ 3 | **/docs/** 4 | **/.eslintrc.js 5 | build/ 6 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a bug report to help us improve 4 | title: "" 5 | labels: "bug" 6 | assignees: "" 7 | --- 8 | 9 | 14 | 15 | ### Search terms you've used 16 | 17 | 18 | 19 | ### Impacted package 20 | 21 | Which packages do you think might be impacted by the bug ? 22 | 23 | - [ ] solid-client-authn-browser 24 | - [ ] solid-client-authn-node 25 | - [ ] solid-client-authn-core 26 | - [ ] oidc-client-ext 27 | - [ ] Other (please specify): ... 28 | 29 | ### Bug description 30 | 31 | 32 | 33 | ### To Reproduce 34 | 35 | 1. 36 | 2. 37 | 3. 38 | 4. 39 | 40 | ### Expected result 41 | 42 | 43 | 44 | ### Actual result 45 | 46 | 47 | 48 | ### Environment 49 | 50 | Please run 51 | 52 | npx envinfo --system --npmPackages --binaries --npmGlobalPackages --browsers 53 | 54 | in your project folder and paste the output here: 55 | 56 | ``` 57 | $ npx envinfo --system --npmPackages --binaries --npmGlobalPackages --browsers 58 | ``` 59 | 60 | ## Additional information 61 | 62 | 63 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for a new feature 4 | title: "" 5 | labels: "enhancement" 6 | assignees: "" 7 | --- 8 | 9 | 14 | 15 | ### Search terms you've used 16 | 17 | 18 | 19 | ### Impacted environment 20 | 21 | In which environment would the proposed feature apply ? 22 | 23 | - [ ] The browser 24 | - [ ] Node.js 25 | - [ ] Other (please specify): ... 26 | - [ ] I'm not sure. 27 | 28 | ### Feature suggestion 29 | 30 | 31 | 32 | ### Expected functionality/enhancement 33 | 34 | 35 | 36 | ### Actual functionality/enhancement 37 | 38 | 39 | 40 | ### Use Cases 41 | 42 | 46 | 47 | ### Additional information 48 | 49 | 50 | -------------------------------------------------------------------------------- /.github/codeql/config.yml: -------------------------------------------------------------------------------- 1 | paths-ignore: 2 | - "**/examples" 3 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | # Enable version updates for our CI github-actions. 4 | - package-ecosystem: "github-actions" 5 | # For GitHub Actions, setting the directory to / will check for workflow 6 | # files in .github/workflows. 7 | directory: "/" 8 | schedule: 9 | interval: "weekly" 10 | - package-ecosystem: npm 11 | directory: "/" 12 | schedule: 13 | interval: weekly 14 | open-pull-requests-limit: 10 15 | # The following is required for workspaces to be updated: see https://github.com/dependabot/dependabot-core/issues/5226. 16 | versioning-strategy: increase 17 | ignore: 18 | - dependency-name: "eslint" 19 | update-types: ["version-update:semver-major"] 20 | - dependency-name: "@typescript-eslint/eslint-plugin" 21 | update-types: ["version-update:semver-major"] 22 | - dependency-name: "typedoc-plugin-markdown" 23 | update-types: ["version-update:semver-major"] 24 | groups: 25 | internal-tooling: 26 | patterns: 27 | - "@inrupt/internal-*" 28 | - "@inrupt/base-*" 29 | - "@inrupt/jest-*" 30 | - "@inrupt/eslint-*" 31 | external-types: 32 | patterns: 33 | - "@types/*" 34 | - package-ecosystem: npm 35 | directory: "/e2e/browser/solid-client-authn-browser/test-app" 36 | schedule: 37 | interval: weekly 38 | ignore: 39 | - dependency-name: "eslint" 40 | update-types: ["version-update:semver-major"] 41 | open-pull-requests-limit: 10 42 | - package-ecosystem: npm 43 | directory: "/packages/browser/examples/single/native" 44 | schedule: 45 | interval: weekly 46 | open-pull-requests-limit: 10 47 | - package-ecosystem: npm 48 | directory: "/packages/browser/examples/single/script" 49 | schedule: 50 | interval: weekly 51 | open-pull-requests-limit: 10 52 | - package-ecosystem: "pip" 53 | directory: "/packages/browser/docs/api" 54 | schedule: 55 | interval: "weekly" 56 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | This PR fixes bug #. 4 | 5 | - [ ] I've added a unit test to test for potential regressions of this bug. 6 | - [ ] The changelog has been updated, if applicable. 7 | - [ ] Commits in this PR are minimal and [have descriptive commit messages](https://chris.beams.io/posts/git-commit/). 8 | 9 | 10 | 11 | # New feature description 12 | 13 | # Checklist 14 | 15 | - [ ] All acceptance criteria are met. 16 | - [ ] Relevant documentation, if any, has been written/updated. 17 | - [ ] The changelog has been updated, if applicable. 18 | - [ ] New functions/types have been exported in `index.ts`, if applicable. 19 | - [ ] Commits in this PR are minimal and [have descriptive commit messages](https://chris.beams.io/posts/git-commit/). 20 | 21 | 22 | 23 | This PR bumps the version to . 24 | 25 | # Release Steps 26 | 27 | 1. Look at the [CHANGELOG.md](../CHANGELOG.md) to determine whether the release should be a major, minor, or patch release. Coordinate with the team to ensure the next version is agreed upon. 28 | 2. Run `npm run lerna-version -- ` with the decided on version. 29 | 3. Update the `CHANGELOG.md` to release the latest the version, and set the release date. 30 | 4. Commit the changes on a `release/vX.Y.Z` branch 31 | 5. Push to GitHub, create a PR, and merge once CI passes. 32 | 6. Create a release on GitHub for the new version, using a combination of the release notes from the `CHANGELOG.md` and the automatically generated changes. 33 | -------------------------------------------------------------------------------- /.github/workflows/audit.yml: -------------------------------------------------------------------------------- 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: inrupt/typescript-sdk-tools/.github/workflows/reusable-audit.yml@v3 13 | secrets: 14 | WEBHOOK_E2E_FAILURE: ${{ secrets.WEBHOOK_E2E_FAILURE }} 15 | -------------------------------------------------------------------------------- /.github/workflows/e2e-node.yml: -------------------------------------------------------------------------------- 1 | name: End-to-end node tests 2 | 3 | on: 4 | push: 5 | workflow_dispatch: 6 | concurrency: 7 | group: ${{ github.workflow }}-${{ github.ref }} 8 | cancel-in-progress: true 9 | env: 10 | CI: true 11 | jobs: 12 | e2e-node: 13 | runs-on: ${{ matrix.os }} 14 | environment: 15 | name: ${{ matrix.environment-name }} 16 | continue-on-error: ${{ matrix.experimental }} 17 | strategy: 18 | matrix: 19 | os: [ubuntu-latest] 20 | node-version: ["22.x", "20.x", "18.x"] 21 | environment-name: ["ESS PodSpaces", "ESS Release-2-3", "ESS Dev-2-4"] 22 | experimental: [false] 23 | steps: 24 | - uses: actions/checkout@v4 25 | - uses: actions/setup-node@v4 26 | with: 27 | node-version: ${{ matrix.node-version }} 28 | cache: npm 29 | - run: npm ci 30 | if: github.actor != 'dependabot[bot]' 31 | - name: Install e2e tests dependencies 32 | run: npx playwright install --with-deps 33 | if: github.actor != 'dependabot[bot]' 34 | - # Dependabot cannot access secrets, so it doesn't have a token to authenticate to ESS. 35 | # We want jobs in this workflow to be gating PRs, so the whole matrix must 36 | # run even for dependabot so that the matrixed jobs are skipped, instead 37 | # of the whole pipeline. 38 | if: ${{ github.actor != 'dependabot[bot]' }} 39 | run: npm run test:e2e:node:all 40 | env: 41 | E2E_TEST_IDP: ${{ secrets.E2E_TEST_IDP }} 42 | E2E_TEST_OWNER_CLIENT_ID: ${{ secrets.E2E_TEST_OWNER_CLIENT_ID }} 43 | E2E_TEST_OWNER_CLIENT_SECRET: ${{ secrets.E2E_TEST_OWNER_CLIENT_SECRET }} 44 | E2E_TEST_ENVIRONMENT: ${{ matrix.environment-name }} 45 | E2E_TEST_USER: ${{ secrets.E2E_TEST_USER }} 46 | E2E_TEST_PASSWORD: ${{ secrets.E2E_TEST_PASSWORD }} 47 | 48 | check: 49 | if: always() 50 | needs: 51 | - e2e-node 52 | runs-on: ubuntu-latest 53 | steps: 54 | - name: Decide whether the needed jobs succeeded or failed 55 | uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # release/v1 56 | with: 57 | allowed-skips: e2e-node 58 | jobs: ${{ toJSON(needs) }} 59 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: CD-release 2 | 3 | on: 4 | push: 5 | tags: 6 | - v[0-9]+.[0-9]+.[0-9]+ 7 | 8 | env: 9 | CI: true 10 | jobs: 11 | publish-npm: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v4 15 | - name: Prepare for publication to npm 16 | uses: actions/setup-node@v4 17 | with: 18 | node-version-file: ".nvmrc" 19 | registry-url: "https://registry.npmjs.org" 20 | cache: npm 21 | - run: npm ci 22 | - run: npm run publish -- from-package --no-verify-access --yes 23 | env: 24 | NODE_AUTH_TOKEN: ${{ secrets.INRUPT_NPM_TOKEN }} 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # OS Specififc 9 | .DS_Store 10 | 11 | # TypeScript build result 12 | dist 13 | browserDist 14 | 15 | # Runtime data 16 | pids 17 | *.pid 18 | *.seed 19 | *.pid.lock 20 | 21 | # Directory for instrumented libs generated by jscoverage/JSCover 22 | lib-cov 23 | 24 | # Coverage directory used by tools like istanbul 25 | coverage 26 | 27 | # Output from https://github.com/w3c/ldp-testsuite 28 | report 29 | test-output 30 | 31 | # nyc test coverage 32 | .nyc_output 33 | 34 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 35 | .grunt 36 | 37 | # Bower dependency directory (https://bower.io/) 38 | bower_components 39 | 40 | # node-waf configuration 41 | .lock-wscript 42 | 43 | # Compiled binary addons (https://nodejs.org/api/addons.html) 44 | build/Release 45 | 46 | # Dependency directories 47 | node_modules/ 48 | jspm_packages/ 49 | 50 | # TypeScript v1 declaration files 51 | typings/ 52 | 53 | # Optional npm cache directory 54 | .npm 55 | 56 | # Optional eslint cache 57 | .eslintcache 58 | 59 | # Optional REPL history 60 | .node_repl_history 61 | 62 | # Output of 'npm pack' 63 | *.tgz 64 | 65 | # Yarn Integrity file 66 | .yarn-integrity 67 | 68 | # dotenv environment variables file 69 | .env*.local 70 | config.json 71 | data 72 | 73 | # next.js build output 74 | .next 75 | 76 | # IDEs 77 | .idea 78 | .vscode 79 | 80 | # Lerna 81 | lerna-debug.log 82 | packages/*/lib 83 | 84 | # Documentation 85 | packages/**/docs/prose/build/ 86 | packages/**/docs/api/build/ 87 | packages/**/docs/api/source/api/ 88 | packages/**/docs/dist/ 89 | 90 | # Examples 91 | build/ 92 | 93 | # Rollup-built code 94 | umd/ 95 | 96 | # license-checker 97 | license.csv 98 | 99 | # playright tests output 100 | test-results/ 101 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 22 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | build/ 2 | dist/ 3 | browserDist/ 4 | node_modules/ 5 | docs/ 6 | resources/ 7 | sampleFlows/ 8 | coverage/ 9 | docs/**/*.md 10 | packages/*/docs/**/*.md 11 | **/.next/ 12 | **/umd/ 13 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @inrupt/engineering 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Begin license text. 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 | End license text.Source Distributions 22 | -------------------------------------------------------------------------------- /NOTICE-TEMPLATE: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # This file is intended as a template, to be copied to contained packages and 4 | # edited as appropriate for that particular package (including deleting this 5 | # template pre-amble!), and renamed to remove the '-TEMPLATE' suffix. 6 | # 7 | ############################################################################### 8 | 9 | Inrupt `solid-client-authn-XXXX` 10 | Copyright 2021 Inrupt Inc. 11 | 12 | This product includes software developed at 13 | Inrupt Inc. (https://inrupt.com/). -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security policy 2 | 3 | This document gathers security-related policies and guidelines for the codebase 4 | available in this repository. 5 | 6 | Authentication is a sensitive domain, and as such we designed the `@inrupt/solid-client-authn-*` 7 | libraries with a particular attention to security. In particular, 8 | we decided to apply the following rules: 9 | 10 | - Comply with the [OAuth security guidelines](https://tools.ietf.org/id/draft-ietf-oauth-security-topics-15.html) 11 | This involves, among other things: 12 | - No support for the implicit grant and the resource owner password grant 13 | - The use of a PKCE token 14 | - Binding tokens to a DPoP key to make them sender-constrained whenever possible 15 | - Short-lived tokens (e.g., ID token and Access token) and private cryptographic 16 | material (e.g. a DPoP private key) are only stored in a function closure, so that 17 | they may not be extracted once received from the remote server. These protected 18 | elements will not be made available directly (e.g. through a function call) or 19 | indirectly (e.g. allowing to sign a header with the DPoP key) to any third-party. 20 | - Longer-lived tokens (e.g. refresh tokens) are only stored in a secure storage, 21 | i.e., a storage which isn't shared beyond the library's control. This means not using 22 | the `localStorage` and `sessionStorage` in browsers. 23 | - If these restrictions on the high-level layer are blocking some legitimate use 24 | cases, the options is added when possible for advanced users to drop down to a 25 | lower-level API where token and key management is left to the dependant, and no 26 | longer a concern of the library. 27 | 28 | # Reporting a vulnerability 29 | 30 | If you discover a vulnerability in our code, or experience a bug related to security, 31 | please report it following the instructions provided on [Inrupt’s security page](https://inrupt.com/security/). 32 | -------------------------------------------------------------------------------- /audit.json: -------------------------------------------------------------------------------- 1 | { 2 | "auditReportVersion": 2, 3 | "vulnerabilities": {}, 4 | "metadata": { 5 | "vulnerabilities": { 6 | "info": 0, 7 | "low": 0, 8 | "moderate": 0, 9 | "high": 0, 10 | "critical": 0, 11 | "total": 0 12 | }, 13 | "dependencies": { 14 | "prod": 205, 15 | "dev": 1789, 16 | "optional": 26, 17 | "peer": 18, 18 | "peerOptional": 0, 19 | "total": 2005 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /documentation/diagrams/README: -------------------------------------------------------------------------------- 1 | The diagrams in this directory are generated using [PlantUML](https://plantuml.com/). 2 | 3 | Example usage: 4 | ``` 5 | plantuml auth_code_flow.pluml -tsvg 6 | ``` 7 | 8 | This command will generate `auth_code_flow.svg`. -------------------------------------------------------------------------------- /documentation/diagrams/auth_code_flow.pluml: -------------------------------------------------------------------------------- 1 | @startuml 2 | 3 | hide footbox 4 | 5 | participant Issuer as "OIDC issuer" 6 | actor RO as "Resource Owner (browser)" 7 | participant Client 8 | participant "Solid Server" 9 | 10 | == Front channel == 11 | 12 | RO -> Client: Initiates login 13 | activate Client 14 | Client -> Client: Session::login 15 | Client -> Issuer: Discovery 16 | Client -> Issuer: Registration (optional) 17 | Client -> Client: OIDC handler 18 | Client -> RO: Redirect browser to authorization endpoint 19 | deactivate Client 20 | RO -> Issuer: Logs in 21 | Issuer -> RO: Redirects browser with authorization code 22 | RO -> Client: Reloads app at redirect IRI 23 | activate Client 24 | Client -> Client: Handle incoming redirect 25 | 26 | == Back channel == 27 | 28 | Client -> Issuer: Sends code to token endpoint 29 | Issuer -> Client: Sends Access, ID and (optional) Refresh Tokens 30 | Client -> Client: Initializes authenticated fetch 31 | Client -> "Solid Server": Accesses the protected resource\nwith the access token 32 | 33 | @enduml 34 | -------------------------------------------------------------------------------- /documentation/diagrams/module_map.pluml: -------------------------------------------------------------------------------- 1 | @startuml 2 | 3 | 4 | package "Client libraries" { 5 | [@inrupt/solid-client-authn-browser] 6 | [@inrupt/solid-client-authn-node] 7 | } 8 | 9 | [@inrupt/oidc-client-ext] --> [@inrupt/oidc-client]: depends on 10 | [@inrupt/solid-client-authn-browser] --> [@inrupt/solid-client-authn-core]: depends on 11 | [@inrupt/solid-client-authn-browser] --> [@inrupt/oidc-client-ext]: depends on 12 | [@inrupt/solid-client-authn-node] --> [@inrupt/solid-client-authn-core]: depends on 13 | [@inrupt/solid-client-authn-node] --> [openid-client]: depends on 14 | [@inrupt/oidc-client-ext] --> [@inrupt/solid-client-authn-core]: depends on 15 | 16 | 17 | @enduml 18 | -------------------------------------------------------------------------------- /documentation/diagrams/refresh_flow.pluml: -------------------------------------------------------------------------------- 1 | @startuml 2 | 3 | actor RO as "Resource Owner (browser)" 4 | participant Issuer as "OIDC issuer" 5 | participant Client 6 | participant RS as "Solid Server" 7 | 8 | hide footbox 9 | 10 | note over Issuer, Client 11 | Assuming that the Client already has a Refresh Token 12 | end note 13 | 14 | == Back channel == 15 | 16 | activate Client 17 | Client -> Issuer: Sends Refresh Token to token endpoint 18 | Issuer -> Client: Sends Access, ID and (optional) rotated Refresh Tokens 19 | Client -> Client: Initializes authenticated fetch 20 | Client -> RS: Accesses the protected resource\nwith the access token 21 | 22 | @enduml 23 | -------------------------------------------------------------------------------- /e2e/browser/globalSetup.ts: -------------------------------------------------------------------------------- 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 | // Fail fast with dotenv: 26 | setupEnv(); 27 | 28 | // Return the teardown function. 29 | return async () => {}; 30 | } 31 | export default globalSetup; 32 | -------------------------------------------------------------------------------- /e2e/browser/solid-client-authn-browser/test-app/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | -------------------------------------------------------------------------------- /e2e/browser/solid-client-authn-browser/test-app/README.md: -------------------------------------------------------------------------------- 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, run the development server: 6 | 7 | ```bash 8 | npm run dev 9 | # or 10 | yarn dev 11 | ``` 12 | 13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 14 | 15 | You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file. 16 | 17 | [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`. 18 | 19 | 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. 20 | 21 | ## Learn More 22 | 23 | To learn more about Next.js, take a look at the following resources: 24 | 25 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. 26 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. 27 | 28 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! 29 | 30 | ## Deploy on Vercel 31 | 32 | 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. 33 | 34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. 35 | -------------------------------------------------------------------------------- /e2e/browser/solid-client-authn-browser/test-app/app/layout.tsx: -------------------------------------------------------------------------------- 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 | export default function TestAppLayout({ 22 | children, 23 | }: { 24 | children: React.ReactNode; 25 | }) { 26 | return ( 27 | 28 | 29 |
{children}
30 | 31 | 32 | ); 33 | } 34 | -------------------------------------------------------------------------------- /e2e/browser/solid-client-authn-browser/test-app/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. 6 | -------------------------------------------------------------------------------- /e2e/browser/solid-client-authn-browser/test-app/next.config.js: -------------------------------------------------------------------------------- 1 | const nextConfig = { 2 | reactStrictMode: true, 3 | }; 4 | 5 | module.exports = nextConfig; 6 | -------------------------------------------------------------------------------- /e2e/browser/solid-client-authn-browser/test-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-app", 3 | "version": "2.5.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint", 10 | "test:esbuild": "esbuild app/page.tsx --bundle" 11 | }, 12 | "dependencies": { 13 | "@inrupt/internal-playwright-testids": "^3.2.6", 14 | "@inrupt/solid-client-authn-browser": "^2.5.0", 15 | "next": "^15.3.3", 16 | "react": "^19.0.0", 17 | "react-dom": "^19.1.0" 18 | }, 19 | "devDependencies": { 20 | "@inrupt/eslint-config-lib": "^3.2.7", 21 | "@playwright/test": "^1.52.0", 22 | "@types/node": "^22.15.30", 23 | "@types/react": "^19.1.6", 24 | "@types/react-dom": "^19.1.6", 25 | "esbuild": "^0.25.4", 26 | "eslint": "^8.57.1", 27 | "eslint-config-next": "^15.3.3" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /e2e/browser/solid-client-authn-browser/test-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "noEmit": true, 14 | "esModuleInterop": true, 15 | "module": "esnext", 16 | "moduleResolution": "node", 17 | "resolveJsonModule": true, 18 | "isolatedModules": true, 19 | "jsx": "preserve", 20 | "incremental": true, 21 | "plugins": [ 22 | { 23 | "name": "next" 24 | } 25 | ] 26 | }, 27 | "include": [ 28 | "**/*.ts", 29 | "**/*.tsx", 30 | "next-env.d.ts", 31 | ".next/types/**/*.ts" 32 | ], 33 | "exclude": [ 34 | "node_modules" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /e2e/env/.env.example: -------------------------------------------------------------------------------- 1 | # Copy-paste this example file into a .env.test.local and fill in the missing values. 2 | # Note that you can have multiple local environments side by side, e.g. .env.dev.local 3 | # and .env.nss.local, and select which should be loaded by setting the `NODE_ENV` 4 | # environment variable. For instance, running `NODE_ENV=dev npm run test:e2e:node` 5 | # will load .env.dev.local. 6 | 7 | # Environment name. See https://github.com/inrupt/typescript-sdk-tools/tree/main/packages/internal-test-env. 8 | # Examples: "ESS Podspaces" 9 | E2E_TEST_ENVIRONMENT=Some environment 10 | 11 | # Mark the features you want to test if any 12 | # E2E_TEST_FEATURE_X=true 13 | 14 | E2E_TEST_IDP= 15 | # Obtain credentials registering to your selected identity provider, e.g. via 16 | # https://login.inrupt.com/registration.html or https://openid.dev-next.inrupt.com/registration.html 17 | E2E_TEST_OWNER_CLIENT_ID= 18 | E2E_TEST_OWNER_CLIENT_SECRET= 19 | 20 | # The following are your login and password, used to login into your OpenID Provider, e.g. https://login.inrupt.com/ 21 | E2E_TEST_USER= 22 | E2E_TEST_PASSWORD= 23 | 24 | # Pods are provisionned differently depending on the provider. For examples, see 25 | # https://provision.inrupt.com or https://provision.dev-next.inrupt.com 26 | E2E_TEST_POD= 27 | -------------------------------------------------------------------------------- /e2e/node/jest.setup.ts: -------------------------------------------------------------------------------- 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 | // Fail fast on dotenv: 25 | setupEnv(); 26 | -------------------------------------------------------------------------------- /jest.setup.ts: -------------------------------------------------------------------------------- 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 "@inrupt/jest-jsdom-polyfills"; 23 | globalThis.fetch = async () => new Response(); 24 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "useNx": true, 3 | "version": "2.5.0" 4 | } 5 | -------------------------------------------------------------------------------- /packages/browser/.npmignore: -------------------------------------------------------------------------------- 1 | .git 2 | docs 3 | coverage 4 | report 5 | .vscode 6 | examples 7 | sampleFlows/ 8 | .prettierignore 9 | README.md 10 | sonar-project.properties 11 | -------------------------------------------------------------------------------- /packages/browser/.prettierignore: -------------------------------------------------------------------------------- 1 | # TODO: figure out why the root .prettierignore file isn't detected: 2 | docs/**/*.md 3 | examples/**/*.md 4 | -------------------------------------------------------------------------------- /packages/browser/NOTICE: -------------------------------------------------------------------------------- 1 | Inrupt `solid-client-authn-core` 2 | Copyright 2021 Inrupt Inc. 3 | 4 | This product includes software developed at 5 | Inrupt Inc. (https://inrupt.com/). -------------------------------------------------------------------------------- /packages/browser/docs/api/README.md: -------------------------------------------------------------------------------- 1 | # apidocs 2 | 3 | Builds the API docs site from generated api \*.md files. 4 | 5 | ## To Build 6 | 7 | To build: 8 | 9 | 0. Prereq: [python3](https://www.python.org/downloads/), [Node.js](https://nodejs.org/). 10 | 11 | 1. Optional but recommended. Create a virtual env: 12 | 13 | ```sh 14 | python3 -m venv 15 | source /bin/activate 16 | ``` 17 | 18 | 1. Generate the API .md files: 19 | 20 | npm ci; npm run build-api-docs 21 | 22 | 1. Go to the apidocs directory: 23 | 24 | cd apidocs 25 | 26 | 1. Install the docs requirements (different from library docs requirements): 27 | 28 | ```sh 29 | pip install -r https://raw.githubusercontent.com/inrupt/docs-assets/main/requirements/api/requirements.txt 30 | ``` 31 | 32 | 1. Make the API docs: 33 | 34 | ```sh 35 | make html 36 | ``` 37 | 38 | There should be a `build/html` directory with the html artifacts. 39 | 40 | When finished, can deactivate your virtual env. 41 | 42 | ## Third Party Licenses 43 | 44 | The `requirements.txt` lists the 3rd party libraries used for the docs. 45 | For the licenses, see the shared 46 | [inrupt/docs-assets](https://github.com/inrupt/docs-assets#readme). 47 | -------------------------------------------------------------------------------- /packages/browser/docs/api/source/functions.md: -------------------------------------------------------------------------------- 1 | # Functions 2 | 3 | -------------------------------------------------------------------------------- /packages/browser/docs/api/source/index.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | ============================== 4 | solid-client-authn-browser API 5 | ============================== 6 | 7 | .. COMMENT: If we want left hand side in specific order, we'll have to be specific in the toctree. For now, will just use the default alphabetical order. 8 | 9 | .. toctree:: 10 | :glob: 11 | :titlesonly: 12 | 13 | ** -------------------------------------------------------------------------------- /packages/browser/examples/single/bundle/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env", "@babel/preset-react"] 3 | } 4 | -------------------------------------------------------------------------------- /packages/browser/examples/single/bundle/README.md: -------------------------------------------------------------------------------- 1 | # `solid-client-authn-browser` sample app 2 | 3 | This application provides a snippet of code showcasing usage of the 4 | `solid-client-authn-browser` library in React components, with a bundler. 5 | 6 | ## Install and run 7 | 8 | - Run `npm ci` in the **root** directory, to build `solid-client-authn-browser`. 9 | - Run `npm ci` in the current directory, to build the sample app. 10 | - Run `npm run dev` to start the app. It should automatically open 11 | `http://localhost:3001/` in a browser window. 12 | -------------------------------------------------------------------------------- /packages/browser/examples/single/bundle/client-app-profile.jsonld: -------------------------------------------------------------------------------- 1 | { 2 | "@context": ["https://www.w3.org/ns/solid/oidc-context.jsonld"], 3 | "client_id": "https://example.org/your-client-id", 4 | "client_name": "solid-client-authn-browser demo", 5 | "redirect_uris": ["http://localhost:3113/"], 6 | "grant_types" : ["refresh_token","authorization_code"], 7 | "token_endpoint_auth_method": "none" 8 | } 9 | -------------------------------------------------------------------------------- /packages/browser/examples/single/bundle/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "browser-in-bundle", 3 | "private": true, 4 | "version": "2.5.0", 5 | "description": "", 6 | "main": "index.js", 7 | "scripts": { 8 | "clean": "rm -rf ./dist", 9 | "start": "webpack serve --no-client-overlay", 10 | "dev": "npm run start", 11 | "build": "webpack --mode production", 12 | "test": "echo \"Error: no test specified\" && exit 1" 13 | }, 14 | "keywords": [], 15 | "author": "", 16 | "devDependencies": { 17 | "@babel/core": "^7.27.4", 18 | "@babel/preset-env": "^7.27.2", 19 | "@babel/preset-react": "^7.27.1", 20 | "babel-loader": "^10.0.0", 21 | "html-loader": "^5.1.0", 22 | "html-webpack-plugin": "^5.6.3", 23 | "webpack": "^5.99.9", 24 | "webpack-cli": "^6.0.1", 25 | "webpack-dev-server": "^5.2.1" 26 | }, 27 | "dependencies": { 28 | "@inrupt/solid-client-authn-browser": "file:../../../", 29 | "react": "^19.0.0", 30 | "react-dom": "^19.1.0", 31 | "regenerator-runtime": "^0.14.1" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/browser/examples/single/bundle/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | solid-client-authn Browser In Bundle Demo 6 | 7 | 8 |
9 | 10 | 11 | -------------------------------------------------------------------------------- /packages/browser/examples/single/bundle/src/index.js: -------------------------------------------------------------------------------- 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 React from "react"; 23 | import { createRoot } from "react-dom/client"; 24 | import App from "./App"; 25 | 26 | createRoot(document.getElementById("container")).render(); 27 | -------------------------------------------------------------------------------- /packages/browser/examples/single/bundle/webpack.config.js: -------------------------------------------------------------------------------- 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 | const HtmlWebPackPlugin = require("html-webpack-plugin"); 22 | 23 | module.exports = { 24 | module: { 25 | rules: [ 26 | { 27 | test: /\.(js|jsx)$/, 28 | exclude: /node_modules/, 29 | use: { 30 | loader: "babel-loader", 31 | }, 32 | }, 33 | { 34 | test: /\.html$/, 35 | use: [ 36 | { 37 | loader: "html-loader", 38 | }, 39 | ], 40 | }, 41 | ], 42 | }, 43 | plugins: [ 44 | new HtmlWebPackPlugin({ 45 | template: "./src/index.html", 46 | filename: "./index.html", 47 | }), 48 | ], 49 | devServer: { 50 | port: 3113, 51 | historyApiFallback: true, 52 | }, 53 | }; 54 | -------------------------------------------------------------------------------- /packages/browser/examples/single/script/README.md: -------------------------------------------------------------------------------- 1 | # `solid-client-authn-browser` sample app 2 | 3 | This application provides a snippet of code showcasing usage of the 4 | `solid-client-authn-browser` library in a `script` tag, without using a bundler. 5 | 6 | ## Install and run 7 | 8 | - Run `npm ci` and `npm run build` in the **root** directory, to build `solid-client-authn-browser`. 9 | - Run `node server.mjs` to start the app. It will start a small web server bound to 10 | `http://localhost:3001`, that resolves the browser bundle for `solid-client-authn-browser`. 11 | -------------------------------------------------------------------------------- /packages/browser/examples/single/script/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

solid-client-authn Script Tag Tester

5 |

6 | Logging in to 7 | https://login.inrupt.com/ 10 |

11 |
12 | WebID of the user you just logged in as: 13 | 14 |
15 | 16 | 17 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /packages/browser/examples/single/script/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@inrupt/solid-client-authn-browser-via-script-tag-example", 3 | "private": true, 4 | "version": "2.5.0", 5 | "description": "", 6 | "main": "index.js", 7 | "scripts": { 8 | "clean": "", 9 | "start": "ts-node server.ts", 10 | "dev": "npm run start", 11 | "test": "echo \"Error: no test specified\" && exit 1" 12 | }, 13 | "author": "", 14 | "dependencies": { 15 | "@types/express": "^5.0.2", 16 | "express": "^5.1.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/browser/examples/single/script/server.mjs: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import path from "path"; 3 | 4 | const PORT = 3001; 5 | 6 | const app = express(); 7 | 8 | app.get("/", (_, res) => { 9 | res.sendFile(path.join(import.meta.dirname, "./index.html")); 10 | }); 11 | 12 | app.get("/solid-client-authn.bundle.js", (_, res) => { 13 | res.sendFile( 14 | path.join(import.meta.dirname, "../../../dist/solid-client-authn.bundle.js"), 15 | ); 16 | }); 17 | 18 | app.listen(PORT, () => console.log(`Listening on port [${PORT}]...`)); 19 | -------------------------------------------------------------------------------- /packages/browser/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@inrupt/solid-client-authn-browser", 3 | "version": "2.5.0", 4 | "license": "MIT", 5 | "types": "dist/index.d.ts", 6 | "browser": "dist/index.js", 7 | "main": "dist/index.js", 8 | "module": "dist/index.mjs", 9 | "bundle": "dist/solid-client-authn.bundle.js", 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/inrupt/solid-client-authn-js.git" 13 | }, 14 | "exports": { 15 | ".": { 16 | "require": "./dist/index.js", 17 | "import": "./dist/index.mjs", 18 | "types": "./dist/index.d.ts" 19 | } 20 | }, 21 | "scripts": { 22 | "prepublishOnly": "npm run build", 23 | "build": "rollup --config rollup.config.mjs", 24 | "licenses:check": "license-checker --production --out license.csv --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\"", 25 | "build-api-docs": "npx typedoc --out docs/api/source/api --readme none", 26 | "build-docs-preview-site": "npm run build-api-docs; cd docs/api; make html" 27 | }, 28 | "devDependencies": { 29 | "@types/node": "^22.15.30", 30 | "@types/uuid": "^10.0.0" 31 | }, 32 | "dependencies": { 33 | "@inrupt/oidc-client-ext": "^2.5.0", 34 | "@inrupt/solid-client-authn-core": "^2.5.0", 35 | "events": "^3.3.0", 36 | "jose": "^5.1.3", 37 | "uuid": "^11.1.0" 38 | }, 39 | "publishConfig": { 40 | "access": "public" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/browser/sampleFlows/SolidAuthClientArchitecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inrupt/solid-client-authn-js/e83e860af5cdb5b142b0adedb671f2d65fd5308e/packages/browser/sampleFlows/SolidAuthClientArchitecture.png -------------------------------------------------------------------------------- /packages/browser/sampleFlows/authorization-code-with-pkce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inrupt/solid-client-authn-js/e83e860af5cdb5b142b0adedb671f2d65fd5308e/packages/browser/sampleFlows/authorization-code-with-pkce.png -------------------------------------------------------------------------------- /packages/browser/sampleFlows/authorization-code-with-pkce.seqdiag: -------------------------------------------------------------------------------- 1 | title: Authorization Code Flow with PKCE 2 | 3 | note left of RP: AUTHORIZATION 4 | note over RP: 1.Alice uses the decentphotos app 5 | note over RP: 2. Alice selets her OP or WebID 6 | RP->Alice's Pod (RS): 2.1 Retrieve Profile 7 | Alice's Pod (RS)->RP: 8 | RP->Alice's OP: 3. Requests OP configuration 9 | Alice's OP->RP: 4. Returns OP configuration 10 | RP->Alice's OP: 5. Requests OP JWKS 11 | Alice's OP->RP: 6. Returns OP JWKS 12 | note over RP: 7. Generates Private/Public key pair 13 | note over RP: 8. Generates PKCE nonce 14 | note over RP: 9. Saves both to local storage 15 | RP->Alice's OP: 10. Authorization Request 16 | Alice's OP->Decentphotos WebID: 11. Retrieves WebID 17 | Decentphotos WebID->Alice's OP: 18 | note over Alice's OP: 11. Validates redirect protocol with WebID 19 | note over Alice's OP: 12. Gets Alice's consent 20 | note over Alice's OP: 13. Generates an id_vc 21 | Alice's OP->RP: 12. Sends code to redirect protocol 22 | RP->Alice's OP: 13. Token requst with code and nonce proof 23 | note over Alice's OP: 14. Validates nonce proof 24 | Alice's OP->RP: 15. Sends id_vc inside id_token 25 | 26 | 27 | note left of RP: SENDING REQUEST 28 | note over RP: 1. Creates a pop_token 29 | RP->Bob's Pod (RS): 2. Request sent 30 | note over Bob's Pod (RS): 3. Checks pop_token Audience 31 | note over Bob's Pod (RS): 4. Checks client signature 32 | Bob's Pod (RS)->Alice's Pod (RS): 5. Retrieves Profile 33 | Alice's Pod (RS)->Bob's Pod (RS): 34 | note over Bob's Pod (RS): 6. Checks Issuer 35 | Bob's Pod (RS)->Alice's OP: 7. Retrieves OP configuration 36 | Alice's OP->Bob's Pod (RS): 37 | Bob's Pod (RS)->Alice's OP: 8. Requests JWKS 38 | Alice's OP->Bob's Pod (RS): 39 | note over Bob's Pod (RS): 9. Performs Authentication 40 | note over Bob's Pod (RS): 10. Performs Authorization 41 | Bob's Pod (RS)->RP: 11. Returns Result 42 | 43 | note left of RP: REFRESH TOKEN 44 | Bob's Pod (RS)->RP: 1. 401: token expired 45 | RP->Alice's OP: 2. Refresh token auth request 46 | Alice's OP->RP: 3. Return updated token 47 | -------------------------------------------------------------------------------- /packages/browser/sampleFlows/authorization-code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inrupt/solid-client-authn-js/e83e860af5cdb5b142b0adedb671f2d65fd5308e/packages/browser/sampleFlows/authorization-code.png -------------------------------------------------------------------------------- /packages/browser/sampleFlows/client-credentials.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inrupt/solid-client-authn-js/e83e860af5cdb5b142b0adedb671f2d65fd5308e/packages/browser/sampleFlows/client-credentials.png -------------------------------------------------------------------------------- /packages/browser/sampleFlows/client-credentials.seqdiag: -------------------------------------------------------------------------------- 1 | title: Client Credentials Grant 2 | 3 | note left of RP: AUTHORIZATION 4 | note over RP: 1. Alice's server knows a client_secret and OP 5 | RP->Alice's OP: 2. Requests OP configuration 6 | Alice's OP->RP: 3. Returns OP configuration 7 | RP->Alice's OP: 4. Requests OP JWKS 8 | Alice's OP->RP: 5. Returns OP JWKS 9 | note over RP: 6. Generates Private/Public key pair 10 | note over RP: 7. Saves Private/Public key pair to local storage 11 | RP->Alice's OP: 8. Authorization Request 12 | Alice's OP->RP WebID: 9. Retrieves WebID 13 | RP WebID->Alice's OP: 14 | note over Alice's OP: 10. Validates redirect_url with WebID 15 | note over Alice's OP: 11. Validate Client Secret 16 | note over Alice's OP: 12. Generates an access_token 17 | Alice's OP->RP: 12. Returns to redirect_url 18 | 19 | note left of RP: SENDING REQUEST 20 | note over RP: 1. Creates a pop_token 21 | RP->Bob's Pod (RS): 2. Request sent 22 | note over Bob's Pod (RS): 3. Checks pop_token Audience 23 | note over Bob's Pod (RS): 4. Checks client signature 24 | Bob's Pod (RS)->Alice's Pod (RS): 5. Retrieves Profile 25 | Alice's Pod (RS)->Bob's Pod (RS): 26 | note over Bob's Pod (RS): 6. Checks Issuer 27 | Bob's Pod (RS)->Alice's OP: 7. Retrieves OP configuration 28 | Alice's OP->Bob's Pod (RS): 29 | Bob's Pod (RS)->Alice's OP: 8. Requests JWKS 30 | Alice's OP->Bob's Pod (RS): 31 | note over Bob's Pod (RS): 9. Performs Authentication 32 | note over Bob's Pod (RS): 10. Performs Authorization 33 | Bob's Pod (RS)->RP: 11. Returns Result 34 | 35 | note left of RP: REFRESH TOKEN 36 | Bob's Pod (RS)->RP: 1. 401: token expired 37 | RP->Alice's OP: 2. Refresh token auth request 38 | Alice's OP->RP: 3. Return updated token -------------------------------------------------------------------------------- /packages/browser/sampleFlows/legacy-implicit-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inrupt/solid-client-authn-js/e83e860af5cdb5b142b0adedb671f2d65fd5308e/packages/browser/sampleFlows/legacy-implicit-flow.png -------------------------------------------------------------------------------- /packages/browser/sampleFlows/legacy-implicit-flow.seqdiag: -------------------------------------------------------------------------------- 1 | title: Legacy Implicit Flow 2 | 3 | note left of RP: AUTHORIZATION 4 | note over RP: 1. Alice navigates to decentphotos.example 5 | note over RP: 2. Alice selets her OP or WebID 6 | RP->Alice's Pod (RS): 2.1 Retrieve Profile 7 | Alice's Pod (RS)->RP: 8 | RP->Alice's OP: 3. Requests OP configuration 9 | Alice's OP->RP: 4. Returns OP configuration 10 | RP->Alice's OP: 5. Requests OP JWKS 11 | Alice's OP->RP: 6. Returns OP JWKS 12 | note over RP: 7. Generates Private/Public key pair 13 | note over RP: 8. Saves Private/Public key pair to local storage 14 | RP->Alice's OP: 9. Authorization Request 15 | Alice's OP->Decentphotos WebID: 10. Retrieves WebID 16 | Decentphotos WebID->Alice's OP: 17 | note over Alice's OP: 11. Validates redirect_url with WebID 18 | note over Alice's OP: 12. Gets Alice's consent 19 | note over Alice's OP: 13. Generates an access_token 20 | Alice's OP->RP: 12. Returns to redirect_url 21 | 22 | note left of RP: SENDING REQUEST 23 | note over RP: 1. Creates a pop_token 24 | RP->Bob's Pod (RS): 2. Request sent 25 | note over Bob's Pod (RS): 3. Checks pop_token Audience 26 | note over Bob's Pod (RS): 4. Checks client signature 27 | Bob's Pod (RS)->Alice's Pod (RS): 5. Retrieves Profile 28 | Alice's Pod (RS)->Bob's Pod (RS): 29 | note over Bob's Pod (RS): 6. Checks Issuer 30 | Bob's Pod (RS)->Alice's OP: 7. Retrieves OP configuration 31 | Alice's OP->Bob's Pod (RS): 32 | Bob's Pod (RS)->Alice's OP: 8. Requests JWKS 33 | Alice's OP->Bob's Pod (RS): 34 | note over Bob's Pod (RS): 9. Performs Authentication 35 | note over Bob's Pod (RS): 10. Performs Authorization 36 | Bob's Pod (RS)->RP: 11. Returns Result 37 | 38 | note left of RP: SILENT REFRESH 39 | Bob's Pod (RS)->RP: 1. 401: token expired 40 | note over RP: 2. Opens iFrame to OP 41 | RP->Alice's OP: 3. Authorization Request with prompt=none 42 | Alice's OP->RP: 4. Return updated token 43 | 44 | -------------------------------------------------------------------------------- /packages/browser/sampleFlows/self-signed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inrupt/solid-client-authn-js/e83e860af5cdb5b142b0adedb671f2d65fd5308e/packages/browser/sampleFlows/self-signed.png -------------------------------------------------------------------------------- /packages/browser/sampleFlows/self-signed.seqdiag: -------------------------------------------------------------------------------- 1 | title: Self Issued Flow 2 | 3 | note left of RP: AUTHENTICATION 4 | note over RP: 1. Alice uses the Decentphotos App 5 | note over OP: 2. Alice has a self-signed app installed 6 | note over OP: It knows Alice's private key 7 | note over Alice's WebID: 3. issuer: selfissued.me 8 | note over Alice's WebID: Knows Alice's pub cert 9 | note over RP: 4. Alice selects her OP or WebID 10 | RP->Alice's WebID: 4.1 Gets WebID 11 | Alice's WebID->RP: 12 | RP->OP: 5. Requests OP configuration 13 | OP->RP: 14 | RP->OP: 6. Requests OP JWKS 15 | OP->RP: 16 | note over RP: 7. Generates Private/Public key pair 17 | note over RP: 8. Generates PKCE nonce 18 | note over RP: 9. Saves both to local storage 19 | RP->OP: 10. Authorization Request 20 | OP->Decentphotos WebID: 11. Retrieves WebID 21 | Decentphotos WebID->OP: 22 | note over OP: 11. Validates redirect protocol with WebID 23 | note over OP: 12. Gets Alice's consent 24 | note over OP: 13. Generates an access_code 25 | OP->RP: 12. Sends code to redirect protocol 26 | RP->OP: 13. Token requst with code and nonce proof 27 | note over OP: 14. Validates nonce proof 28 | OP->RP: 15. Sends access_token 29 | 30 | note left of RP: SENDING REQUEST 31 | note over RP: 1. Creates a pop_token 32 | RP->Bob's Pod (RS): 2. Request sent 33 | note over Bob's Pod (RS): 3. Checks pop_token Audience 34 | note over Bob's Pod (RS): 4. Checks client signature 35 | Bob's Pod (RS)->Alice's WebID: 5. Retrieves Profile 36 | Alice's WebID->Bob's Pod (RS): 37 | note over Bob's Pod (RS): 6. Checks that access_token cert matches WebID 38 | Bob's Pod (RS)->OP: 7. Retrieves OP configuration 39 | OP->Bob's Pod (RS): 40 | Bob's Pod (RS)->OP: 8. Requests JWKS 41 | OP->Bob's Pod (RS): 42 | note over Bob's Pod (RS): 9. Performs Authentication 43 | note over Bob's Pod (RS): 10. Performs Authorization 44 | Bob's Pod (RS)->RP: 11. Returns Result 45 | 46 | note left of RP: REFRESH TOKEN 47 | Bob's Pod (RS)->RP: 1. 401: token expired 48 | RP->OP: 2. Refresh token auth request 49 | OP->RP: 3. Return updated token -------------------------------------------------------------------------------- /packages/browser/sampleFlows/signatory-access-control.seqdiag: -------------------------------------------------------------------------------- 1 | title: Legacy Implicit Flow 2 | 3 | note left of RP: AUTHORIZATION 4 | note over RP: 1. Alice navigates to badguys.com 5 | note over RP: 2. Alice selects her OP or WebID 6 | RP->Alice's WebId: 2.1 Retrieve Profile 7 | Alice's WebId->RP: 8 | RP->Alice's OP: 3. Get OP configuration 9 | Alice's OP->RP: 10 | RP->Alice's OP: 4. Get OP JWKS 11 | Alice's OP->RP: 12 | note over RP: 5. Generates Private/Public key pair 13 | note over RP: 6. Saves Private/Public key pair to local storage 14 | RP->Alice's OP: 7. Authorization Request 15 | Alice's OP->badguys.com WebId: 8. Retrieves WebID 16 | badguys.com WebId->Alice's OP: 17 | note over Alice's OP: 9. Validates redirect_url with WebID 18 | note over Alice's OP: 10. Gets Alice's consent 19 | note over Alice's OP: 11. Generates an access_token 20 | Alice's OP->RP: 12. Returns to redirect_url 21 | 22 | note left of RP: SENDING REQUEST 23 | note over RP: 1. Creates a pop_token 24 | RP->Bob's Pod (RS): 2. Request sent 25 | note over Bob's Pod (RS): 3. Checks pop_token Audience 26 | note over Bob's Pod (RS): 4. Checks client signature 27 | Bob's Pod (RS)->Alice's WebId: 5. Retrieves Subject Profile 28 | Alice's WebId->Bob's Pod (RS): 29 | note over Bob's Pod (RS): 6. Checks Issuer 30 | Bob's Pod (RS)->Alice's OP: 7. Retrieves OP configuration 31 | Alice's OP->Bob's Pod (RS): 32 | Bob's Pod (RS)->Alice's OP: 8. Requests JWKS 33 | Alice's OP->Bob's Pod (RS): 34 | note over Bob's Pod (RS): 9. Performs Authentication 35 | note over Bob's Pod (RS): 10. Performs Authorization 36 | Bob's Pod (RS)->RP: 11. Returns Result 37 | -------------------------------------------------------------------------------- /packages/browser/sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=inrupt_solid-client-authn-browser 2 | sonar.projectName=solid-client-authn-browser 3 | sonar.organization=inrupt 4 | 5 | # Path is relative to the sonar-project.properties file. Defaults to . 6 | sonar.sources=src 7 | 8 | # Typescript tsconfigPath JSON file 9 | sonar.typescript.tsconfigPath=. 10 | 11 | # Comma-delimited list of paths to LCOV coverage report files. Paths may be absolute or relative to the project root. 12 | sonar.javascript.lcov.reportPaths=./coverage/lcov.info 13 | 14 | # Exclude tests from analysis 15 | sonar.exclusions=**/*.test.ts 16 | -------------------------------------------------------------------------------- /packages/browser/src/constant.ts: -------------------------------------------------------------------------------- 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 { SOLID_CLIENT_AUTHN_KEY_PREFIX } from "@inrupt/solid-client-authn-core"; 23 | 24 | export const KEY_CURRENT_SESSION = `${SOLID_CLIENT_AUTHN_KEY_PREFIX}currentSession`; 25 | 26 | export const KEY_CURRENT_URL = `${SOLID_CLIENT_AUTHN_KEY_PREFIX}currentUrl`; 27 | -------------------------------------------------------------------------------- /packages/browser/src/dependencies.node.spec.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @jest-environment node 24 | */ 25 | import { describe, it, expect } from "@jest/globals"; 26 | import { getClientAuthenticationWithDependencies } from "./dependencies"; 27 | import ClientAuthentication from "./ClientAuthentication"; 28 | 29 | describe("dependencies.node", () => { 30 | it("performs dependency injection in a node environment", () => { 31 | const clientAuthn = getClientAuthenticationWithDependencies({}); 32 | expect(clientAuthn).toBeInstanceOf(ClientAuthentication); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /packages/browser/src/dependencies.spec.ts: -------------------------------------------------------------------------------- 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 { describe, it, expect } from "@jest/globals"; 23 | import { mockStorageUtility } from "@inrupt/solid-client-authn-core"; 24 | import { getClientAuthenticationWithDependencies } from "./dependencies"; 25 | import ClientAuthentication from "./ClientAuthentication"; 26 | 27 | describe("dependencies", () => { 28 | it("performs dependency injection", () => { 29 | const clientAuthn = getClientAuthenticationWithDependencies({}); 30 | expect(clientAuthn).toBeInstanceOf(ClientAuthentication); 31 | }); 32 | 33 | it("performs dependency injection with a given input", () => { 34 | const clientAuthn = getClientAuthenticationWithDependencies({ 35 | secureStorage: mockStorageUtility({}), 36 | }); 37 | expect(clientAuthn).toBeInstanceOf(ClientAuthentication); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /packages/browser/src/index.browser.spec.ts: -------------------------------------------------------------------------------- 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 { it, expect } from "@jest/globals"; 23 | import * as solidClientAuthentication from "./index.browser"; 24 | 25 | it("exports the public API from the entrypoint", () => { 26 | expect(solidClientAuthentication).toBeDefined(); 27 | }); 28 | -------------------------------------------------------------------------------- /packages/browser/src/index.browser.ts: -------------------------------------------------------------------------------- 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 * as solidClientAuthentication from "./index"; 23 | 24 | export default solidClientAuthentication; 25 | -------------------------------------------------------------------------------- /packages/browser/src/index.spec.ts: -------------------------------------------------------------------------------- 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 { it, expect } from "@jest/globals"; 23 | 24 | import { Session } from "./index"; 25 | 26 | it("exports the public API from the entrypoint", () => { 27 | expect(Session).toBeDefined(); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/browser/src/index.ts: -------------------------------------------------------------------------------- 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 | export { 23 | Session, 24 | ISessionOptions, 25 | IHandleIncomingRedirectOptions, 26 | } from "./Session"; 27 | 28 | export * from "./defaultSession"; 29 | 30 | // Re-export of types defined in the core module and produced/consumed by our API 31 | 32 | export { 33 | ILoginInputOptions, 34 | ISessionInfo, 35 | IStorage, 36 | NotImplementedError, 37 | ConfigurationError, 38 | InMemoryStorage, 39 | IHasSessionEventListener, 40 | ISessionEventListener, 41 | IEndSessionOptions, 42 | ILogoutOptions, 43 | EVENTS, 44 | } from "@inrupt/solid-client-authn-core"; 45 | -------------------------------------------------------------------------------- /packages/browser/src/login/__mocks__/LoginHandler.ts: -------------------------------------------------------------------------------- 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 type { 23 | ILoginOptions, 24 | ILoginHandler, 25 | ISessionInfo, 26 | } from "@inrupt/solid-client-authn-core"; 27 | import { jest } from "@jest/globals"; 28 | 29 | export const LoginHandlerResponse: ISessionInfo = { 30 | isLoggedIn: false, 31 | sessionId: "global", 32 | }; 33 | 34 | export const mockLoginHandler = (): ILoginHandler => { 35 | return { 36 | canHandle: jest.fn((_options: ILoginOptions) => Promise.resolve(true)), 37 | handle: jest.fn((_options: ILoginOptions) => Promise.resolve(undefined)), 38 | }; 39 | }; 40 | -------------------------------------------------------------------------------- /packages/browser/src/login/oidc/AggregateOidcHandler.spec.ts: -------------------------------------------------------------------------------- 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 type { IOidcHandler } from "@inrupt/solid-client-authn-core"; 23 | import { AggregateHandler } from "@inrupt/solid-client-authn-core"; 24 | import { jest, it, describe, expect } from "@jest/globals"; 25 | import AggregateOidcHandler from "./AggregateOidcHandler"; 26 | 27 | jest.mock("@inrupt/solid-client-authn-core"); 28 | 29 | describe("AggregateOidcHandler", () => { 30 | it("should pass injected handlers to its superclass", () => { 31 | // We just test if the parent is called. 32 | // eslint-disable-next-line no-new 33 | new AggregateOidcHandler(["Some handler"] as unknown as IOidcHandler[]); 34 | 35 | expect((AggregateHandler as jest.Mock).mock.calls).toEqual([ 36 | [["Some handler"]], 37 | ]); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /packages/browser/src/login/oidc/AggregateOidcHandler.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | /** 28 | * Responsible for selecting the correct OidcHandler to handle the provided OIDC Options 29 | */ 30 | import type { 31 | IOidcHandler, 32 | IOidcOptions, 33 | LoginResult, 34 | } from "@inrupt/solid-client-authn-core"; 35 | import { AggregateHandler } from "@inrupt/solid-client-authn-core"; 36 | 37 | /** 38 | * @hidden 39 | */ 40 | export default class AggregateOidcHandler 41 | extends AggregateHandler<[IOidcOptions], LoginResult> 42 | implements IOidcHandler 43 | { 44 | constructor(oidcLoginHandlers: IOidcHandler[]) { 45 | super(oidcLoginHandlers); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/browser/src/login/oidc/AggregateRedirectHandler.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | /** 28 | * Responsible for selecting the correct OidcHandler to handle the provided OIDC Options 29 | */ 30 | import type { 31 | IIncomingRedirectHandler, 32 | IncomingRedirectInput, 33 | IncomingRedirectResult, 34 | } from "@inrupt/solid-client-authn-core"; 35 | import { AggregateHandler } from "@inrupt/solid-client-authn-core"; 36 | 37 | /** 38 | * @hidden 39 | */ 40 | export default class AggregateRedirectHandler 41 | extends AggregateHandler 42 | implements IIncomingRedirectHandler 43 | { 44 | constructor(redirectHandlers: IIncomingRedirectHandler[]) { 45 | super(redirectHandlers); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/browser/src/login/oidc/Redirector.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | import type { 28 | IRedirector, 29 | IRedirectorOptions, 30 | } from "@inrupt/solid-client-authn-core"; 31 | 32 | /** 33 | * @hidden 34 | */ 35 | export default class Redirector implements IRedirector { 36 | redirect(redirectUrl: string, options?: IRedirectorOptions): void { 37 | if (options && options.handleRedirect) { 38 | options.handleRedirect(redirectUrl); 39 | } else if (options && options.redirectByReplacingState) { 40 | window.history.replaceState({}, "", redirectUrl); 41 | } else { 42 | window.location.href = redirectUrl; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/browser/src/login/oidc/__mocks__/IOidcHandler.ts: -------------------------------------------------------------------------------- 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 type { 23 | IOidcHandler, 24 | IOidcOptions, 25 | ISessionInfo, 26 | } from "@inrupt/solid-client-authn-core"; 27 | import { jest } from "@jest/globals"; 28 | 29 | import { SessionCreatorGetSessionResponse } from "../../../sessionInfo/__mocks__/SessionInfoManager"; 30 | 31 | export const OidcHandlerHandleResponse: ISessionInfo = 32 | SessionCreatorGetSessionResponse; 33 | 34 | export const OidcHandlerMock: jest.Mocked = { 35 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 36 | canHandle: jest.fn((_options: IOidcOptions) => Promise.resolve(true)), 37 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 38 | handle: jest.fn(async (_options: IOidcOptions) => Promise.resolve(undefined)), 39 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 40 | } as any; 41 | -------------------------------------------------------------------------------- /packages/browser/src/login/oidc/__mocks__/IOidcOptions.ts: -------------------------------------------------------------------------------- 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 type { IOidcOptions } from "@inrupt/solid-client-authn-core"; 23 | import { jest } from "@jest/globals"; 24 | 25 | export const standardOidcOptions: IOidcOptions = { 26 | sessionId: "mySession", 27 | issuer: "https://example.com", 28 | dpop: true, 29 | redirectUrl: "https://app.example.com", 30 | handleRedirect: jest.fn((url) => url), 31 | // This will be fixed in a different pull request 32 | issuerConfiguration: { 33 | issuer: "https://example.com", 34 | authorizationEndpoint: "https://example.com/auth", 35 | tokenEndpoint: "https://example.com/token", 36 | jwksUri: "https://example.com/jwks", 37 | subjectTypesSupported: [], 38 | claimsSupported: [], 39 | scopesSupported: ["openid"], 40 | }, 41 | client: { 42 | clientId: "coolApp", 43 | clientType: "dynamic", 44 | }, 45 | }; 46 | -------------------------------------------------------------------------------- /packages/browser/src/login/oidc/__mocks__/Redirector.ts: -------------------------------------------------------------------------------- 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 type { 23 | IRedirector, 24 | IRedirectorOptions, 25 | } from "@inrupt/solid-client-authn-core"; 26 | import { jest } from "@jest/globals"; 27 | 28 | export const mockedRedirector = 29 | jest.fn<(redirectUrl: string, redirectOptions: IRedirectorOptions) => void>(); 30 | export const mockRedirector = (): IRedirector => { 31 | return { 32 | redirect: mockedRedirector, 33 | }; 34 | }; 35 | -------------------------------------------------------------------------------- /packages/browser/src/login/oidc/refresh/__mocks__/TokenRefresher.ts: -------------------------------------------------------------------------------- 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 { jest } from "@jest/globals"; 23 | import type { 24 | ITokenRefresher, 25 | TokenEndpointResponse, 26 | } from "@inrupt/solid-client-authn-core"; 27 | 28 | // Some identifiers are in camelcase on purpose. 29 | /* eslint-disable camelcase */ 30 | 31 | export const mockTokenRefresher = ( 32 | tokenSet: TokenEndpointResponse, 33 | ): ITokenRefresher => { 34 | return { 35 | refresh: jest.fn().mockResolvedValue(tokenSet), 36 | }; 37 | }; 38 | 39 | const mockIdTokenPayload = () => { 40 | return { 41 | sub: "https://my.webid", 42 | iss: "https://my.idp/", 43 | aud: "https://resource.example.org", 44 | exp: 1662266216, 45 | iat: 1462266216, 46 | }; 47 | }; 48 | 49 | export const mockDefaultTokenSet = (): TokenEndpointResponse => { 50 | return { 51 | accessToken: "some refreshed access token", 52 | idToken: JSON.stringify(mockIdTokenPayload()), 53 | }; 54 | }; 55 | 56 | export const mockDefaultTokenRefresher = (): ITokenRefresher => 57 | mockTokenRefresher(mockDefaultTokenSet()); 58 | -------------------------------------------------------------------------------- /packages/browser/src/logout/buildRpInitiatedLogout.ts: -------------------------------------------------------------------------------- 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 | import type { 22 | IEndSessionOptions, 23 | IRpLogoutOptions, 24 | } from "@inrupt/solid-client-authn-core"; 25 | import { getEndSessionUrl } from "@inrupt/solid-client-authn-core"; 26 | 27 | /** 28 | * @param options.endSessionEndpoint The end_session_endpoint advertised by the server 29 | * @param options.idTokenHint The idToken supplied by the server after logging in 30 | * Redirects the window to the location required to perform RP initiated logout 31 | * 32 | * @hidden 33 | */ 34 | export function buildRpInitiatedLogout({ 35 | endSessionEndpoint, 36 | idTokenHint, 37 | }: Omit) { 38 | return function logout({ state, postLogoutUrl }: IRpLogoutOptions) { 39 | window.location.href = getEndSessionUrl({ 40 | endSessionEndpoint, 41 | idTokenHint, 42 | state, 43 | postLogoutRedirectUri: postLogoutUrl, 44 | }); 45 | }; 46 | } 47 | -------------------------------------------------------------------------------- /packages/browser/src/storage/BrowserStorage.spec.ts: -------------------------------------------------------------------------------- 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 { describe, it, expect } from "@jest/globals"; 23 | 24 | import BrowserStorage from "./BrowserStorage"; 25 | 26 | describe("BrowserStorage", () => { 27 | it("should get storage", () => { 28 | expect(new BrowserStorage().storage).toBeDefined(); 29 | }); 30 | 31 | it("should exercise operations - no need for separate tests", async () => { 32 | const storage = new BrowserStorage(); 33 | 34 | const testKey = "some key"; 35 | await expect(storage.get(testKey)).resolves.toBeUndefined(); 36 | 37 | const testValue = "some value"; 38 | await storage.set(testKey, testValue); 39 | await expect(storage.get(testKey)).resolves.toEqual(testValue); 40 | 41 | await storage.delete(testKey); 42 | await expect(storage.get(testKey)).resolves.toBeUndefined(); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /packages/browser/src/storage/BrowserStorage.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | import type { IStorage } from "@inrupt/solid-client-authn-core"; 28 | 29 | /** 30 | * @hidden 31 | */ 32 | export default class BrowserStorage implements IStorage { 33 | get storage(): typeof window.localStorage { 34 | return window.localStorage; 35 | } 36 | 37 | async get(key: string): Promise { 38 | return this.storage.getItem(key) || undefined; 39 | } 40 | 41 | async set(key: string, value: string): Promise { 42 | this.storage.setItem(key, value); 43 | } 44 | 45 | async delete(key: string): Promise { 46 | this.storage.removeItem(key); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /packages/browser/src/storage/StorageUtility.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | /** 28 | * A helper class that will validate items taken from local storage 29 | */ 30 | import type { IStorage } from "@inrupt/solid-client-authn-core"; 31 | import { StorageUtility } from "@inrupt/solid-client-authn-core"; 32 | 33 | /** 34 | * This class in a no-value-added extension of StorageUtility from the core module. 35 | * The reason it has to be declared is for TSyringe to find the decorators in the 36 | * same modules as where the dependency container is declared (in this case, 37 | * the browser module, with the dependancy container in dependencies.ts). 38 | * @hidden 39 | */ 40 | export default class StorageUtilityBrowser extends StorageUtility { 41 | constructor(secureStorage: IStorage, insecureStorage: IStorage) { 42 | super(secureStorage, insecureStorage); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /packages/browser/src/storage/__mocks__/LocalStorage.ts: -------------------------------------------------------------------------------- 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 | export class LocalStorageMock { 23 | public store: { 24 | [key: string]: string; 25 | }; 26 | 27 | constructor(store?: Record) { 28 | this.store = store ?? {}; 29 | } 30 | 31 | public clear(): void { 32 | this.store = {}; 33 | } 34 | 35 | public getItem(key: string): string | null { 36 | return this.store[key] || null; 37 | } 38 | 39 | public setItem(key: string, value: string): void { 40 | this.store[key] = value.toString(); 41 | } 42 | 43 | public removeItem(key: string): void { 44 | delete this.store[key]; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /packages/browser/src/util/UUIDGenerator.spec.ts: -------------------------------------------------------------------------------- 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 { jest, it, describe, expect } from "@jest/globals"; 23 | import UuidGenerator from "./UuidGenerator"; 24 | 25 | jest.mock("uuid"); 26 | 27 | describe("UuidGenerator", () => { 28 | it("should simply wrap the `uuid` module", () => { 29 | const uuidMock: { v4: jest.Mock } = jest.requireMock("uuid") as any; 30 | uuidMock.v4.mockReturnValueOnce("some uuid"); 31 | 32 | const generator = new UuidGenerator(); 33 | expect(generator.v4()).toBe("some uuid"); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /packages/browser/src/util/UuidGenerator.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | /** 28 | * A wrapper class for uuid 29 | */ 30 | import { v4 } from "uuid"; 31 | 32 | /** 33 | * @hidden 34 | */ 35 | export interface IUuidGenerator { 36 | v4(): string; 37 | } 38 | 39 | /** 40 | * @hidden 41 | */ 42 | export default class UuidGenerator { 43 | // eslint-disable-next-line class-methods-use-this 44 | v4(): string { 45 | return v4(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/browser/src/util/__mocks__/UuidGenerator.ts: -------------------------------------------------------------------------------- 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 { jest } from "@jest/globals"; 23 | import type { IUuidGenerator } from "../UuidGenerator"; 24 | 25 | export const UuidGeneratorMockResponse = "fee3fa53-a6a9-475c-a0da-b1343a4fff76"; 26 | 27 | export const UuidGeneratorMock: jest.Mocked = { 28 | v4: jest.fn(() => UuidGeneratorMockResponse), 29 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 30 | } as any; 31 | -------------------------------------------------------------------------------- /packages/browser/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.build.json", 3 | 4 | "compilerOptions": { 5 | "lib": ["es2022", "dom"], 6 | "outDir": "./dist" 7 | }, 8 | 9 | "typedocOptions": { 10 | "out": "website/docs/api/browser", 11 | "entryPoints": ["./src/index.ts"], 12 | "entryDocument": "index.rst", 13 | "hideInPageTOC": true, 14 | "plugin": ["typedoc-plugin-markdown"] 15 | }, 16 | 17 | "include": ["src/**/*"], 18 | "exclude": ["src/**/*.spec.ts", "**/__mocks__/*"] 19 | } 20 | -------------------------------------------------------------------------------- /packages/core/.npmignore: -------------------------------------------------------------------------------- 1 | .git 2 | docs 3 | coverage 4 | report 5 | .vscode 6 | .prettierignore 7 | sonar-project.properties 8 | -------------------------------------------------------------------------------- /packages/core/.prettierignore: -------------------------------------------------------------------------------- 1 | # TODO: figure out why the root .prettierignore file isn't detected: 2 | docs/**/*.md 3 | -------------------------------------------------------------------------------- /packages/core/docs/api/README.md: -------------------------------------------------------------------------------- 1 | # apidocs 2 | 3 | Builds the API docs site from generated api \*.md files. 4 | 5 | ## To Build 6 | 7 | To build: 8 | 9 | 0. Prereq: [python3](https://www.python.org/downloads/), [Node.js](https://nodejs.org/). 10 | 11 | 1. Optional but recommended. Create a virtual env: 12 | 13 | ```sh 14 | python3 -m venv 15 | source /bin/activate 16 | ``` 17 | 18 | 1. Generate the API .md files: 19 | 20 | npm ci; npm run build-api-docs 21 | 22 | 1. Go to the apidocs directory: 23 | 24 | cd apidocs 25 | 26 | 1. Install the docs requirements (different from library docs requirements): 27 | 28 | ```sh 29 | pip install -r https://raw.githubusercontent.com/inrupt/docs-assets/main/requirements/api/requirements.txt 30 | ``` 31 | 32 | 1. Make the API docs: 33 | 34 | ```sh 35 | make html 36 | ``` 37 | 38 | There should be a `build/html` directory with the html artifacts. 39 | 40 | When finished, can deactivate your virtual env. 41 | 42 | ## Third Party Licenses 43 | 44 | The `requirements.txt` lists the 3rd party libraries used for the docs. 45 | For the licenses, see the shared 46 | [inrupt/docs-assets](https://github.com/inrupt/docs-assets#readme). 47 | -------------------------------------------------------------------------------- /packages/core/docs/api/source/index.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | =========================== 4 | solid-client-authn-core API 5 | =========================== 6 | 7 | .. -core doesn't export classes, so this line is removed from the toctree (compared to non-core): 8 | .. /classes/* 9 | 10 | .. toctree:: 11 | :glob: 12 | :titlesonly: 13 | 14 | /interfaces/* 15 | -------------------------------------------------------------------------------- /packages/core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@inrupt/solid-client-authn-core", 3 | "version": "2.5.0", 4 | "license": "MIT", 5 | "main": "dist/index.js", 6 | "module": "dist/index.mjs", 7 | "types": "dist/index.d.ts", 8 | "exports": { 9 | ".": { 10 | "require": "./dist/index.js", 11 | "import": "./dist/index.mjs", 12 | "types": "./dist/index.d.ts" 13 | }, 14 | "./mocks": { 15 | "require": "./dist/mocks.js", 16 | "import": "./dist/mocks.mjs", 17 | "types": "./dist/mocks.d.ts" 18 | } 19 | }, 20 | "typesVersions": { 21 | "*": { 22 | "mocks": [ 23 | "dist/mocks.d.ts" 24 | ] 25 | } 26 | }, 27 | "repository": { 28 | "type": "git", 29 | "url": "https://github.com/inrupt/solid-client-authn-js.git" 30 | }, 31 | "scripts": { 32 | "prepublishOnly": "npm run build", 33 | "build": "rollup --config rollup.config.mjs", 34 | "licenses:check": "license-checker --production --out license.csv --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\"", 35 | "build-api-docs": "npx typedoc --out docs/api/source/api --readme none", 36 | "build-docs-preview-site": "npm run build-api-docs; cd docs/api; make html" 37 | }, 38 | "dependencies": { 39 | "events": "^3.3.0", 40 | "jose": "^5.1.3", 41 | "uuid": "^11.1.0" 42 | }, 43 | "publishConfig": { 44 | "access": "public" 45 | }, 46 | "engines": { 47 | "node": "^18.0.0 || ^20.0.0 || ^22.0.0" 48 | }, 49 | "devDependencies": { 50 | "@types/uuid": "^10.0.0" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /packages/core/rollup.config.mjs: -------------------------------------------------------------------------------- 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 createConfig, { createSharedConfig } from "@inrupt/base-rollup-config"; 23 | // eslint-disable-next-line import/extensions 24 | import pkg from "./package.json" with { type: "json" }; 25 | 26 | export default [ 27 | ...createConfig(pkg), 28 | { 29 | input: "./src/mocks.ts", 30 | output: [ 31 | { 32 | file: pkg.exports["./mocks"].require, 33 | format: "cjs", 34 | }, 35 | { 36 | file: pkg.exports["./mocks"].import, 37 | format: "esm", 38 | }, 39 | ], 40 | ...createSharedConfig(pkg), 41 | }, 42 | ]; 43 | -------------------------------------------------------------------------------- /packages/core/sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=inrupt_solid-client-authn-core 2 | sonar.projectName=solid-client-authn-core 3 | sonar.organization=inrupt 4 | 5 | # Path is relative to the sonar-project.properties file. Defaults to . 6 | sonar.sources=src 7 | 8 | # Typescript tsconfigPath JSON file 9 | sonar.typescript.tsconfigPath=. 10 | 11 | # Comma-delimited list of paths to LCOV coverage report files. Paths may be absolute or relative to the project root. 12 | sonar.javascript.lcov.reportPaths=./coverage/lcov.info 13 | 14 | # Exclude tests from analysis 15 | sonar.exclusions=**/*.test.ts 16 | -------------------------------------------------------------------------------- /packages/core/src/Session.ts: -------------------------------------------------------------------------------- 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 | export type SessionConfig = { 23 | keepAlive: boolean; 24 | }; 25 | -------------------------------------------------------------------------------- /packages/core/src/errors/ConfigurationError.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | /** 28 | * Error to be triggered when a poor configuration is received 29 | */ 30 | 31 | // NOTE: There's a bug with istanbul and typescript that prevents full branch coverages 32 | // https://github.com/gotwarlost/istanbul/issues/690 33 | // The workaround is to put istanbul ignore on the constructor 34 | /** 35 | * @hidden 36 | */ 37 | export default class ConfigurationError extends Error { 38 | /* istanbul ignore next */ 39 | constructor(message: string) { 40 | super(message); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/core/src/errors/InvalidResponseError.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | /** 28 | * Error to be triggered when receiving a response missing mandatory elements 29 | */ 30 | 31 | // NOTE: There's a bug with istanbul and typescript that prevents full branch coverages 32 | // https://github.com/gotwarlost/istanbul/issues/690 33 | // The workaround is to put istanbul ignore on the constructor 34 | /** 35 | * @hidden 36 | */ 37 | export class InvalidResponseError extends Error { 38 | /* istanbul ignore next */ 39 | constructor(public readonly missingFields: string[]) { 40 | super( 41 | `Invalid response from OIDC provider: missing fields ${missingFields}`, 42 | ); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /packages/core/src/errors/NotImplementedError.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | /** 28 | * Error to be triggered if a method is not implemented 29 | * @hidden 30 | */ 31 | export default class NotImplementedError extends Error { 32 | /* istanbul ignore next */ 33 | constructor(methodName: string) { 34 | super(`[${methodName}] is not implemented`); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/core/src/errors/OidcProviderError.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | /** 28 | * Error to be triggered when receiving a response missing mandatory elements 29 | */ 30 | 31 | // NOTE: There's a bug with istanbul and typescript that prevents full branch coverages 32 | // https://github.com/gotwarlost/istanbul/issues/690 33 | // The workaround is to put istanbul ignore on the constructor 34 | /** 35 | * @hidden 36 | */ 37 | export class OidcProviderError extends Error { 38 | /* istanbul ignore next */ 39 | constructor( 40 | message: string, 41 | public readonly error: string, 42 | public readonly errorDescription?: string, 43 | ) { 44 | super(message); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /packages/core/src/errors/errors.spec.ts: -------------------------------------------------------------------------------- 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 { describe, it, expect } from "@jest/globals"; 23 | /** 24 | * Test for all custom errors 25 | */ 26 | import ConfigurationError from "./ConfigurationError"; 27 | import NotImplementedError from "./NotImplementedError"; 28 | 29 | describe("errors", () => { 30 | const errors: { 31 | name: string; 32 | class: any; 33 | params: unknown[]; 34 | message: string; 35 | }[] = [ 36 | { 37 | name: "ConfigurationError", 38 | class: ConfigurationError, 39 | params: ["Bad Config"], 40 | message: "Bad Config", 41 | }, 42 | { 43 | name: "NotImplementedError", 44 | class: NotImplementedError, 45 | params: ["FunctionName"], 46 | message: "[FunctionName] is not implemented", 47 | }, 48 | ]; 49 | 50 | errors.forEach((err) => { 51 | it(`Should throw [${err.name}]`, () => { 52 | expect(() => { 53 | // eslint-disable-next-line new-cap 54 | const error = new err.class(...err.params); 55 | throw error; 56 | }).toThrow(err.message); 57 | }); 58 | }); 59 | }); 60 | -------------------------------------------------------------------------------- /packages/core/src/login/ILoginHandler.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | /** 28 | * A Login Handler will log a user in if it is able to use the provided Login Parameters 29 | */ 30 | import type IHandleable from "../util/handlerPattern/IHandleable"; 31 | import type ILoginOptions from "./ILoginOptions"; 32 | import type { IncomingRedirectResult } from "./oidc/IIncomingRedirectHandler"; 33 | 34 | // FIXME: Remove this file as we only have one login handler: 35 | export type LoginResult = IncomingRedirectResult | undefined; 36 | 37 | /** 38 | * @hidden 39 | */ 40 | type ILoginHandler = IHandleable<[ILoginOptions], LoginResult>; 41 | export default ILoginHandler; 42 | -------------------------------------------------------------------------------- /packages/core/src/login/oidc/IClient.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | type IClientBase = { 28 | clientName?: string; 29 | idTokenSignedResponseAlg?: string; 30 | }; 31 | 32 | /** 33 | * @hidden 34 | */ 35 | export type ISolidOidcClient = IClientBase & { 36 | clientId: string; 37 | clientType: "solid-oidc"; 38 | // A solid-oidc client has no concept of client secret, 39 | // but this makes type checking easier in the codebase. 40 | clientSecret?: undefined; 41 | }; 42 | 43 | /** 44 | * @hidden 45 | */ 46 | export type IOpenIdStaticClient = IClientBase & { 47 | clientId: string; 48 | clientSecret: string; 49 | clientType: "static"; 50 | }; 51 | 52 | /** 53 | * @hidden 54 | */ 55 | export type IOpenIdDynamicClient = IClientBase & { 56 | clientId: string; 57 | clientType: "dynamic"; 58 | } & ( // The expiration date is required if a secret is present. 59 | | { clientSecret: string; expiresAt: number } 60 | | { clientSecret?: undefined; expiresAt?: undefined } 61 | ); 62 | 63 | /** 64 | * @hidden 65 | */ 66 | export type IClient = 67 | | ISolidOidcClient 68 | | IOpenIdStaticClient 69 | | IOpenIdDynamicClient; 70 | -------------------------------------------------------------------------------- /packages/core/src/login/oidc/IIncomingRedirectHandler.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | // eslint-disable-next-line no-shadow 28 | import type { EventEmitter } from "events"; 29 | import type IHandleable from "../../util/handlerPattern/IHandleable"; 30 | import type { ISessionInfo } from "../../sessionInfo/ISessionInfo"; 31 | import type { IRpLogoutOptions } from "../../logout/ILogoutHandler"; 32 | import type { SessionConfig } from "../../Session"; 33 | 34 | export type IncomingRedirectResult = ISessionInfo & { fetch: typeof fetch } & { 35 | getLogoutUrl?: (options: IRpLogoutOptions) => string; 36 | }; 37 | export type IncomingRedirectInput = [ 38 | string, 39 | EventEmitter | undefined, 40 | SessionConfig | undefined, 41 | ]; 42 | 43 | /** 44 | * @hidden 45 | */ 46 | type IIncomingRedirectHandler = IHandleable< 47 | // Tuple of the URL to redirect to, an optional event listener for when 48 | // we receive a new refresh token, and, an optional onError function: 49 | IncomingRedirectInput, 50 | IncomingRedirectResult 51 | >; 52 | export default IIncomingRedirectHandler; 53 | -------------------------------------------------------------------------------- /packages/core/src/login/oidc/IIssuerConfigFetcher.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | /** 28 | * Responsible for fetching an IDP configuration 29 | */ 30 | import type { IIssuerConfig } from "./IIssuerConfig"; 31 | 32 | export interface IIssuerConfigFetcher { 33 | /** 34 | * Fetches the configuration 35 | * @param issuer URL of the IDP 36 | */ 37 | fetchConfig(issuer: string): Promise; 38 | } 39 | -------------------------------------------------------------------------------- /packages/core/src/login/oidc/IOidcHandler.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | /** 28 | * OidcHandlers handle the login process for a given IDP (as defined by the OIDC Options) 29 | */ 30 | import type IHandleable from "../../util/handlerPattern/IHandleable"; 31 | import type { IncomingRedirectResult } from "./IIncomingRedirectHandler"; 32 | import type IOidcOptions from "./IOidcOptions"; 33 | 34 | export type OidcHandlerResult = IncomingRedirectResult | undefined; 35 | 36 | /** 37 | * @hidden 38 | */ 39 | type IOidcHandler = IHandleable<[IOidcOptions], OidcHandlerResult>; 40 | export default IOidcHandler; 41 | -------------------------------------------------------------------------------- /packages/core/src/login/oidc/IRedirector.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | /** 28 | * @hidden 29 | */ 30 | export interface IRedirectorOptions { 31 | handleRedirect?: (url: string) => unknown; 32 | redirectByReplacingState?: boolean; 33 | } 34 | 35 | /** 36 | * @hidden 37 | */ 38 | export interface IRedirector { 39 | redirect(redirectUrl: string, redirectorOptions: IRedirectorOptions): void; 40 | } 41 | -------------------------------------------------------------------------------- /packages/core/src/login/oidc/__mocks__/IncomingRedirectHandler.ts: -------------------------------------------------------------------------------- 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 type { EventEmitter } from "events"; 23 | import { jest } from "@jest/globals"; 24 | 25 | import type IIncomingRedirectHandler from "../IIncomingRedirectHandler"; 26 | 27 | const canHandle = jest.fn((_url: string) => Promise.resolve(true)); 28 | 29 | const handle = jest.fn((_url: string, _emitter: EventEmitter | undefined) => 30 | Promise.resolve({ 31 | sessionId: "global", 32 | isLoggedIn: true, 33 | webId: "https://pod.com/profile/card#me", 34 | fetch: jest.fn(globalThis.fetch), 35 | }), 36 | ); 37 | 38 | export const mockCanHandleIncomingRedirect = canHandle; 39 | export const mockHandleIncomingRedirect = handle; 40 | 41 | export const mockIncomingRedirectHandler = (): IIncomingRedirectHandler => { 42 | return { 43 | canHandle, 44 | handle, 45 | }; 46 | }; 47 | -------------------------------------------------------------------------------- /packages/core/src/login/oidc/__mocks__/IssuerConfig.ts: -------------------------------------------------------------------------------- 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 type { IIssuerConfig } from "../../.."; 23 | 24 | export const mockIssuerConfig = (): IIssuerConfig => { 25 | return { 26 | issuer: "https://idp.com", 27 | authorizationEndpoint: "https://idp.com/auth", 28 | tokenEndpoint: "https://idp.com/token", 29 | jwksUri: "https://idp.com/jwks", 30 | subjectTypesSupported: [], 31 | claimsSupported: [], 32 | grantTypesSupported: ["refresh_token"], 33 | scopesSupported: ["openid"], 34 | }; 35 | }; 36 | -------------------------------------------------------------------------------- /packages/core/src/login/oidc/__mocks__/IssuerConfigFetcher.ts: -------------------------------------------------------------------------------- 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 type { IIssuerConfig } from "../IIssuerConfig"; 23 | import type { IIssuerConfigFetcher } from "../IIssuerConfigFetcher"; 24 | 25 | export function mockIssuerConfigFetcher( 26 | config: IIssuerConfig, 27 | ): IIssuerConfigFetcher { 28 | return { 29 | fetchConfig: async (): Promise => config, 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /packages/core/src/login/oidc/redirectIriUtils.ts: -------------------------------------------------------------------------------- 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 | export function isValidRedirectUrl(redirectUrl: string): boolean { 23 | // If the redirect URL is not a valid URL, an error will be thrown. 24 | try { 25 | const urlObject = new URL(redirectUrl); 26 | const noReservedQuery = 27 | !urlObject.searchParams.has("code") && 28 | !urlObject.searchParams.has("state"); 29 | // As per https://tools.ietf.org/html/rfc6749#section-3.1.2, the redirect URL 30 | // must not include a hash fragment. 31 | const noHash = urlObject.hash === ""; 32 | return noReservedQuery && noHash; 33 | } catch (e) { 34 | return false; 35 | } 36 | } 37 | 38 | export function removeOpenIdParams(redirectUrl: string): URL { 39 | const cleanedUpUrl = new URL(redirectUrl); 40 | // For auth code flow 41 | cleanedUpUrl.searchParams.delete("state"); 42 | cleanedUpUrl.searchParams.delete("code"); 43 | // For login error 44 | cleanedUpUrl.searchParams.delete("error"); 45 | cleanedUpUrl.searchParams.delete("error_description"); 46 | // For RFC9207 47 | cleanedUpUrl.searchParams.delete("iss"); 48 | return cleanedUpUrl; 49 | } 50 | -------------------------------------------------------------------------------- /packages/core/src/logout/GeneralLogoutHandler.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | import type ILogoutHandler from "./ILogoutHandler"; 28 | import type { ISessionInfoManager } from "../sessionInfo/ISessionInfoManager"; 29 | 30 | /** 31 | * @hidden 32 | */ 33 | export default class GeneralLogoutHandler implements ILogoutHandler { 34 | constructor(private sessionInfoManager: ISessionInfoManager) { 35 | this.sessionInfoManager = sessionInfoManager; 36 | } 37 | 38 | async canHandle(): Promise { 39 | return true; 40 | } 41 | 42 | async handle(userId: string): Promise { 43 | await this.sessionInfoManager.clear(userId); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/core/src/logout/__mocks__/LogoutHandler.ts: -------------------------------------------------------------------------------- 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 { jest } from "@jest/globals"; 23 | import { clear } from "../../sessionInfo/SessionInfoManager"; 24 | import type { ILogoutHandler, IStorageUtility } from "../../index"; 25 | 26 | export const mockLogoutHandler = ( 27 | storageUtility: IStorageUtility, 28 | ): ILogoutHandler => { 29 | return { 30 | canHandle: jest.fn(async (_localUserId: string) => Promise.resolve(true)), 31 | handle: jest.fn(async (localUserId: string) => { 32 | return clear(localUserId, storageUtility); 33 | }), 34 | }; 35 | }; 36 | -------------------------------------------------------------------------------- /packages/core/src/mocks.spec.ts: -------------------------------------------------------------------------------- 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 { test, describe, expect } from "@jest/globals"; 23 | import * as mocks from "./mocks"; 24 | 25 | describe("mocks", () => { 26 | test("exposes the various mocks", () => { 27 | // Storage: 28 | expect(mocks.mockStorage).toBeDefined(); 29 | expect(mocks.mockStorageUtility).toBeDefined(); 30 | expect(mocks.StorageUtilityGetResponse).toBeDefined(); 31 | expect(mocks.StorageUtilityMock).toBeDefined(); 32 | 33 | // Incoming Redirects: 34 | expect(mocks.mockIncomingRedirectHandler).toBeDefined(); 35 | expect(mocks.mockCanHandleIncomingRedirect).toBeDefined(); 36 | expect(mocks.mockHandleIncomingRedirect).toBeDefined(); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /packages/core/src/mocks.ts: -------------------------------------------------------------------------------- 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 | export { 23 | mockStorage, 24 | mockStorageUtility, 25 | StorageUtilityMock, 26 | StorageUtilityGetResponse, 27 | } from "./storage/__mocks__/StorageUtility"; 28 | 29 | export { 30 | mockIncomingRedirectHandler, 31 | mockCanHandleIncomingRedirect, 32 | mockHandleIncomingRedirect, 33 | } from "./login/oidc/__mocks__/IncomingRedirectHandler"; 34 | 35 | export { mockLogoutHandler } from "./logout/__mocks__/LogoutHandler"; 36 | -------------------------------------------------------------------------------- /packages/core/src/sessionInfo/ISessionInfo.spec.ts: -------------------------------------------------------------------------------- 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 { describe, it, expect } from "@jest/globals"; 23 | 24 | import { isSupportedTokenType } from "./ISessionInfo"; 25 | 26 | describe("isSupportedTokenType", () => { 27 | it("returns true for supported token types", async () => { 28 | expect(isSupportedTokenType("DPoP")).toBe(true); 29 | expect(isSupportedTokenType("Bearer")).toBe(true); 30 | }); 31 | 32 | it("returns false for unkonwn token types", async () => { 33 | expect(isSupportedTokenType("SomeTokenType")).toBe(false); 34 | expect(isSupportedTokenType("")).toBe(false); 35 | expect(isSupportedTokenType(undefined as unknown as string)).toBe(false); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /packages/core/src/sessionInfo/ISessionInfoManager.spec.ts: -------------------------------------------------------------------------------- 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 { describe, it, expect } from "@jest/globals"; 23 | 24 | import { USER_SESSION_PREFIX } from "./ISessionInfoManager"; 25 | 26 | describe("ISessionInfoManager", () => { 27 | it("should export a default user session prefix", () => { 28 | expect(USER_SESSION_PREFIX).toBe("solidClientAuthenticationUser"); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /packages/core/src/sessionInfo/__mocks__/SessionInfoManager.ts: -------------------------------------------------------------------------------- 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 type { 23 | ISessionInfo, 24 | ISessionInfoManager, 25 | ISessionInternalInfo, 26 | IStorageUtility, 27 | } from "@inrupt/solid-client-authn-core"; 28 | import { SessionInfoManagerBase } from "../SessionInfoManager"; 29 | 30 | class SessionInfoManager extends SessionInfoManagerBase { 31 | get(): Promise<(ISessionInfo & ISessionInternalInfo) | undefined> { 32 | throw new Error("Method not implemented."); 33 | } 34 | } 35 | 36 | export function mockSessionInfoManager( 37 | storageUtility: IStorageUtility, 38 | ): ISessionInfoManager { 39 | return new SessionInfoManager(storageUtility); 40 | } 41 | -------------------------------------------------------------------------------- /packages/core/src/storage/IStorage.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * Interface that various platforms should implement for their own storage implementation 24 | */ 25 | export default interface IStorage { 26 | get: (key: string) => Promise; 27 | set: (key: string, value: string) => Promise; 28 | delete: (key: string) => Promise; 29 | } 30 | -------------------------------------------------------------------------------- /packages/core/src/storage/IStorageUtility.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | export default interface IStorageUtility { 28 | get( 29 | key: string, 30 | options?: { errorIfNull?: boolean; secure?: boolean }, 31 | ): Promise; 32 | set( 33 | key: string, 34 | value: string, 35 | options?: { secure?: boolean }, 36 | ): Promise; 37 | delete(key: string, options?: { secure?: boolean }): Promise; 38 | getForUser( 39 | userId: string, 40 | key: string, 41 | options?: { errorIfNull?: boolean; secure?: boolean }, 42 | ): Promise; 43 | setForUser( 44 | userId: string, 45 | values: Record, 46 | options?: { secure?: boolean }, 47 | ): Promise; 48 | deleteForUser( 49 | userId: string, 50 | key: string, 51 | options?: { secure?: boolean }, 52 | ): Promise; 53 | deleteAllUserData( 54 | userId: string, 55 | options?: { secure?: boolean }, 56 | ): Promise; 57 | } 58 | -------------------------------------------------------------------------------- /packages/core/src/storage/InMemoryStorage.spec.ts: -------------------------------------------------------------------------------- 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 { describe, it, expect } from "@jest/globals"; 23 | 24 | import InMemoryStorage from "./InMemoryStorage"; 25 | 26 | describe("InMemoryStorage", () => { 27 | const nodeStorage = new InMemoryStorage(); 28 | it("can set an item", async () => { 29 | await expect(nodeStorage.set("a", "A")).resolves.not.toBeNull(); 30 | }); 31 | it("can get an item", async () => { 32 | expect(await nodeStorage.get("a")).toBe("A"); 33 | }); 34 | it("returns undefined if the key does not exist", async () => { 35 | expect(await nodeStorage.get("doesNotExist")).toBeUndefined(); 36 | }); 37 | it("can delete an item", async () => { 38 | await nodeStorage.delete("a"); 39 | expect(await nodeStorage.get("a")).toBeUndefined(); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /packages/core/src/storage/InMemoryStorage.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | import type IStorage from "./IStorage"; 28 | 29 | /** 30 | * @hidden 31 | */ 32 | export default class InMemoryStorage implements IStorage { 33 | private map: Record = {}; 34 | 35 | async get(key: string): Promise { 36 | return this.map[key] || undefined; 37 | } 38 | 39 | async set(key: string, value: string): Promise { 40 | this.map[key] = value; 41 | } 42 | 43 | async delete(key: string): Promise { 44 | delete this.map[key]; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /packages/core/src/util/handlerPattern/IHandleable.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | /** 28 | * A handler is an abstract concept for execution. It knows what it can handle, 29 | * and will perform the action if needed. 30 | * @hidden 31 | */ 32 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 33 | export default interface IHandleable

, R> { 34 | canHandle(...params: P): Promise; 35 | handle(...params: P): Promise; 36 | } 37 | -------------------------------------------------------------------------------- /packages/core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.build.json", 3 | 4 | "compilerOptions": { 5 | "lib": ["es2022", "dom"], 6 | "outDir": "./dist" 7 | }, 8 | 9 | "typedocOptions": { 10 | "out": "website/docs/api/core", 11 | "entryPoints": ["./src/index.ts"], 12 | "entryDocument": "index.rst", 13 | "hideInPageTOC": true, 14 | "plugin": ["typedoc-plugin-markdown"] 15 | }, 16 | 17 | "include": ["src/**/*"], 18 | "exclude": ["src/**/*.spec.ts", "**/__mocks__/*"] 19 | } 20 | -------------------------------------------------------------------------------- /packages/node/.npmignore: -------------------------------------------------------------------------------- 1 | .git 2 | docs 3 | coverage 4 | report 5 | .vscode 6 | examples 7 | .prettierignore 8 | sonar-project.properties 9 | -------------------------------------------------------------------------------- /packages/node/.prettierignore: -------------------------------------------------------------------------------- 1 | # TODO: figure out why the root .prettierignore file isn't detected: 2 | docs/**/*.md 3 | examples/**/*.md 4 | -------------------------------------------------------------------------------- /packages/node/docs/api/README.md: -------------------------------------------------------------------------------- 1 | # apidocs 2 | 3 | Builds the API docs site from generated API `\*.md` files. 4 | 5 | ## To Build 6 | 7 | To build: 8 | 9 | 0. Prereq: [python3](https://www.python.org/downloads/), [Node.js](https://nodejs.org/). 10 | 11 | 1. Optional but recommended. Create a virtual env: 12 | 13 | ```sh 14 | python3 -m venv 15 | source /bin/activate 16 | ``` 17 | 18 | 1. Generate the API .md files: 19 | 20 | npm ci; npm run build-api-docs 21 | 22 | 1. Go to the apidocs directory: 23 | 24 | cd apidocs 25 | 26 | 1. Install the docs requirements (different from library docs requirements): 27 | 28 | ```sh 29 | pip install -r https://raw.githubusercontent.com/inrupt/docs-assets/main/requirements/api/requirements.txt 30 | ``` 31 | 32 | 1. Make the API docs: 33 | 34 | ```sh 35 | make html 36 | ``` 37 | 38 | There should be a `build/html` directory with the html artifacts. 39 | 40 | When finished, can deactivate your virtual env. 41 | 42 | ## Third Party Licenses 43 | 44 | The `requirements.txt` lists the 3rd party libraries used for the docs. 45 | For the licenses, see the shared 46 | [inrupt/docs-assets](https://github.com/inrupt/docs-assets#readme). 47 | 48 | -------------------------------------------------------------------------------- /packages/node/docs/api/redirects.txt: -------------------------------------------------------------------------------- 1 | developer-tools/api/javascript/solid-client-authn-node/README.html -> developer-tools/api/javascript/solid-client-authn-node/index.html 2 | developer-tools/api/javascript/solid-client-authn-node/classes/_session_.session.html -> developer-tools/api/javascript/solid-client-authn-node/classes/session.html 3 | developer-tools/api/javascript/solid-client-authn-node/classes/_sessionmanager_.sessionmanager.html -> developer-tools/api/javascript/solid-client-authn-node/classes/sessionmanager.html 4 | developer-tools/api/javascript/solid-client-authn-node/interfaces/_sessionmanager_.isessionmanager.html -> developer-tools/api/javascript/solid-client-authn-node/classes/notimplementederror.html 5 | developer-tools/api/javascript/solid-client-authn-node/interfaces/_session_.isessionoptions.html -> developer-tools/api/javascript/solid-client-authn-node/interfaces/isessionoptions.html 6 | developer-tools/api/javascript/solid-client-authn-node/modules/_session_.html -> developer-tools/api/javascript/solid-client-authn-node/classes/session.html -------------------------------------------------------------------------------- /packages/node/docs/api/source/functions.md: -------------------------------------------------------------------------------- 1 | # Functions 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/node/docs/api/source/index.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | =========================== 4 | solid-client-authn-node API 5 | =========================== 6 | 7 | .. toctree:: 8 | :glob: 9 | :titlesonly: 10 | 11 | ** -------------------------------------------------------------------------------- /packages/node/examples/script/.env.example: -------------------------------------------------------------------------------- 1 | CLIENT_ID="some-client-id" 2 | CLIENT_SECRET="some-client-secret" 3 | OPENID_PROVIDER="https://login.inrupt.com" 4 | -------------------------------------------------------------------------------- /packages/node/examples/script/README.md: -------------------------------------------------------------------------------- 1 | # Example authenticated script 2 | 3 | To run this example: 4 | 5 | - Copy `.env.example` into `.env.local` 6 | - Edit `.env.local` so that it contains clients credentials registered 7 | at the appropriate OpenID Provider. 8 | - Run `node --env-file=.env.local index.mjs` 9 | -------------------------------------------------------------------------------- /packages/node/examples/script/index.mjs: -------------------------------------------------------------------------------- 1 | import { Session } from "@inrupt/solid-client-authn-node"; 2 | 3 | const session = new Session(); 4 | await session.login({ 5 | oidcIssuer: process.env.OPENID_PROVIDER, 6 | clientId: process.env.CLIENT_ID, 7 | clientSecret: process.env.CLIENT_SECRET, 8 | }); 9 | 10 | console.log(`You are now logged in as ${session.info.webId}`); 11 | 12 | await session.logout(); 13 | -------------------------------------------------------------------------------- /packages/node/examples/script/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@inrupt/demo-authn-node-script", 3 | "private": true, 4 | "version": "2.5.0", 5 | "description": "Demo for script authentication in NodeJS", 6 | "type": "module", 7 | "main": "./index.mjs", 8 | "author": "Inrupt, Inc.", 9 | "license": "MIT", 10 | "dependencies": { 11 | "@inrupt/solid-client-authn-node": "^2.5.0" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/node/examples/server/.env.example: -------------------------------------------------------------------------------- 1 | PORT=3001 2 | OPENID_PROVIDER="https://login.inrupt.com/" 3 | 4 | # Endpoint whenre the app receives the redirection from the OpenID Provider after the user authenticated. 5 | # This must match one of the `redirect_uris` values from the Client ID Document. 6 | REDIRECT_URL="http://localhost:3001/redirect" 7 | 8 | # Endpoint whenre the app receives the redirection from the OpenID Provider after the user logged out. 9 | # This must match one of the `post_logout_redirect_uris` values from the Client ID Document. 10 | POST_LOGOUT_REDIRECT_URL="http://localhost:3001" 11 | 12 | # Solid-OIDC Client identifier for the application. 13 | CLIENT_ID="https://storage.inrupt.com/d70fd154-de71-4627-89f3-9f9515950f7a/client_ids/ca999ecd-7951-4982-b7eb-d4376985f978" 14 | -------------------------------------------------------------------------------- /packages/node/examples/server/README.md: -------------------------------------------------------------------------------- 1 | # Demo: a server-side NodeJS application managing multiple sessions 2 | 3 | This demo shows how you can run a NodeJS server with multiple sessions in parallel. 4 | Check out the code in `src/serverSideApp.mjs` for more details. 5 | 6 | Note that until [this issue](https://github.com/solid/node-solid-server/issues/1533) 7 | is resolved, this will not work against NSS. This demo is only intended to work 8 | against a compliant OIDC implementation, such as Inrupt's ESS. A developer version 9 | of ESS is available on [PodSpaces](https://start.inrupt.com/). 10 | 11 | ## Installing the app 12 | 13 | To install this demo app, 14 | 15 | 1. run `npm ci` and `npm run build` at the root of the repository, 16 | which will trigger the build of the libraries our app depends on. 17 | 2. If you want to customize the Client ID or the OpenID Provider being 18 | used, change the content of .env.example. 19 | 20 | ## Running the app 21 | 22 | Run `node --env-file=.env.example src/serverSideApp.mjs` 23 | 24 | Four endpoints are available: 25 | 26 | - `/login`, to initiate the login process against a Solid Identity Provider 27 | (by default, `https://login.inrupt.com`) 28 | - `/redirect`, where the Solid Identity Provider will redirect users after login 29 | - `/fetch`, where you have to pass a `resource=` query param in 30 | order to fetch a resource (protected resources will require you be logged in and to have been granted READ access to that resource, whereas public resources can be fetched whether you're logged in or not) 31 | - `/logout`, to log out of the session 32 | -------------------------------------------------------------------------------- /packages/node/examples/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@inrupt/demo-authn-node-script-multisession", 3 | "private": true, 4 | "version": "2.5.0", 5 | "description": "Demo for session management in NodeJS", 6 | "main": "src/index.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/inrupt/solid-client-authn-js.git" 10 | }, 11 | "author": "Inrupt, Inc.", 12 | "license": "MIT", 13 | "bugs": { 14 | "url": "https://github.com/inrupt/solid-client-authn-js/issues" 15 | }, 16 | "homepage": "https://github.com/inrupt/solid-client-authn-js#readme", 17 | "dependencies": { 18 | "@inrupt/solid-client": "^2.1.2", 19 | "@inrupt/solid-client-authn-node": "^2.5.0", 20 | "cookie-session": "^2.1.0", 21 | "express": "^5.1.0" 22 | }, 23 | "devDependencies": { 24 | "@types/cookie-session": "^2.0.49", 25 | "@types/express": "^5.0.2" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/node/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@inrupt/solid-client-authn-node", 3 | "version": "2.5.0", 4 | "license": "MIT", 5 | "main": "dist/index.js", 6 | "types": "dist/index.d.ts", 7 | "module": "dist/index.mjs", 8 | "repository": { 9 | "type": "git", 10 | "url": "https://github.com/inrupt/solid-client-authn-js.git" 11 | }, 12 | "exports": { 13 | ".": { 14 | "require": "./dist/index.js", 15 | "import": "./dist/index.mjs", 16 | "types": "./dist/index.d.ts" 17 | } 18 | }, 19 | "scripts": { 20 | "prepublishOnly": "npm run build", 21 | "build": "rollup --config rollup.config.mjs", 22 | "licenses:check": "license-checker --production --out license.csv --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\"", 23 | "build-api-docs": "npx typedoc --out docs/api/source/api --readme none", 24 | "build-docs-preview-site": "npm run build-api-docs; cd docs/api; make html" 25 | }, 26 | "devDependencies": { 27 | "@types/node": "^22.15.30", 28 | "@types/uuid": "^10.0.0" 29 | }, 30 | "dependencies": { 31 | "@inrupt/solid-client-authn-core": "^2.5.0", 32 | "jose": "^5.1.3", 33 | "openid-client": "^5.7.1", 34 | "uuid": "^11.1.0" 35 | }, 36 | "publishConfig": { 37 | "access": "public" 38 | }, 39 | "engines": { 40 | "node": "^18.0.0 || ^20.0.0 || ^22.0.0" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/node/rollup.config.mjs: -------------------------------------------------------------------------------- 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 pkg from "./package.json" with { type: "json" }; 23 | import createConfig from '@inrupt/base-rollup-config'; 24 | 25 | export default createConfig(pkg); 26 | -------------------------------------------------------------------------------- /packages/node/sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=inrupt_solid-client-authn-node 2 | sonar.projectName=solid-client-authn-node 3 | sonar.organization=inrupt 4 | 5 | # Path is relative to the sonar-project.properties file. Defaults to . 6 | sonar.sources=src 7 | 8 | # Typescript tsconfigPath JSON file 9 | sonar.typescript.tsconfigPath=. 10 | 11 | # Comma-delimited list of paths to LCOV coverage report files. Paths may be absolute or relative to the project root. 12 | sonar.javascript.lcov.reportPaths=./coverage/lcov.info 13 | 14 | # Exclude tests from analysis 15 | sonar.exclusions=**/*.test.ts 16 | -------------------------------------------------------------------------------- /packages/node/src/constant.ts: -------------------------------------------------------------------------------- 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 { SOLID_CLIENT_AUTHN_KEY_PREFIX } from "@inrupt/solid-client-authn-core"; 23 | 24 | export const KEY_REGISTERED_SESSIONS = `${SOLID_CLIENT_AUTHN_KEY_PREFIX}registeredSessions`; 25 | -------------------------------------------------------------------------------- /packages/node/src/index.spec.ts: -------------------------------------------------------------------------------- 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 { it, expect } from "@jest/globals"; 23 | 24 | import { Session } from "./index"; 25 | 26 | it("exports the public API from the entrypoint", () => { 27 | expect(Session).toBeDefined(); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/node/src/index.ts: -------------------------------------------------------------------------------- 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 | export { Session, ISessionOptions } from "./Session"; 23 | 24 | export { 25 | getSessionFromStorage, 26 | getSessionIdFromStorageAll, 27 | clearSessionFromStorageAll, 28 | refreshSession, 29 | } from "./multiSession"; 30 | 31 | export { refreshTokens, logout } from "./multisession.fromTokens"; 32 | 33 | // Re-export of types defined in the core module and produced/consumed by our API 34 | export { 35 | ILoginInputOptions, 36 | ILogoutOptions, 37 | ISessionInfo, 38 | IStorage, 39 | NotImplementedError, 40 | ConfigurationError, 41 | InMemoryStorage, 42 | EVENTS, 43 | type SessionTokenSet, 44 | type AuthorizationRequestState, 45 | } from "@inrupt/solid-client-authn-core"; 46 | -------------------------------------------------------------------------------- /packages/node/src/login/__mocks__/LoginHandler.ts: -------------------------------------------------------------------------------- 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 type { 23 | ILoginOptions, 24 | ILoginHandler, 25 | ISessionInfo, 26 | } from "@inrupt/solid-client-authn-core"; 27 | import { jest } from "@jest/globals"; 28 | 29 | export const LoginHandlerResponse: ISessionInfo = { 30 | isLoggedIn: false, 31 | sessionId: "global", 32 | }; 33 | 34 | export const mockLoginHandler = (): ILoginHandler => { 35 | return { 36 | canHandle: jest.fn((_options: ILoginOptions) => Promise.resolve(true)), 37 | handle: jest.fn((_options: ILoginOptions) => Promise.resolve(undefined)), 38 | }; 39 | }; 40 | -------------------------------------------------------------------------------- /packages/node/src/login/oidc/AggregateIncomingRedirectHandler.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | /** 28 | * Responsible for selecting the correct OidcHandler to handle the provided OIDC Options 29 | */ 30 | import type { 31 | IIncomingRedirectHandler, 32 | ISessionInfo, 33 | SessionConfig, 34 | } from "@inrupt/solid-client-authn-core"; 35 | import { AggregateHandler } from "@inrupt/solid-client-authn-core"; 36 | import type { EventEmitter } from "events"; 37 | 38 | /** 39 | * @hidden 40 | */ 41 | export default class AggregateIncomingRedirectHandler 42 | extends AggregateHandler< 43 | [string, EventEmitter, SessionConfig], 44 | ISessionInfo & { fetch: typeof fetch } 45 | > 46 | implements IIncomingRedirectHandler 47 | { 48 | constructor(redirectHandlers: IIncomingRedirectHandler[]) { 49 | super(redirectHandlers); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /packages/node/src/login/oidc/AggregateOidcHandler.spec.ts: -------------------------------------------------------------------------------- 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 type { IOidcHandler } from "@inrupt/solid-client-authn-core"; 23 | import { AggregateHandler } from "@inrupt/solid-client-authn-core"; 24 | import { jest, it, describe, expect } from "@jest/globals"; 25 | import AggregateOidcHandler from "./AggregateOidcHandler"; 26 | 27 | jest.mock("@inrupt/solid-client-authn-core"); 28 | 29 | describe("AggregateOidcHandler", () => { 30 | it("should pass injected handlers to its superclass", () => { 31 | // We just test if the parent is called. 32 | // eslint-disable-next-line no-new 33 | new AggregateOidcHandler(["Some handler"] as unknown as IOidcHandler[]); 34 | 35 | expect((AggregateHandler as jest.Mock).mock.calls).toEqual([ 36 | [["Some handler"]], 37 | ]); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /packages/node/src/login/oidc/AggregateOidcHandler.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | /** 28 | * Responsible for selecting the correct OidcHandler to handle the provided OIDC Options 29 | */ 30 | import type { 31 | IOidcHandler, 32 | IOidcOptions, 33 | LoginResult, 34 | } from "@inrupt/solid-client-authn-core"; 35 | import { AggregateHandler } from "@inrupt/solid-client-authn-core"; 36 | 37 | /** 38 | * @hidden 39 | */ 40 | export default class AggregateOidcHandler 41 | extends AggregateHandler<[IOidcOptions], LoginResult> 42 | implements IOidcHandler 43 | { 44 | constructor(oidcLoginHandlers: IOidcHandler[]) { 45 | super(oidcLoginHandlers); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/node/src/login/oidc/Redirector.spec.ts: -------------------------------------------------------------------------------- 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 { jest, it, describe, expect } from "@jest/globals"; 23 | import Redirector from "./Redirector"; 24 | 25 | /** 26 | * Test for Redirector 27 | */ 28 | describe("Redirector", () => { 29 | describe("Redirect", () => { 30 | it("calls the provided redirect callback", () => { 31 | const redirector = new Redirector(); 32 | const redirectCallback = jest.fn(); 33 | redirector.redirect("https://someUrl.com/redirect", { 34 | handleRedirect: redirectCallback, 35 | }); 36 | expect(redirectCallback).toHaveBeenCalled(); 37 | }); 38 | 39 | it("throws if no handler is provided", () => { 40 | const redirector = new Redirector(); 41 | expect(() => 42 | redirector.redirect("https://someUrl.com/redirect"), 43 | ).toThrow(); 44 | }); 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /packages/node/src/login/oidc/Redirector.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | import type { 28 | IRedirector, 29 | IRedirectorOptions, 30 | } from "@inrupt/solid-client-authn-core"; 31 | 32 | /** 33 | * @hidden 34 | */ 35 | export default class Redirector implements IRedirector { 36 | redirect(redirectUrl: string, options?: IRedirectorOptions): void { 37 | if (options && options.handleRedirect) { 38 | options.handleRedirect(redirectUrl); 39 | } else { 40 | throw new Error( 41 | "A redirection handler must be provided in the Node environment.", 42 | ); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/node/src/login/oidc/TokenRequester.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | import { NotImplementedError } from "@inrupt/solid-client-authn-core"; 28 | 29 | /** 30 | * @hidden 31 | */ 32 | export interface ITokenRequester { 33 | request(localUserId: string, body: Record): Promise; 34 | } 35 | 36 | /** 37 | * @hidden 38 | */ 39 | export default class TokenRequester { 40 | async request( 41 | _sessionId: string, 42 | _body: Record, 43 | ): Promise { 44 | throw new NotImplementedError("TokenRequester not implemented for Node"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /packages/node/src/login/oidc/__mocks__/IOidcHandler.ts: -------------------------------------------------------------------------------- 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 type { 23 | IOidcHandler, 24 | IOidcOptions, 25 | ISessionInfo, 26 | } from "@inrupt/solid-client-authn-core"; 27 | import { jest } from "@jest/globals"; 28 | 29 | import { SessionCreatorGetSessionResponse } from "../../../sessionInfo/__mocks__/SessionInfoManager"; 30 | 31 | export const OidcHandlerHandleResponse: ISessionInfo = 32 | SessionCreatorGetSessionResponse; 33 | 34 | export const OidcHandlerMock: jest.Mocked = { 35 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 36 | canHandle: jest.fn((_options: IOidcOptions) => Promise.resolve(true)), 37 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 38 | handle: jest.fn(async (_options: IOidcOptions) => Promise.resolve(undefined)), 39 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 40 | } as any; 41 | -------------------------------------------------------------------------------- /packages/node/src/login/oidc/__mocks__/Redirector.ts: -------------------------------------------------------------------------------- 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 type { IRedirector } from "@inrupt/solid-client-authn-core"; 23 | import { jest } from "@jest/globals"; 24 | 25 | export const mockedRedirector = jest.fn(); 26 | export const mockRedirector = (): IRedirector => { 27 | return { 28 | redirect: mockedRedirector, 29 | }; 30 | }; 31 | -------------------------------------------------------------------------------- /packages/node/src/login/oidc/refresh/__mocks__/TokenRefresher.ts: -------------------------------------------------------------------------------- 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 { jest } from "@jest/globals"; 23 | import type { 24 | ITokenRefresher, 25 | TokenEndpointResponse, 26 | } from "@inrupt/solid-client-authn-core"; 27 | 28 | // Some identifiers are in camelcase on purpose. 29 | /* eslint-disable camelcase */ 30 | 31 | export const mockTokenRefresher = ( 32 | tokenSet: TokenEndpointResponse, 33 | ): ITokenRefresher => { 34 | return { 35 | refresh: jest.fn().mockResolvedValue(tokenSet), 36 | }; 37 | }; 38 | 39 | const mockIdTokenPayload = () => { 40 | return { 41 | sub: "https://my.webid", 42 | iss: "https://my.idp/", 43 | aud: "https://resource.example.org", 44 | exp: 1662266216, 45 | iat: 1462266216, 46 | }; 47 | }; 48 | 49 | export const mockDefaultTokenSet = (): TokenEndpointResponse => { 50 | return { 51 | accessToken: "some refreshed access token", 52 | idToken: JSON.stringify(mockIdTokenPayload()), 53 | expiresAt: Date.now() + 3600, 54 | }; 55 | }; 56 | 57 | export const mockDefaultTokenRefresher = (): ITokenRefresher => 58 | mockTokenRefresher(mockDefaultTokenSet()); 59 | -------------------------------------------------------------------------------- /packages/node/src/storage/StorageUtility.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | /** 28 | * A helper class that will validate items taken from local storage 29 | */ 30 | import type { IStorage } from "@inrupt/solid-client-authn-core"; 31 | import { StorageUtility } from "@inrupt/solid-client-authn-core"; 32 | 33 | /** 34 | * This class in a no-value-added extension of StorageUtility from the core module. 35 | * The reason it has to be declared is for TSyringe to find the decorators in the 36 | * same modules as where the dependency container is declared (in this case, 37 | * the browser module, with the dependancy container in dependencies.ts). 38 | * @hidden 39 | */ 40 | export default class StorageUtilityNode extends StorageUtility { 41 | constructor(secureStorage: IStorage, insecureStorage: IStorage) { 42 | super(secureStorage, insecureStorage); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /packages/node/src/util/UuidGenerator.spec.ts: -------------------------------------------------------------------------------- 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 { jest, it, describe, expect } from "@jest/globals"; 23 | import UuidGenerator from "./UuidGenerator"; 24 | 25 | jest.mock("uuid"); 26 | 27 | describe("UuidGenerator", () => { 28 | it("should simply wrap the `uuid` module", () => { 29 | const uuidMock: { v4: jest.Mock } = jest.requireMock("uuid") as any; 30 | uuidMock.v4.mockReturnValueOnce("some uuid"); 31 | 32 | const generator = new UuidGenerator(); 33 | expect(generator.v4()).toBe("some uuid"); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /packages/node/src/util/UuidGenerator.ts: -------------------------------------------------------------------------------- 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 | /** 23 | * @hidden 24 | * @packageDocumentation 25 | */ 26 | 27 | /** 28 | * A wrapper class for uuid 29 | */ 30 | import { v4 } from "uuid"; 31 | 32 | /** 33 | * @hidden 34 | */ 35 | export interface IUuidGenerator { 36 | v4(): string; 37 | } 38 | 39 | /** 40 | * @hidden 41 | */ 42 | export default class UuidGenerator { 43 | // eslint-disable-next-line class-methods-use-this 44 | v4(): string { 45 | return v4(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/node/src/util/__mocks__/UuidGenerator.ts: -------------------------------------------------------------------------------- 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 { jest } from "@jest/globals"; 23 | import type { IUuidGenerator } from "../UuidGenerator"; 24 | 25 | export const UuidGeneratorMockResponse = "fee3fa53-a6a9-475c-a0da-b1343a4fff76"; 26 | 27 | export const UuidGeneratorMock: jest.Mocked = { 28 | v4: jest.fn(() => UuidGeneratorMockResponse), 29 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 30 | } as any; 31 | -------------------------------------------------------------------------------- /packages/node/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.build.json", 3 | 4 | "compilerOptions": { 5 | "lib": ["es2022"], 6 | "outDir": "./dist" 7 | }, 8 | 9 | "typedocOptions": { 10 | "out": "website/docs/api/node", 11 | "entryPoints": ["./src/index.ts"], 12 | "entryDocument": "index.rst", 13 | "hideInPageTOC": true, 14 | "plugin": ["typedoc-plugin-markdown"] 15 | }, 16 | 17 | "include": ["src/**/*"], 18 | "exclude": ["src/**/*.spec.ts", "**/__mocks__/*"] 19 | } 20 | -------------------------------------------------------------------------------- /packages/oidc-browser/.npmignore: -------------------------------------------------------------------------------- 1 | coverage 2 | report 3 | .vscode 4 | .prettierignore 5 | README.md 6 | sonar-project.properties 7 | -------------------------------------------------------------------------------- /packages/oidc-browser/.prettierignore: -------------------------------------------------------------------------------- 1 | # TODO: figure out why the root .prettierignore file isn't detected: 2 | docs/**/*.md -------------------------------------------------------------------------------- /packages/oidc-browser/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@inrupt/oidc-client-ext", 3 | "version": "2.5.0", 4 | "description": "A module extending oidc-client-js with new features, such as dynamic client registration and DPoP support.", 5 | "homepage": "https://github.com/inrupt/solid-client-authn-js/tree/main/packages/oidc/", 6 | "bugs": "https://github.com/inrupt/solid-client-authn-js/issues", 7 | "main": "dist/index.js", 8 | "module": "dist/index.es.js", 9 | "types": "dist/index.d.ts", 10 | "sideEffects": false, 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/inrupt/solid-client-authn-js.git" 14 | }, 15 | "scripts": { 16 | "prepublishOnly": "npm run build", 17 | "build": "rollup --config rollup.config.mjs", 18 | "licenses:check": "license-checker --production --out license.csv --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\"", 19 | "build-docs-preview-site": "npm run build-api-docs; cd docs/prose; make html; cd ../api; make html; cd ../; rm -r dist || true; mkdir -p dist/prose dist/api; cp -r prose/build/html/. dist/prose/; cp -r api/build/html/. dist/api/; echo 'Draft documentation: Prose, API docs.' >> dist/index.html" 20 | }, 21 | "license": "MIT", 22 | "devDependencies": { 23 | "@types/jest": "^29.5.14", 24 | "@types/uuid": "^10.0.0", 25 | "ts-node": "^10.9.2" 26 | }, 27 | "dependencies": { 28 | "@inrupt/oidc-client": "^1.11.6", 29 | "@inrupt/solid-client-authn-core": "^2.5.0", 30 | "jose": "^5.1.3", 31 | "uuid": "^11.1.0" 32 | }, 33 | "publishConfig": { 34 | "access": "public" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/oidc-browser/rollup.config.mjs: -------------------------------------------------------------------------------- 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 { createSharedConfig } from "@inrupt/base-rollup-config"; 23 | // eslint-disable-next-line import/extensions 24 | import pkg from "./package.json" with { type: "json" }; 25 | 26 | export default { 27 | input: "./src/index.ts", 28 | output: [ 29 | { 30 | file: pkg.main, 31 | format: "cjs", 32 | }, 33 | { 34 | file: pkg.module, 35 | format: "esm", 36 | }, 37 | ], 38 | ...createSharedConfig(pkg), 39 | }; 40 | -------------------------------------------------------------------------------- /packages/oidc-browser/sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=inrupt_oidc-client-ext 2 | sonar.projectName=oidc-client-ext 3 | sonar.organization=inrupt 4 | 5 | # Path is relative to the sonar-project.properties file. Defaults to . 6 | sonar.sources=src 7 | 8 | # Typescript tsconfigPath JSON file 9 | sonar.typescript.tsconfigPath=. 10 | 11 | # Comma-delimited list of paths to LCOV coverage report files. Paths may be absolute or relative to the project root. 12 | sonar.javascript.lcov.reportPaths=./coverage/lcov.info 13 | 14 | # Exclude tests from analysis 15 | sonar.exclusions=**/*.test.ts 16 | -------------------------------------------------------------------------------- /packages/oidc-browser/src/index.ts: -------------------------------------------------------------------------------- 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 | export { 23 | Version, 24 | Log, 25 | OidcClient, 26 | OidcClientSettings, 27 | WebStorageStateStore, 28 | InMemoryWebStorage, 29 | UserManager, 30 | AccessTokenEvents, 31 | MetadataService, 32 | CordovaPopupNavigator, 33 | CordovaIFrameNavigator, 34 | CheckSessionIFrame, 35 | SigninRequest, 36 | SigninResponse, 37 | // TODO: Investigate why this fails 38 | // TokenRevocationClient, 39 | SessionMonitor, 40 | // Global, 41 | User, 42 | } from "@inrupt/oidc-client"; 43 | 44 | export { registerClient } from "./dcr/clientRegistrar"; 45 | export { 46 | getTokens, 47 | TokenEndpointInput, 48 | CodeExchangeResult, 49 | } from "./dpop/tokenExchange"; 50 | export { refresh } from "./refresh/refreshGrant"; 51 | export { 52 | normalizeCallbackUrl, 53 | clearOidcPersistentStorage, 54 | } from "./cleanup/cleanup"; 55 | -------------------------------------------------------------------------------- /packages/oidc-browser/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.build.json", 3 | 4 | "compilerOptions": { 5 | "lib": ["es2022", "dom"], 6 | "outDir": "./dist" 7 | }, 8 | 9 | "typedocOptions": { 10 | "out": "website/docs/api/oidc-client-ext", 11 | "entryPoints": ["./src/index.ts"], 12 | "plugin": ["typedoc-plugin-markdown"] 13 | }, 14 | 15 | "include": ["src/**/*"], 16 | "exclude": ["*.spec.ts"] 17 | } 18 | -------------------------------------------------------------------------------- /playwright.client-authn.config.ts: -------------------------------------------------------------------------------- 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 type { PlaywrightTestConfig } from "@playwright/test"; 23 | import { baseConfig } from "./playwright.shared.config"; 24 | // The extension is necessary for JSON imports. 25 | // eslint-disable-next-line import/extensions 26 | import CONSTANTS from "./playwright.client-authn.constants.json"; 27 | 28 | const config: PlaywrightTestConfig = { 29 | ...baseConfig, 30 | testMatch: "e2e.playwright.ts", 31 | webServer: { 32 | command: `cd ./e2e/browser/solid-client-authn-browser/test-app/ && npm run dev -- -p ${CONSTANTS.CLIENT_AUTHN_TEST_PORT}`, 33 | port: CONSTANTS.CLIENT_AUTHN_TEST_PORT, 34 | timeout: 120 * 1000, 35 | reuseExistingServer: !process.env.CI, 36 | }, 37 | }; 38 | 39 | export default config; 40 | -------------------------------------------------------------------------------- /playwright.client-authn.constants.json: -------------------------------------------------------------------------------- 1 | { "CLIENT_AUTHN_TEST_PORT": 3002 } 2 | -------------------------------------------------------------------------------- /tests/environment/customEnvironment.ts: -------------------------------------------------------------------------------- 1 | import Environment from "jest-environment-jsdom"; 2 | 3 | export default class CustomTestEnvironment extends Environment { 4 | async setup() { 5 | await super.setup(); 6 | if (typeof this.global.TextEncoder === "undefined") { 7 | // The following doesn't work from jest-jsdom-polyfills. 8 | // TextEncoder (global or via 'util') references a Uint8Array constructor 9 | // different than the global one used by users in tests. This makes sure the 10 | // same constructor is referenced by both. 11 | this.global.Uint8Array = Uint8Array; 12 | } 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "packages/*/src/**/*.ts", 4 | "e2e/*/**/*.ts", 5 | "e2e/node/jest.setup.ts", 6 | "./jest.setup.ts", 7 | "./jest.config.ts" 8 | ], 9 | "compilerOptions": { 10 | "module": "commonjs", 11 | "strict": true, 12 | "declaration": true, 13 | "noImplicitAny": true, 14 | "esModuleInterop": true, 15 | "target": "es2022", 16 | "sourceMap": true, 17 | "lib": ["es2022", "dom"], 18 | "moduleResolution": "node", 19 | "resolveJsonModule": true, 20 | "outDir": "./dist", 21 | // This is required to transform native ESM from our dependencies using ts-jest. 22 | "allowJs": true 23 | }, 24 | "exclude": ["node_modules", "dist"], 25 | 26 | // We don't provide an 'out' value here, each sub-package should provide its 27 | // own. 28 | "typedocOptions": { 29 | "exclude": [ 30 | // Re-exported functions are already documented in their own modules: 31 | "./packages/*/src/index.ts", 32 | "./packages/*/src/index.browser.ts", 33 | "./e2e/**/*.ts" 34 | ], 35 | "excludeNotDocumented": false, 36 | "excludePrivate": true, 37 | "excludeInternal": true, 38 | "theme": "markdown", 39 | "readme": "none" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.build.json", 3 | 4 | "compilerOptions": { 5 | "baseUrl": "./packages", 6 | "paths": { 7 | "*": ["*/src"] 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "github": { 3 | "silent": true 4 | } 5 | } 6 | --------------------------------------------------------------------------------