├── .github ├── ISSUE_TEMPLATE │ ├── bug.yml │ ├── improvement.yml │ └── new-feature.yml ├── actions │ └── setup-go │ │ └── action.yml ├── pull_request_template.md └── workflows │ ├── pr-builder.yml │ └── release.yml ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── backend ├── .golangci.yml ├── README.md ├── cmd │ └── server │ │ ├── main.go │ │ └── repository │ │ ├── conf │ │ └── deployment.yaml │ │ └── resources │ │ └── graphs │ │ ├── auth_flow_config_basic.json │ │ ├── auth_flow_config_basic_google.json │ │ ├── auth_flow_config_basic_google_github.json │ │ ├── auth_flow_config_basic_with_prompt.json │ │ ├── auth_flow_config_github.json │ │ └── auth_flow_config_google.json ├── dbscripts │ ├── runtimedb │ │ ├── postgress.sql │ │ └── sqlite.sql │ └── thunderdb │ │ ├── postgress.sql │ │ └── sqlite.sql ├── go.mod ├── go.sum ├── internal │ ├── application │ │ ├── handler │ │ │ └── applicationhandler.go │ │ ├── model │ │ │ ├── application.go │ │ │ └── oauthapp.go │ │ ├── provider │ │ │ └── applicationprovider.go │ │ ├── service │ │ │ └── applicationservice.go │ │ └── store │ │ │ ├── constants.go │ │ │ └── store.go │ ├── authn │ │ ├── authnhandler.go │ │ ├── model │ │ │ └── model.go │ │ └── utils │ │ │ └── authnutils.go │ ├── executor │ │ ├── authassert │ │ │ └── authassertexecutor.go │ │ ├── basicauth │ │ │ └── basicauthexecutor.go │ │ ├── githubauth │ │ │ ├── constants.go │ │ │ └── githubauthexecutor.go │ │ ├── googleauth │ │ │ ├── constants.go │ │ │ └── googleauthexecutor.go │ │ ├── oauth │ │ │ ├── model │ │ │ │ └── model.go │ │ │ ├── oauthexecutor.go │ │ │ └── utils │ │ │ │ └── utils.go │ │ └── oidcauth │ │ │ ├── constants.go │ │ │ ├── model │ │ │ └── model.go │ │ │ └── oidcauthexecutor.go │ ├── flow │ │ ├── constants │ │ │ ├── constants.go │ │ │ └── errorconstants.go │ │ ├── dao │ │ │ └── flowdao.go │ │ ├── engine │ │ │ └── flowengine.go │ │ ├── flowservice.go │ │ ├── graphservice │ │ │ └── graphservice.go │ │ ├── handler │ │ │ └── flowexechandler.go │ │ ├── jsonmodel │ │ │ └── model.go │ │ ├── model │ │ │ ├── decisionnode.go │ │ │ ├── executor.go │ │ │ ├── flowmodel.go │ │ │ ├── graph.go │ │ │ ├── node.go │ │ │ ├── promptnode.go │ │ │ └── taskexecutionnode.go │ │ └── utils │ │ │ └── utils.go │ ├── idp │ │ ├── handler │ │ │ └── idphandler.go │ │ ├── model │ │ │ └── idp.go │ │ ├── provider │ │ │ └── idpprovider.go │ │ ├── service │ │ │ └── idpservice.go │ │ └── store │ │ │ ├── constants.go │ │ │ └── store.go │ ├── notification │ │ └── message │ │ │ ├── client │ │ │ ├── client.go │ │ │ ├── custom.go │ │ │ ├── twilio.go │ │ │ └── vonage.go │ │ │ ├── constants │ │ │ └── constants.go │ │ │ ├── model │ │ │ └── model.go │ │ │ └── provider │ │ │ └── provider.go │ ├── oauth │ │ ├── jwt │ │ │ └── jwtgenerator.go │ │ ├── oauth2 │ │ │ ├── authz │ │ │ │ ├── authzhandler.go │ │ │ │ ├── authzvalidator.go │ │ │ │ ├── codepersistence.go │ │ │ │ ├── constants │ │ │ │ │ ├── constants.go │ │ │ │ │ └── dbconstants.go │ │ │ │ ├── model │ │ │ │ │ └── model.go │ │ │ │ └── utils │ │ │ │ │ └── authzutils.go │ │ │ ├── constants │ │ │ │ └── constants.go │ │ │ ├── granthandlers │ │ │ │ ├── authorizationcode.go │ │ │ │ ├── clientcredentials.go │ │ │ │ └── granthandler.go │ │ │ ├── model │ │ │ │ ├── error.go │ │ │ │ ├── parameter.go │ │ │ │ └── token.go │ │ │ ├── token │ │ │ │ └── tokenhandler.go │ │ │ └── utils │ │ │ │ └── oauthutils.go │ │ ├── scope │ │ │ ├── constants │ │ │ │ └── dbconstants.go │ │ │ ├── provider │ │ │ │ └── validatorprovider.go │ │ │ └── validator │ │ │ │ └── scopevalidator.go │ │ └── session │ │ │ ├── model │ │ │ └── sessiondata.go │ │ │ ├── store │ │ │ └── sessiondatastore.go │ │ │ └── utils │ │ │ └── sessionutils.go │ ├── outboundauth │ │ ├── abstract │ │ │ └── abstractauthenticator.go │ │ ├── authenticator.go │ │ ├── basicauth │ │ │ └── basicauthenticator.go │ │ ├── github │ │ │ ├── constants.go │ │ │ └── githubauthenticator.go │ │ ├── model │ │ │ └── model.go │ │ └── oidc │ │ │ ├── oidcauthenticator.go │ │ │ └── utils │ │ │ └── utils.go │ ├── system │ │ ├── cache │ │ │ └── basecache.go │ │ ├── cert │ │ │ └── cert.go │ │ ├── config │ │ │ ├── config.go │ │ │ └── runtimeconfig.go │ │ ├── constants │ │ │ └── serverconstants.go │ │ ├── crypto │ │ │ └── jwt │ │ │ │ └── utils │ │ │ │ └── jwtutils.go │ │ ├── database │ │ │ ├── client │ │ │ │ └── dbclient.go │ │ │ ├── model │ │ │ │ ├── dbquery.go │ │ │ │ └── model.go │ │ │ └── provider │ │ │ │ └── dbprovider.go │ │ ├── error │ │ │ ├── apierror │ │ │ │ └── error.go │ │ │ └── serviceerror │ │ │ │ └── error.go │ │ ├── healthcheck │ │ │ ├── handler │ │ │ │ └── healthcheckhandler.go │ │ │ ├── model │ │ │ │ └── status.go │ │ │ ├── provider │ │ │ │ └── healthcheckprovider.go │ │ │ └── service │ │ │ │ ├── dbconstants.go │ │ │ │ └── healthcheckservice.go │ │ ├── log │ │ │ ├── constants.go │ │ │ ├── field.go │ │ │ └── log.go │ │ ├── managers │ │ │ └── servicemanager.go │ │ ├── server │ │ │ ├── dbconstants.go │ │ │ ├── model.go │ │ │ └── serveroperation.go │ │ ├── services │ │ │ ├── applicationservice.go │ │ │ ├── authnservice.go │ │ │ ├── authorizationservice.go │ │ │ ├── flowexecutionservice.go │ │ │ ├── healthcheckservice.go │ │ │ ├── idpservice.go │ │ │ ├── service.go │ │ │ ├── tokenservice.go │ │ │ └── userservice.go │ │ └── utils │ │ │ ├── hashutil.go │ │ │ ├── httputil.go │ │ │ ├── serverutils.go │ │ │ ├── stringutil.go │ │ │ └── uuidutil.go │ └── user │ │ ├── handler │ │ └── userhandler.go │ │ ├── model │ │ └── user.go │ │ ├── provider │ │ └── userprovider.go │ │ ├── service │ │ └── userservice.go │ │ └── store │ │ ├── constants.go │ │ └── store.go └── scripts │ └── init_script.sh ├── build.sh ├── docs └── apis │ ├── application.yaml │ ├── flow.yaml │ ├── healthcheck.yaml │ ├── idp.yaml │ └── user.yaml ├── frontend ├── .editorconfig ├── .npmrc ├── .prettierignore ├── README.md ├── apps │ └── gate │ │ ├── .prettierignore │ │ ├── README.md │ │ ├── eslint.config.mjs │ │ ├── next.config.ts │ │ ├── package.json │ │ ├── prettier.config.mjs │ │ ├── public │ │ ├── favicon.ico │ │ └── images │ │ │ ├── login │ │ │ └── image-light.svg │ │ │ ├── logo-dark.svg │ │ │ └── logo-light.svg │ │ ├── scripts │ │ └── package.js │ │ ├── server.js │ │ ├── src │ │ ├── app │ │ │ ├── error │ │ │ │ └── page.tsx │ │ │ ├── layout.tsx │ │ │ ├── login │ │ │ │ ├── content.tsx │ │ │ │ └── page.tsx │ │ │ ├── not-found.tsx │ │ │ └── page.tsx │ │ ├── components │ │ │ └── Logo.tsx │ │ ├── configs │ │ │ └── app.json │ │ ├── globals.css │ │ ├── images │ │ │ ├── github-icon.tsx │ │ │ ├── google-icon.tsx │ │ │ └── layout-image.tsx │ │ └── layouts │ │ │ └── base.tsx │ │ └── tsconfig.json ├── nx.json ├── package.json ├── packages │ ├── oxygen-ui │ │ ├── README.md │ │ ├── package.json │ │ ├── scripts │ │ │ └── generate-exports.js │ │ ├── src │ │ │ ├── components │ │ │ │ ├── Alert │ │ │ │ │ └── Alert.tsx │ │ │ │ ├── AlertTitle │ │ │ │ │ └── AlertTitle.tsx │ │ │ │ ├── Box │ │ │ │ │ └── Box.tsx │ │ │ │ ├── Button │ │ │ │ │ └── Button.tsx │ │ │ │ ├── Checkbox │ │ │ │ │ └── Checkbox.tsx │ │ │ │ ├── CircularProgress │ │ │ │ │ └── CircularProgress.tsx │ │ │ │ ├── Divider │ │ │ │ │ └── Divider.tsx │ │ │ │ ├── FormControl │ │ │ │ │ └── FormControl.tsx │ │ │ │ ├── FormControlLabel │ │ │ │ │ └── FormControlLabel.tsx │ │ │ │ ├── FormLabel │ │ │ │ │ └── FormLabel.tsx │ │ │ │ ├── Grid │ │ │ │ │ └── Grid.tsx │ │ │ │ ├── Icon │ │ │ │ │ └── Icon.tsx │ │ │ │ ├── IconButton │ │ │ │ │ └── IconButton.tsx │ │ │ │ ├── InitColorSchemeScript │ │ │ │ │ └── InitColorSchemeScript.ts │ │ │ │ ├── Input │ │ │ │ │ └── Input.tsx │ │ │ │ ├── InputLabel │ │ │ │ │ └── InputLabel.tsx │ │ │ │ ├── Link │ │ │ │ │ └── Link.tsx │ │ │ │ ├── OutlinedInput │ │ │ │ │ └── OutlinedInput.tsx │ │ │ │ ├── Paper │ │ │ │ │ └── Paper.tsx │ │ │ │ ├── Stack │ │ │ │ │ └── Stack.tsx │ │ │ │ ├── TextField │ │ │ │ │ └── TextField.tsx │ │ │ │ ├── ThemeToggle │ │ │ │ │ └── ThemeToggle.tsx │ │ │ │ └── Typography │ │ │ │ │ └── Typography.tsx │ │ │ ├── contexts │ │ │ │ └── ThemeProvider.tsx │ │ │ ├── hooks │ │ │ │ ├── useColorScheme.ts │ │ │ │ ├── useMounted.ts │ │ │ │ └── useTheme.ts │ │ │ ├── index.ts │ │ │ ├── theme.ts │ │ │ └── theme │ │ │ │ └── components.ts │ │ └── tsconfig.json │ └── tsconfig.tsbuildinfo ├── pnpm-workspace.yaml ├── tsconfig.base.json └── workspace.json ├── samples ├── api │ └── postman │ │ ├── idp.json │ │ └── user.json └── apps │ └── oauth │ ├── .env.example │ ├── .gitignore │ ├── README.md │ ├── eslint.config.js │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── runtime.json │ └── vite.svg │ ├── server │ ├── package-lock.json │ ├── package.json │ ├── server.js │ ├── start.bat │ └── start.sh │ ├── src │ ├── App.css │ ├── App.tsx │ ├── assets │ │ └── react.svg │ ├── components │ │ ├── ConnectionErrorModal.tsx │ │ └── Layout.tsx │ ├── config.tsx │ ├── contexts │ │ ├── AuthContext.ts │ │ └── AuthProvider.tsx │ ├── hooks │ │ └── useAuth.ts │ ├── index.css │ ├── main.tsx │ ├── pages │ │ ├── ErrorPage.tsx │ │ ├── HomePage.tsx │ │ ├── LoginPage.tsx │ │ └── RedirectLoginPage.tsx │ ├── services │ │ ├── applicationsService.ts │ │ ├── authService.ts │ │ └── jwtService.ts │ ├── theme │ │ ├── ThemeProvider.tsx │ │ ├── ThemeToggle.tsx │ │ ├── theme.css │ │ └── theme.ts │ └── vite-env.d.ts │ ├── tsconfig.app.json │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── start.bat ├── start.sh ├── tests └── integration │ ├── application │ ├── applicationapi_test.go │ └── model.go │ ├── flowauthn │ ├── basicauth_test.go │ ├── githubauth_test.go │ ├── googleauth_test.go │ ├── model.go │ └── utils.go │ ├── go.mod │ ├── go.sum │ ├── healthcheck │ └── healthcheckapi_test.go │ ├── identity │ └── oauth2 │ │ └── token │ │ └── token_test.go │ ├── idp │ ├── idpapi_test.go │ └── model.go │ ├── main.go │ ├── resources │ ├── dbscripts │ │ ├── runtimedb │ │ │ └── sqlite.sql │ │ └── thunderdb │ │ │ └── sqlite.sql │ └── deployment.yaml │ ├── testutils │ └── testutils.go │ └── user │ ├── model.go │ └── userapi_test.go └── version.txt /.github/ISSUE_TEMPLATE/bug.yml: -------------------------------------------------------------------------------- 1 | name: "🐞 Report a Bug" 2 | description: Create an issue if something does not work as expected. 3 | labels: ["Type/Bug"] 4 | body: 5 | - type: textarea 6 | id: background 7 | attributes: 8 | label: Description 9 | description: Please share a clear and concise description of the problem. 10 | placeholder: Description 11 | - type: textarea 12 | id: steps 13 | attributes: 14 | label: Steps to Reproduce 15 | description: List the steps you followed when you encountered the issue. 16 | validations: 17 | required: true 18 | - type: input 19 | id: version 20 | attributes: 21 | label: Version 22 | description: Enter product version or commit. 23 | validations: 24 | required: true 25 | - type: textarea 26 | id: environment 27 | attributes: 28 | label: Environment Details (with versions) 29 | description: Mention the environment details (OS, Database, etc..) that the product is running on. 30 | validations: 31 | required: false 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/improvement.yml: -------------------------------------------------------------------------------- 1 | 2 | name: "🚀 Improvement Request" 3 | description: Suggest an improvement to the product. 4 | labels: ["Type/Improvement"] 5 | body: 6 | - type: textarea 7 | id: limitation 8 | attributes: 9 | label: Current Limitation 10 | description: Describe the current limitation. 11 | validations: 12 | required: true 13 | - type: textarea 14 | id: suggestion 15 | attributes: 16 | label: Suggested Improvement 17 | description: Describe the improvement you suggest. 18 | validations: 19 | required: true 20 | - type: input 21 | id: version 22 | attributes: 23 | label: Version 24 | description: Enter product version or commit. 25 | validations: 26 | required: false 27 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/new-feature.yml: -------------------------------------------------------------------------------- 1 | name: "💡 New Feature Request" 2 | description: Suggest new functionality and features for the product. 3 | labels: ["Type/NewFeature"] 4 | body: 5 | - type: textarea 6 | id: problem 7 | attributes: 8 | label: Problem 9 | description: What is the problem this feature will solve? 10 | validations: 11 | required: true 12 | - type: textarea 13 | id: solution 14 | attributes: 15 | label: Proposed Solution 16 | description: Describe the solution you'd like to have. 17 | validations: 18 | required: true 19 | - type: textarea 20 | id: alternatives 21 | attributes: 22 | label: Alternatives 23 | description: Describe any alternatives have you considered 24 | validations: 25 | required: false 26 | - type: input 27 | id: version 28 | attributes: 29 | label: Version 30 | description: Enter product version or commit. 31 | validations: 32 | required: false 33 | -------------------------------------------------------------------------------- /.github/actions/setup-go/action.yml: -------------------------------------------------------------------------------- 1 | name: Setup Go 2 | description: Sets up Go environment 3 | runs: 4 | using: "composite" 5 | steps: 6 | - uses: actions/setup-go@v5 7 | with: 8 | go-version-file: backend/go.mod 9 | -------------------------------------------------------------------------------- /.github/workflows/pr-builder.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build the project on pull requests with tests 2 | # Uses: 3 | # OS: ubuntu-latest 4 | # Go: go 1.x 5 | 6 | name: 👷🛠️ PR Builder 7 | 8 | on: 9 | pull_request: 10 | branches: [main] 11 | workflow_dispatch: 12 | 13 | env: 14 | GOFLAGS: "-mod=readonly" 15 | 16 | jobs: 17 | lint: 18 | name: 🧹 Lint Code 19 | if: ${{ github.event_name == 'pull_request' }} 20 | runs-on: ubuntu-latest 21 | steps: 22 | - name: 📥 Checkout Code 23 | uses: actions/checkout@v4 24 | 25 | - name: ⚙️ Set up Go Environment 26 | uses: ./.github/actions/setup-go 27 | 28 | - name: 📦 Prepare golangci-lint Locally 29 | run: make golangci-lint 30 | 31 | - name: 🔍 Run Linter 32 | run: make lint 33 | 34 | build: 35 | name: 🛠️ Build and Test 36 | if: ${{ github.event.label.name == 'trigger-pr-builder' || github.event_name == 'workflow_dispatch' || github.event_name == 'pull_request' }} 37 | runs-on: ubuntu-latest 38 | steps: 39 | - name: 📥 Checkout Code 40 | uses: actions/checkout@v4 41 | 42 | - name: ⚙️ Set up Go Environment 43 | uses: ./.github/actions/setup-go 44 | 45 | - name: 🗄️ Cache Go Modules 46 | uses: actions/cache@v4 47 | id: cache-go-modules 48 | with: 49 | path: | 50 | ~/.cache/go-build 51 | ~/go/pkg/mod 52 | key: ${{ runner.os }}-go-modules-${{ hashFiles('**/go.sum') }} 53 | restore-keys: | 54 | ${{ runner.os }}-go-modules- 55 | 56 | - name: 📦 Install Dependencies 57 | run: | 58 | cd backend 59 | go mod download 60 | cd ../tests/integration 61 | go mod download 62 | 63 | - name: 🧹 Clean Previous Builds 64 | run: | 65 | set -e 66 | make clean_all 67 | 68 | - name: 🔨 Build and Run Tests 69 | run: | 70 | set -e 71 | make all OS=$(go env GOOS) ARCH=$(go env GOARCH) 72 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | *.db 8 | */**/executables/* 9 | 10 | # Test binary, built with `go test -c` 11 | *.test 12 | 13 | # Output of the go coverage tool, specifically when used with LiteIDE 14 | *.out 15 | 16 | # Dependency directories 17 | node_modules 18 | .pnp 19 | .pnp.* 20 | .yarn/* 21 | !.yarn/patches 22 | !.yarn/plugins 23 | !.yarn/releases 24 | !.yarn/versions 25 | 26 | # Go workspace file 27 | go.work 28 | go.work.sum 29 | 30 | # OS generated files 31 | .DS_Store 32 | Thumbs.db 33 | 34 | # Server certificates. 35 | *.pem 36 | *.key 37 | *.crt 38 | *.cert 39 | 40 | # IDE settings, swap files, and temporary artifacts 41 | .idea 42 | *.swp 43 | *.swo 44 | *~ 45 | *.tgz 46 | .project 47 | .classpath 48 | .c9/ 49 | *.launch 50 | .settings/ 51 | *.sublime-workspace 52 | 53 | # IDE - VSCode 54 | .vscode/* 55 | !.vscode/settings.json 56 | !.vscode/tasks.json 57 | !.vscode/launch.json 58 | !.vscode/extensions.json 59 | 60 | # Misc 61 | .sass-cache 62 | /connect.lock 63 | /coverage 64 | /libpeerconnection.log 65 | npm-debug.log 66 | yarn-error.log 67 | testem.log 68 | /typings 69 | 70 | # debug 71 | npm-debug.log* 72 | yarn-debug.log* 73 | yarn-error.log* 74 | .pnpm-debug.log* 75 | 76 | # NX artifacts 77 | frontend/.nx/cache 78 | frontend/.nx/workspace-data 79 | 80 | # typescript 81 | *.tsbuildinfo 82 | next-env.d.ts 83 | 84 | # next.js artifacts 85 | .next 86 | 87 | # env files (can opt-in for committing if needed) 88 | .env* 89 | !.env.example 90 | 91 | # Project compiled output folders 92 | build 93 | target 94 | dist 95 | tmp 96 | out 97 | out-tsc 98 | backend/bin 99 | frontend/packages/*/modules 100 | samples/apps/*/server/app 101 | 102 | # IDE settings 103 | settings.json 104 | .cursor/rules/nx-rules.mdc 105 | .github/instructions/nx.instructions.md 106 | -------------------------------------------------------------------------------- /backend/.golangci.yml: -------------------------------------------------------------------------------- 1 | run: 2 | timeout: 5m 3 | allow-parallel-runners: true 4 | 5 | linters: 6 | disable-all: true 7 | enable: 8 | - dupl 9 | - errcheck 10 | - errorlint 11 | - goconst 12 | - gocritic 13 | - gocyclo 14 | - gofmt 15 | - goimports 16 | - goprintffuncname 17 | - gosec 18 | - gosimple 19 | - govet 20 | - ineffassign 21 | - lll 22 | - misspell 23 | - nakedret 24 | - prealloc 25 | - revive 26 | - staticcheck 27 | - typecheck 28 | - unconvert 29 | - unparam 30 | - unused 31 | - whitespace 32 | 33 | linters-settings: 34 | errcheck: 35 | check-blank: false 36 | check-type-assertions: false 37 | gci: 38 | sections: 39 | - standard 40 | - default 41 | - prefix(github.com/asgardeo/thunder) 42 | govet: 43 | enable-all: true 44 | disable: 45 | - fieldalignment 46 | - shadow 47 | gocritic: 48 | disabled-checks: 49 | - exitAfterDefer 50 | - ifElseChain 51 | - elseif 52 | enabled-tags: 53 | - diagnostic 54 | goimports: 55 | local-prefixes: github.com/asgardeo/thunder 56 | misspell: 57 | locale: US 58 | ignore-words: 59 | - cancelled 60 | lll: 61 | line-length: 120 62 | revive: 63 | rules: 64 | - name: struct-tag 65 | arguments: [ "json,inline" ] 66 | - name: var-naming 67 | - name: redundant-import-alias 68 | - name: comment-spacings 69 | - name: exported 70 | arguments: 71 | - disableStutteringCheck 72 | - name: package-comments 73 | 74 | issues: 75 | max-same-issues: 0 76 | max-issues-per-linter: 0 77 | exclude-use-default: false 78 | 79 | output: 80 | show-stats: true 81 | -------------------------------------------------------------------------------- /backend/README.md: -------------------------------------------------------------------------------- 1 | # Project Thunder Backend 2 | -------------------------------------------------------------------------------- /backend/cmd/server/repository/conf/deployment.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | hostname: "localhost" 3 | port: 8090 4 | 5 | gate_client: 6 | hostname: "localhost" 7 | port: 9090 8 | 9 | security: 10 | cert_file: "repository/resources/security/server.cert" 11 | key_file: "repository/resources/security/server.key" 12 | 13 | database: 14 | identity: 15 | type: "sqlite" 16 | path: "repository/database/thunderdb.db" 17 | options: "_journal_mode=WAL&_busy_timeout=5000" 18 | runtime: 19 | type: "sqlite" 20 | path: "repository/database/runtimedb.db" 21 | options: "_journal_mode=WAL&_busy_timeout=5000" 22 | 23 | oauth: 24 | jwt: 25 | issuer: "thunder" 26 | validity_period: 3600 27 | 28 | authenticator: 29 | default: "BasicAuthenticator" 30 | authenticators: 31 | - name: "BasicAuthenticator" 32 | type: "local" 33 | display_name: "Username & Password" 34 | description: "Login with username and password" 35 | 36 | flow: 37 | graph_directory: "repository/resources/graphs/" 38 | authn: 39 | default_flow: "auth_flow_config_basic" 40 | 41 | # provider: 42 | # message: 43 | # default_provider: "twilio" 44 | # providers: 45 | # - name: "twilio" 46 | # provider: "twilio" 47 | # display_name: "Twilio Message Provider" 48 | # description: "Send messages using Twilio" 49 | # properties: 50 | # account_sid: "" 51 | # auth_token: "" 52 | # sender_id: "" 53 | # - name: "vonage" 54 | # provider: "vonage" 55 | # display_name: "Vonage Message Provider" 56 | # description: "Send messages using Vonage" 57 | # properties: 58 | # api_key: "" 59 | # api_secret: "" 60 | # sender_id: "" 61 | # - name: "custom" 62 | # provider: "custom" 63 | # display_name: "Custom Message Provider" 64 | # description: "Send messages using a custom provider" 65 | # properties: 66 | # url: "" 67 | # http_method: "POST" 68 | # http_headers: "" 69 | # content_type: "JSON" 70 | # payload_template: "" 71 | -------------------------------------------------------------------------------- /backend/cmd/server/repository/resources/graphs/auth_flow_config_basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "auth_flow_config_basic", 3 | "type": "AUTHENTICATION", 4 | "nodes": [ 5 | { 6 | "id": "basic_auth", 7 | "type": "TASK_EXECUTION", 8 | "inputData": [ 9 | { 10 | "name": "username", 11 | "type": "string", 12 | "required": true 13 | }, 14 | { 15 | "name": "password", 16 | "type": "string", 17 | "required": true 18 | }, 19 | { 20 | "name": "firstName", 21 | "type": "string", 22 | "required": false 23 | } 24 | ], 25 | "executor": { 26 | "name": "BasicAuthExecutor" 27 | }, 28 | "next": [ 29 | "authenticated" 30 | ] 31 | }, 32 | { 33 | "id": "authenticated", 34 | "type": "AUTHENTICATION_SUCCESS" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /backend/cmd/server/repository/resources/graphs/auth_flow_config_basic_google.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "auth_flow_config_basic_google", 3 | "type": "AUTHENTICATION", 4 | "nodes": [ 5 | { 6 | "id": "choose_auth", 7 | "type": "DECISION", 8 | "next": [ 9 | "basic_auth", 10 | "google_auth" 11 | ] 12 | }, 13 | { 14 | "id": "basic_auth", 15 | "type": "TASK_EXECUTION", 16 | "inputData": [ 17 | { 18 | "name": "username", 19 | "type": "string", 20 | "required": true 21 | }, 22 | { 23 | "name": "password", 24 | "type": "string", 25 | "required": true 26 | } 27 | ], 28 | "executor": { 29 | "name": "BasicAuthExecutor" 30 | }, 31 | "next": [ 32 | "authenticated" 33 | ] 34 | }, 35 | { 36 | "id": "google_auth", 37 | "type": "TASK_EXECUTION", 38 | "inputData": [ 39 | { 40 | "name": "code", 41 | "type": "string", 42 | "required": true 43 | }, 44 | { 45 | "name": "nonce", 46 | "type": "string", 47 | "required": false 48 | } 49 | ], 50 | "executor": { 51 | "name": "GoogleOIDCAuthExecutor", 52 | "idpName": "Google" 53 | }, 54 | "next": [ 55 | "authenticated" 56 | ] 57 | }, 58 | { 59 | "id": "authenticated", 60 | "type": "AUTHENTICATION_SUCCESS" 61 | } 62 | ] 63 | } 64 | -------------------------------------------------------------------------------- /backend/cmd/server/repository/resources/graphs/auth_flow_config_basic_with_prompt.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "auth_flow_config_basic_with_prompt", 3 | "type": "AUTHENTICATION", 4 | "nodes": [ 5 | { 6 | "id": "prompt_username", 7 | "type": "PROMPT_ONLY", 8 | "inputData": [ 9 | { 10 | "name": "username", 11 | "type": "string", 12 | "required": true 13 | } 14 | ], 15 | "next": [ 16 | "basic_auth" 17 | ] 18 | }, 19 | { 20 | "id": "basic_auth", 21 | "type": "TASK_EXECUTION", 22 | "inputData": [ 23 | { 24 | "name": "password", 25 | "type": "string", 26 | "required": true 27 | } 28 | ], 29 | "executor": { 30 | "name": "BasicAuthExecutor" 31 | }, 32 | "next": [ 33 | "authenticated" 34 | ] 35 | }, 36 | { 37 | "id": "authenticated", 38 | "type": "AUTHENTICATION_SUCCESS" 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /backend/cmd/server/repository/resources/graphs/auth_flow_config_github.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "auth_flow_config_github", 3 | "type": "AUTHENTICATION", 4 | "nodes": [ 5 | { 6 | "id": "github_auth", 7 | "type": "TASK_EXECUTION", 8 | "inputData": [ 9 | { 10 | "name": "code", 11 | "type": "string", 12 | "required": true 13 | } 14 | ], 15 | "executor": { 16 | "name": "GithubOAuthExecutor", 17 | "idpName": "Github" 18 | }, 19 | "next": [ 20 | "authenticated" 21 | ] 22 | }, 23 | { 24 | "id": "authenticated", 25 | "type": "AUTHENTICATION_SUCCESS" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /backend/cmd/server/repository/resources/graphs/auth_flow_config_google.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "auth_flow_config_google", 3 | "type": "AUTHENTICATION", 4 | "nodes": [ 5 | { 6 | "id": "google_auth", 7 | "type": "TASK_EXECUTION", 8 | "inputData": [ 9 | { 10 | "name": "code", 11 | "type": "string", 12 | "required": true 13 | }, 14 | { 15 | "name": "nonce", 16 | "type": "string", 17 | "required": false 18 | } 19 | ], 20 | "executor": { 21 | "name": "GoogleOIDCAuthExecutor", 22 | "idpName": "Google" 23 | }, 24 | "next": [ 25 | "authenticated" 26 | ] 27 | }, 28 | { 29 | "id": "authenticated", 30 | "type": "AUTHENTICATION_SUCCESS" 31 | } 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /backend/dbscripts/runtimedb/postgress.sql: -------------------------------------------------------------------------------- 1 | -- Table to store OAuth2 authorization codes. 2 | CREATE TABLE IDN_OAUTH2_AUTHZ_CODE ( 3 | ID INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, 4 | CODE_ID VARCHAR(36) UNIQUE NOT NULL, 5 | AUTHORIZATION_CODE VARCHAR(500) NOT NULL, 6 | CONSUMER_KEY VARCHAR(255) NOT NULL, 7 | CALLBACK_URL VARCHAR(500), 8 | AUTHZ_USER VARCHAR(255) NOT NULL, 9 | TIME_CREATED TIMESTAMP NOT NULL, 10 | EXPIRY_TIME TIMESTAMP NOT NULL, 11 | STATE VARCHAR(50) NOT NULL 12 | ); 13 | 14 | -- Table to store scopes associated with OAuth2 authorization codes. 15 | CREATE TABLE IDN_OAUTH2_AUTHZ_CODE_SCOPE ( 16 | ID INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, 17 | CODE_ID VARCHAR(36) NOT NULL REFERENCES IDN_OAUTH2_AUTHZ_CODE(CODE_ID) ON DELETE CASCADE, 18 | SCOPE VARCHAR(255) NOT NULL, 19 | UNIQUE (CODE_ID, SCOPE) 20 | ); 21 | -------------------------------------------------------------------------------- /backend/dbscripts/runtimedb/sqlite.sql: -------------------------------------------------------------------------------- 1 | -- Table to store OAuth2 authorization codes. 2 | CREATE TABLE IDN_OAUTH2_AUTHZ_CODE ( 3 | ID INTEGER PRIMARY KEY AUTOINCREMENT, 4 | CODE_ID VARCHAR(36) UNIQUE NOT NULL, 5 | AUTHORIZATION_CODE VARCHAR(500) NOT NULL, 6 | CONSUMER_KEY VARCHAR(255) NOT NULL, 7 | CALLBACK_URL VARCHAR(500), 8 | AUTHZ_USER VARCHAR(255) NOT NULL, 9 | TIME_CREATED DATETIME NOT NULL, 10 | EXPIRY_TIME DATETIME NOT NULL, 11 | STATE VARCHAR(50) NOT NULL 12 | ); 13 | 14 | -- Table to store scopes associated with OAuth2 authorization codes. 15 | CREATE TABLE IDN_OAUTH2_AUTHZ_CODE_SCOPE ( 16 | ID INTEGER PRIMARY KEY AUTOINCREMENT, 17 | CODE_ID VARCHAR(36) NOT NULL REFERENCES IDN_OAUTH2_AUTHZ_CODE(CODE_ID) ON DELETE CASCADE, 18 | SCOPE VARCHAR(255) NOT NULL, 19 | UNIQUE (CODE_ID, SCOPE) 20 | ); 21 | -------------------------------------------------------------------------------- /backend/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/asgardeo/thunder 2 | 3 | go 1.24.2 4 | 5 | require ( 6 | github.com/lib/pq v1.10.9 7 | gopkg.in/yaml.v3 v3.0.1 8 | modernc.org/sqlite v1.37.0 9 | ) 10 | 11 | require ( 12 | github.com/dustin/go-humanize v1.0.1 // indirect 13 | github.com/google/uuid v1.6.0 // indirect 14 | github.com/mattn/go-isatty v0.0.20 // indirect 15 | github.com/ncruces/go-strftime v0.1.9 // indirect 16 | github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect 17 | golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 // indirect 18 | golang.org/x/sys v0.33.0 // indirect 19 | modernc.org/libc v1.65.2 // indirect 20 | modernc.org/mathutil v1.7.1 // indirect 21 | modernc.org/memory v1.10.0 // indirect 22 | ) 23 | -------------------------------------------------------------------------------- /backend/internal/application/model/application.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package model defines the data structures for the application module. 20 | package model 21 | 22 | // Application represents an application with its details. 23 | type Application struct { 24 | ID string `json:"id,omitempty"` 25 | Name string `json:"name"` 26 | Description string `json:"description"` 27 | ClientID string `json:"client_id"` 28 | ClientSecret string `json:"client_secret"` 29 | CallbackURLs []string `json:"callback_url"` 30 | SupportedGrantTypes []string `json:"supported_grant_types"` 31 | AuthFlowGraphID string `json:"auth_flow_graph_id,omitempty"` 32 | } 33 | -------------------------------------------------------------------------------- /backend/internal/application/provider/applicationprovider.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package provider provides functionality for managing application service instances. 20 | package provider 21 | 22 | import ( 23 | "github.com/asgardeo/thunder/internal/application/service" 24 | ) 25 | 26 | // ApplicationProviderInterface defines the interface for the application provider. 27 | type ApplicationProviderInterface interface { 28 | GetApplicationService() service.ApplicationServiceInterface 29 | } 30 | 31 | // ApplicationProvider is the default implementation of the ApplicationProviderInterface. 32 | type ApplicationProvider struct{} 33 | 34 | // NewApplicationProvider creates a new instance of ApplicationProvider. 35 | func NewApplicationProvider() ApplicationProviderInterface { 36 | return &ApplicationProvider{} 37 | } 38 | 39 | // GetApplicationService returns the application service instance. 40 | func (ap *ApplicationProvider) GetApplicationService() service.ApplicationServiceInterface { 41 | return service.GetApplicationService() 42 | } 43 | -------------------------------------------------------------------------------- /backend/internal/authn/model/model.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package model defines the data structures for authentication flow. 20 | package model 21 | 22 | import ( 23 | "context" 24 | "time" 25 | ) 26 | 27 | // AuthenticatedUser represents the user information of an authenticated user. 28 | type AuthenticatedUser struct { 29 | IsAuthenticated bool 30 | UserID string 31 | Username string 32 | Domain string 33 | AuthenticatedSubjectID string 34 | Attributes map[string]string 35 | } 36 | 37 | // AuthenticationContext represents the context of an authentication session. 38 | type AuthenticationContext struct { 39 | context.Context 40 | SessionDataKey string 41 | RequestQueryParams map[string]string 42 | AuthenticatedUser AuthenticatedUser 43 | AuthTime time.Time 44 | } 45 | -------------------------------------------------------------------------------- /backend/internal/executor/githubauth/constants.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package githubauth 20 | 21 | // Constants used for GitHub OAuth2 authentication and API endpoints. 22 | const ( 23 | githubAuthorizeEndpoint = "https://github.com/login/oauth/authorize" 24 | githubTokenEndpoint = "https://github.com/login/oauth/access_token" // #nosec G101 25 | githubUserInfoEndpoint = "https://api.github.com/user" 26 | githubUserEmailEndpoint = "https://api.github.com/user/emails" 27 | userScope = "user" 28 | userEmailScope = "user:email" 29 | ) 30 | -------------------------------------------------------------------------------- /backend/internal/executor/googleauth/constants.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package googleauth 20 | 21 | // Constants used for Google OAuth2 authentication and API endpoints. 22 | const ( 23 | googleAuthorizeEndpoint = "https://accounts.google.com/o/oauth2/v2/auth" 24 | googleTokenEndpoint = "https://oauth2.googleapis.com/token" // #nosec G101 25 | googleUserInfoEndpoint = "https://openidconnect.googleapis.com/v1/userinfo" 26 | googleJwksEndpoint = "https://www.googleapis.com/oauth2/v3/certs" 27 | ) 28 | 29 | // idTokenNonUserAttributes contains the list of non-user attributes that are expected in the ID token. 30 | var idTokenNonUserAttributes = []string{"aud", "exp", "iat", "iss", "at_hash", "azp", "nonce"} 31 | -------------------------------------------------------------------------------- /backend/internal/executor/oidcauth/constants.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package oidcauth 20 | 21 | // idTokenNonUserAttributes contains the list of non-user attributes that are expected in the ID token. 22 | var idTokenNonUserAttributes = []string{"aud", "exp", "iat", "iss", "at_hash", "azp"} 23 | -------------------------------------------------------------------------------- /backend/internal/executor/oidcauth/model/model.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package model provides the data structures for OIDC authentication properties and responses. 20 | package model 21 | 22 | // OIDCTokenResponse represents the response from the OIDC token endpoint. 23 | type OIDCTokenResponse struct { 24 | AccessToken string `json:"access_token"` 25 | TokenType string `json:"token_type"` 26 | Scope string `json:"scope"` 27 | RefreshToken string `json:"refresh_token"` 28 | IDToken string `json:"id_token"` 29 | ExpiresIn int `json:"expires_in"` 30 | } 31 | -------------------------------------------------------------------------------- /backend/internal/flow/graphservice/graphservice.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package graphservice provides the graph service implementation. 20 | package graphservice 21 | 22 | import ( 23 | "sync" 24 | 25 | "github.com/asgardeo/thunder/internal/flow/dao" 26 | ) 27 | 28 | var ( 29 | instance *GraphService 30 | once sync.Once 31 | ) 32 | 33 | // GraphServiceInterface defines the interface for the graph service. 34 | type GraphServiceInterface interface { 35 | IsValidGraphID(graphID string) bool 36 | } 37 | 38 | // GraphService is the implementation of GraphServiceInterface. 39 | type GraphService struct{} 40 | 41 | // GetGraphService returns a singleton instance of GraphServiceInterface. 42 | func GetGraphService() GraphServiceInterface { 43 | once.Do(func() { 44 | instance = &GraphService{} 45 | }) 46 | return instance 47 | } 48 | 49 | // IsValidGraphID checks if the provided graph ID is valid. 50 | func (s *GraphService) IsValidGraphID(graphID string) bool { 51 | flowDAO := dao.GetFlowDAO() 52 | return flowDAO.IsValidGraphID(graphID) 53 | } 54 | -------------------------------------------------------------------------------- /backend/internal/flow/jsonmodel/model.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package jsonmodel provides the structure for representing a graph definition in JSON format. 20 | package jsonmodel 21 | 22 | // GraphDefinition represents the direct graph structure from JSON 23 | type GraphDefinition struct { 24 | ID string `json:"id"` 25 | Type string `json:"type"` 26 | Nodes []NodeDefinition `json:"nodes"` 27 | } 28 | 29 | // NodeDefinition represents a node in the graph definition 30 | type NodeDefinition struct { 31 | ID string `json:"id"` 32 | Type string `json:"type"` 33 | InputData []InputDefinition `json:"inputData"` 34 | Executor ExecutorDefinition `json:"executor"` 35 | Next []string `json:"next,omitempty"` 36 | } 37 | 38 | // InputDefinition represents an input parameter for a node 39 | type InputDefinition struct { 40 | Name string `json:"name"` 41 | Type string `json:"type"` 42 | Required bool `json:"required"` 43 | } 44 | 45 | // ExecutorDefinition represents the executor configuration for a node 46 | type ExecutorDefinition struct { 47 | Name string `json:"name"` 48 | IdpName string `json:"idpName,omitempty"` 49 | } 50 | -------------------------------------------------------------------------------- /backend/internal/idp/model/idp.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package model defines the data structures and interfaces for IdP management. 20 | package model 21 | 22 | import ( 23 | "errors" 24 | ) 25 | 26 | // IDP represents an identity provider in the system. 27 | type IDP struct { 28 | ID string `json:"id"` 29 | Name string `json:"name"` // Display name 30 | Description string `json:"description,omitempty"` // Description shown in UI 31 | ClientID string `json:"client_id"` // OAuth client ID 32 | ClientSecret string `json:"client_secret,omitempty"` // OAuth client secret 33 | RedirectURI string `json:"redirect_uri,omitempty"` // OAuth redirect URI 34 | Scopes []string `json:"scopes,omitempty"` // OAuth scopes 35 | } 36 | 37 | // ErrIDPNotFound is returned when the IdP is not found in the system. 38 | var ErrIDPNotFound = errors.New("IdP not found") 39 | 40 | // ErrBadScopesInRequest is returned when the scopes in the request are invalid. 41 | var ErrBadScopesInRequest = errors.New("failed to marshal scopes") 42 | -------------------------------------------------------------------------------- /backend/internal/idp/provider/idpprovider.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package provider provides the implementation for IdP management operations. 20 | package provider 21 | 22 | import ( 23 | "github.com/asgardeo/thunder/internal/idp/service" 24 | ) 25 | 26 | // IDPProviderInterface defines the interface for the IdP provider. 27 | type IDPProviderInterface interface { 28 | GetIDPService() service.IDPServiceInterface 29 | } 30 | 31 | // IDPProvider is the default implementation of the IdPProviderInterface. 32 | type IDPProvider struct{} 33 | 34 | // NewIDPProvider creates a new instance of IdPProvider. 35 | func NewIDPProvider() IDPProviderInterface { 36 | return &IDPProvider{} 37 | } 38 | 39 | // GetIDPService returns the IdP service instance. 40 | func (ap *IDPProvider) GetIDPService() service.IDPServiceInterface { 41 | return service.GetIDPService() 42 | } 43 | -------------------------------------------------------------------------------- /backend/internal/notification/message/client/client.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package client defines the interface for sending messages and related implementations. 20 | package client 21 | 22 | import ( 23 | "github.com/asgardeo/thunder/internal/notification/message/model" 24 | ) 25 | 26 | // MessageClientInterface defines the interface for clients sending messages. 27 | type MessageClientInterface interface { 28 | GetName() string 29 | SendSMS(sms model.SMSData) error 30 | validate(senderDTO model.MessageSenderDTO) error 31 | } 32 | -------------------------------------------------------------------------------- /backend/internal/notification/message/model/model.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package model defines the data structures used for message notifications. 20 | package model 21 | 22 | import "github.com/asgardeo/thunder/internal/notification/message/constants" 23 | 24 | // SMSData represents the data structure for a SMS message. 25 | type SMSData struct { 26 | To string `json:"to"` 27 | Body string `json:"body"` 28 | } 29 | 30 | // MessageSenderDTO represents the data object for a message sender configuration. 31 | type MessageSenderDTO struct { 32 | Name string `json:"name"` 33 | Provider constants.MessageProviderType `json:"provider"` 34 | DisplayName string `json:"display_name"` 35 | Description string `json:"description"` 36 | Properties map[string]string `json:"properties"` 37 | } 38 | -------------------------------------------------------------------------------- /backend/internal/oauth/oauth2/authz/constants/constants.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package constants defines constants related to OAuth2 authorization. 20 | package constants 21 | 22 | // Authorization code states. 23 | const ( 24 | AuthCodeStateActive = "ACTIVE" 25 | AuthCodeStateInactive = "INACTIVE" 26 | AuthCodeStateExpired = "EXPIRED" 27 | AuthCodeStateRevoked = "REVOKED" 28 | ) 29 | -------------------------------------------------------------------------------- /backend/internal/oauth/oauth2/authz/constants/dbconstants.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package constants 20 | 21 | import dbmodel "github.com/asgardeo/thunder/internal/system/database/model" 22 | 23 | // QueryInsertAuthorizationCode is the query to insert a new authorization code into the database. 24 | var QueryInsertAuthorizationCode = dbmodel.DBQuery{ 25 | ID: "AZQ-00001", 26 | Query: "INSERT INTO IDN_OAUTH2_AUTHZ_CODE (CODE_ID, AUTHORIZATION_CODE, CONSUMER_KEY, " + 27 | "CALLBACK_URL, AUTHZ_USER, TIME_CREATED, EXPIRY_TIME, STATE)" + 28 | "VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", 29 | } 30 | 31 | // QueryInsertAuthorizationCodeScopes is the query to insert scopes for an authorization code. 32 | var QueryInsertAuthorizationCodeScopes = dbmodel.DBQuery{ 33 | ID: "AZQ-00002", 34 | Query: "INSERT INTO IDN_OAUTH2_AUTHZ_CODE_SCOPE (CODE_ID, SCOPE) VALUES ($1, $2)", 35 | } 36 | 37 | // QueryGetAuthorizationCode is the query to retrieve an authorization code by client ID and code. 38 | var QueryGetAuthorizationCode = dbmodel.DBQuery{ 39 | ID: "AZQ-00003", 40 | Query: "SELECT CODE_ID, AUTHORIZATION_CODE, CALLBACK_URL, AUTHZ_USER, TIME_CREATED, " + 41 | "EXPIRY_TIME, STATE FROM IDN_OAUTH2_AUTHZ_CODE WHERE " + 42 | "CONSUMER_KEY = $1 AND AUTHORIZATION_CODE = $2", 43 | } 44 | 45 | // QueryUpdateAuthorizationCodeState is the query to update the state of an authorization code. 46 | var QueryUpdateAuthorizationCodeState = dbmodel.DBQuery{ 47 | ID: "AZQ-00004", 48 | Query: "UPDATE IDN_OAUTH2_AUTHZ_CODE SET STATE = $1 WHERE CODE_ID = $2", 49 | } 50 | -------------------------------------------------------------------------------- /backend/internal/oauth/oauth2/authz/model/model.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package model defines the data structures for OAuth2 authorization. 20 | package model 21 | 22 | import ( 23 | "time" 24 | 25 | sessionmodel "github.com/asgardeo/thunder/internal/oauth/session/model" 26 | ) 27 | 28 | // OAuthMessage represents the OAuth message. 29 | type OAuthMessage struct { 30 | RequestType string 31 | SessionData *sessionmodel.SessionData 32 | RequestHeaders map[string][]string 33 | RequestQueryParams map[string]string 34 | RequestBodyParams map[string]string 35 | } 36 | 37 | // AuthorizationCode represents the authorization code. 38 | type AuthorizationCode struct { 39 | CodeID string 40 | Code string 41 | ClientID string 42 | RedirectURI string 43 | AuthorizedUserID string 44 | TimeCreated time.Time 45 | ExpiryTime time.Time 46 | Scopes string 47 | State string 48 | } 49 | -------------------------------------------------------------------------------- /backend/internal/oauth/oauth2/granthandlers/granthandler.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package granthandlers provides an interface and implementations for handling OAuth 2.0 grant types. 20 | package granthandlers 21 | 22 | import ( 23 | appmodel "github.com/asgardeo/thunder/internal/application/model" 24 | "github.com/asgardeo/thunder/internal/oauth/oauth2/model" 25 | ) 26 | 27 | // GrantHandler defines the interface for handling OAuth 2.0 grants. 28 | type GrantHandler interface { 29 | ValidateGrant(tokenRequest *model.TokenRequest) *model.ErrorResponse 30 | HandleGrant(tokenRequest *model.TokenRequest, 31 | oauthApp *appmodel.OAuthApplication) (*model.TokenResponse, *model.ErrorResponse) 32 | } 33 | -------------------------------------------------------------------------------- /backend/internal/oauth/oauth2/model/error.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package model 20 | 21 | // ErrorResponse represents the OAuth2 error response. 22 | type ErrorResponse struct { 23 | Error string `json:"error"` 24 | ErrorDescription string `json:"error_description,omitempty"` 25 | ErrorURI string `json:"error_uri,omitempty"` 26 | } 27 | -------------------------------------------------------------------------------- /backend/internal/oauth/oauth2/model/parameter.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package model 20 | 21 | // OAuthParameters represents the parameters required for OAuth2 authorization. 22 | type OAuthParameters struct { 23 | SessionDataKey string 24 | State string 25 | ClientID string 26 | RedirectURI string 27 | ResponseType string 28 | Scopes string 29 | } 30 | -------------------------------------------------------------------------------- /backend/internal/oauth/oauth2/model/token.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package model defines the data structures used in the OAuth2 module. 20 | package model 21 | 22 | // TokenRequest represents the OAuth2 token request. 23 | type TokenRequest struct { 24 | GrantType string `json:"grant_type"` 25 | ClientID string `json:"client_id"` 26 | ClientSecret string `json:"client_secret"` 27 | Scope string `json:"scope,omitempty"` 28 | Username string `json:"username,omitempty"` 29 | Password string `json:"password,omitempty"` 30 | RefreshToken string `json:"refresh_token,omitempty"` 31 | CodeVerifier string `json:"code_verifier,omitempty"` 32 | Code string `json:"code,omitempty"` 33 | RedirectURI string `json:"redirect_uri,omitempty"` 34 | } 35 | 36 | // TokenResponse represents the OAuth2 token response. 37 | type TokenResponse struct { 38 | AccessToken string `json:"access_token"` 39 | TokenType string `json:"token_type"` 40 | ExpiresIn int `json:"expires_in"` 41 | RefreshToken string `json:"refresh_token,omitempty"` 42 | Scope string `json:"scope,omitempty"` 43 | } 44 | -------------------------------------------------------------------------------- /backend/internal/oauth/scope/constants/dbconstants.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package constants defines constants related to OAuth scopes. 20 | package constants 21 | 22 | import dbmodel "github.com/asgardeo/thunder/internal/system/database/model" 23 | 24 | // QueryGetAuthorizedScopesByClientID is the query to retrieve authorized scopes by client ID. 25 | var QueryGetAuthorizedScopesByClientID = dbmodel.DBQuery{ 26 | ID: "SCQ-00001", 27 | Query: "SELECT s.NAME FROM AUTHORIZED_SCOPE as ascope JOIN SCOPE as s ON ascope.SCOPE_ID = s.UUID " + 28 | "JOIN IDN_OAUTH_CONSUMER_APPS as apps ON ascope.APP_ID = apps.APP_ID WHERE apps.CONSUMER_KEY = $1", 29 | } 30 | -------------------------------------------------------------------------------- /backend/internal/oauth/scope/provider/validatorprovider.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package provider provides functionality for managing scope validator instances. 20 | package provider 21 | 22 | import "github.com/asgardeo/thunder/internal/oauth/scope/validator" 23 | 24 | // ScopeValidatorProviderInterface defines the interface for providing a scope validator. 25 | type ScopeValidatorProviderInterface interface { 26 | GetScopeValidator() validator.ScopeValidatorInterface 27 | } 28 | 29 | // ScopeValidatorProvider is the default implementation of the ScopeValidatorProviderInterface. 30 | type ScopeValidatorProvider struct{} 31 | 32 | // NewScopeValidatorProvider creates a new instance of ScopeValidatorProvider. 33 | func NewScopeValidatorProvider() ScopeValidatorProviderInterface { 34 | return &ScopeValidatorProvider{} 35 | } 36 | 37 | // GetScopeValidator returns the scope validator instance. 38 | func (svp *ScopeValidatorProvider) GetScopeValidator() validator.ScopeValidatorInterface { 39 | return validator.NewAPIScopeValidator() 40 | } 41 | -------------------------------------------------------------------------------- /backend/internal/oauth/session/model/sessiondata.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package model defines the data structures for managing auth session data. 20 | package model 21 | 22 | import ( 23 | "time" 24 | 25 | authnmodel "github.com/asgardeo/thunder/internal/authn/model" 26 | oauthmodel "github.com/asgardeo/thunder/internal/oauth/oauth2/model" 27 | ) 28 | 29 | // SessionData represents the session data for the authentication. 30 | type SessionData struct { 31 | OAuthParameters oauthmodel.OAuthParameters 32 | AuthTime time.Time 33 | CurrentAuthenticator string 34 | AuthenticatedUser authnmodel.AuthenticatedUser 35 | } 36 | -------------------------------------------------------------------------------- /backend/internal/oauth/session/utils/sessionutils.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package utils provides utility functions for session management. 20 | package utils 21 | 22 | import "github.com/asgardeo/thunder/internal/system/utils" 23 | 24 | // GenerateNewSessionDataKey generates and returns a new session data key. 25 | func GenerateNewSessionDataKey() string { 26 | return utils.GenerateUUID() 27 | } 28 | -------------------------------------------------------------------------------- /backend/internal/outboundauth/authenticator.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package outboundauth provides the interfaces and implementations for outbound authenticators. 20 | package outboundauth 21 | 22 | import ( 23 | "net/http" 24 | 25 | authnmodel "github.com/asgardeo/thunder/internal/authn/model" 26 | "github.com/asgardeo/thunder/internal/outboundauth/model" 27 | ) 28 | 29 | // AuthenticatorInterface defines a common interface for authenticators. 30 | type AuthenticatorInterface interface { 31 | Process(w http.ResponseWriter, r *http.Request, ctx *authnmodel.AuthenticationContext) error 32 | InitiateAuthenticationRequest(w http.ResponseWriter, r *http.Request, ctx *authnmodel.AuthenticationContext) error 33 | ProcessAuthenticationResponse(w http.ResponseWriter, r *http.Request, ctx *authnmodel.AuthenticationContext) error 34 | IsInitialRequest(r *http.Request, ctx *authnmodel.AuthenticationContext) bool 35 | GetAuthenticatorConfig() model.AuthenticatorConfig 36 | GetName() string 37 | GetFriendlyName() string 38 | } 39 | -------------------------------------------------------------------------------- /backend/internal/outboundauth/github/constants.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package github 20 | 21 | // Constants used for GitHub OAuth2 authentication and API endpoints. 22 | const ( 23 | githubAuthorizeEndpoint = "https://github.com/login/oauth/authorize" 24 | githubTokenEndpoint = "https://github.com/login/oauth/access_token" // #nosec G101 25 | githubUserInfoEndpoint = "https://api.github.com/user" 26 | githubUserEmailEndpoint = "https://api.github.com/user/emails" 27 | userScope = "user" 28 | userEmailScope = "user:email" 29 | ) 30 | 31 | // loggerComponentName is the name of the logger component for GitHub authenticator. 32 | const loggerComponentName = "GithubAuthenticator" 33 | -------------------------------------------------------------------------------- /backend/internal/outboundauth/model/model.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package model defines the data structures for outbound authenticators. 20 | package model 21 | 22 | // AuthenticatorConfig holds the common configurations for an authenticator. 23 | type AuthenticatorConfig struct { 24 | Name string `yaml:"name"` 25 | ID string `yaml:"id"` 26 | DisplayName string `yaml:"display_name"` 27 | Description string `yaml:"description"` 28 | Type string `yaml:"type"` 29 | } 30 | 31 | // OIDCAuthenticatorConfig holds the configuration details for the OIDC authenticator. 32 | type OIDCAuthenticatorConfig struct { 33 | AuthorizationEndpoint string `yaml:"authorization_endpoint"` 34 | TokenEndpoint string `yaml:"token_endpoint"` 35 | UserInfoEndpoint string `yaml:"userinfo_endpoint"` 36 | LogoutEndpoint string `yaml:"logout_endpoint"` 37 | ClientID string `yaml:"client_id"` 38 | ClientSecret string `yaml:"client_secret"` 39 | RedirectURI string `yaml:"redirect_uri"` 40 | Scopes []string `yaml:"scopes"` 41 | AdditionalParams map[string]string `yaml:"additional_params"` 42 | Properties map[string]string `yaml:"properties"` 43 | } 44 | -------------------------------------------------------------------------------- /backend/internal/outboundauth/oidc/utils/utils.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package utils provides utility functions for the OIDC authenticator. 20 | package utils 21 | 22 | // GetScopesString converts the scopes slice to a space-separated string. 23 | func GetScopesString(scopes []string) string { 24 | if len(scopes) == 0 { 25 | return "" 26 | } 27 | scopesString := scopes[0] 28 | for i := 1; i < len(scopes); i++ { 29 | scopesString += " " + scopes[i] 30 | } 31 | return scopesString 32 | } 33 | 34 | // GetState generates the state string for the federated flow. 35 | func GetState(sessionDataKey string) string { 36 | return sessionDataKey + "," + "oidc" 37 | } 38 | -------------------------------------------------------------------------------- /backend/internal/system/cert/cert.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package cert provides utilities for managing TLS certificates. 20 | package cert 21 | 22 | import ( 23 | "crypto/tls" 24 | "errors" 25 | "os" 26 | "path" 27 | 28 | "github.com/asgardeo/thunder/internal/system/config" 29 | ) 30 | 31 | // GetTLSConfig loads the TLS configuration from the certificate and key files. 32 | func GetTLSConfig(cfg *config.Config, currentDirectory string) (*tls.Config, error) { 33 | certFilePath := path.Join(currentDirectory, cfg.Security.CertFile) 34 | keyFilePath := path.Join(currentDirectory, cfg.Security.KeyFile) 35 | 36 | // Check if the certificate and key files exist. 37 | if _, err := os.Stat(certFilePath); os.IsNotExist(err) { 38 | return nil, errors.New("certificate file not found at " + certFilePath) 39 | } 40 | if _, err := os.Stat(keyFilePath); os.IsNotExist(err) { 41 | return nil, errors.New("key file not found at " + keyFilePath) 42 | } 43 | 44 | // Load the certificate and key. 45 | cert, err := tls.LoadX509KeyPair(certFilePath, keyFilePath) 46 | if err != nil { 47 | return nil, err 48 | } 49 | 50 | // Return the TLS configuration. 51 | return &tls.Config{ 52 | Certificates: []tls.Certificate{cert}, 53 | MinVersion: tls.VersionTLS12, // Enforce minimum TLS version 1.2 54 | }, nil 55 | } 56 | -------------------------------------------------------------------------------- /backend/internal/system/config/runtimeconfig.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package config 20 | 21 | import "sync" 22 | 23 | // ThunderRuntime holds the runtime configuration for the Thunder server. 24 | type ThunderRuntime struct { 25 | ThunderHome string `yaml:"thunder_home"` 26 | Config Config `yaml:"config"` 27 | } 28 | 29 | var ( 30 | runtimeConfig *ThunderRuntime 31 | once sync.Once 32 | ) 33 | 34 | // InitializeThunderRuntime initializes the ThunderRuntime configuration. 35 | func InitializeThunderRuntime(thunderHome string, config *Config) error { 36 | once.Do(func() { 37 | runtimeConfig = &ThunderRuntime{ 38 | ThunderHome: thunderHome, 39 | Config: *config, 40 | } 41 | }) 42 | 43 | return nil 44 | } 45 | 46 | // GetThunderRuntime returns the ThunderRuntime configuration. 47 | func GetThunderRuntime() *ThunderRuntime { 48 | if runtimeConfig == nil { 49 | panic("ThunderRuntime is not initialized") 50 | } 51 | return runtimeConfig 52 | } 53 | -------------------------------------------------------------------------------- /backend/internal/system/constants/serverconstants.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package constants defines global constants used across the system module. 20 | package constants 21 | 22 | const ( 23 | // LogLevelEnvironmentVariable is the environment variable name for the log level. 24 | LogLevelEnvironmentVariable = "LOG_LEVEL" 25 | // DefaultLogLevel is the default log level used if not specified. 26 | DefaultLogLevel = "info" 27 | ) 28 | 29 | // AuthorizationHeaderName is the name of the authorization header used in HTTP requests. 30 | const AuthorizationHeaderName = "Authorization" 31 | 32 | // AcceptHeaderName is the name of the accept header used in HTTP requests. 33 | const AcceptHeaderName = "Accept" 34 | 35 | // ContentTypeHeaderName is the name of the content type header used in HTTP requests. 36 | const ContentTypeHeaderName = "Content-Type" 37 | 38 | // TokenTypeBearer is the token type used in bearer authentication. 39 | const TokenTypeBearer = "Bearer" 40 | 41 | // ContentTypeJSON is the content type for JSON data. 42 | const ContentTypeJSON = "application/json" 43 | 44 | // ContentTypeFormURLEncoded is the content type for form-urlencoded data. 45 | const ContentTypeFormURLEncoded = "application/x-www-form-urlencoded" 46 | -------------------------------------------------------------------------------- /backend/internal/system/database/model/dbquery.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package model 20 | 21 | // DBQueryInterface defines the interface for database queries. 22 | type DBQueryInterface interface { 23 | GetId() string 24 | GetQuery() string 25 | } 26 | 27 | // DBQuery represents database queries with an identifier and the SQL query string. 28 | type DBQuery struct { 29 | // ID is the unique identifier for the query. 30 | ID string `json:"id"` 31 | // Query is the SQL query string. 32 | Query string `json:"query"` 33 | } 34 | 35 | // GetID returns the unique identifier for the query. 36 | func (d *DBQuery) GetID() string { 37 | return d.ID 38 | } 39 | 40 | // GetQuery returns the SQL query string. 41 | func (d *DBQuery) GetQuery() string { 42 | return d.Query 43 | } 44 | -------------------------------------------------------------------------------- /backend/internal/system/database/model/model.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package model defines the data structures and interfaces for database operations. 20 | package model 21 | 22 | import "database/sql" 23 | 24 | // TxInterface defines the wrapper interface for transaction management. 25 | type TxInterface interface { 26 | // Commit commits the transaction. 27 | Commit() error 28 | // Rollback rolls back the transaction. 29 | Rollback() error 30 | // Exec executes a query with the given arguments. 31 | Exec(query string, args ...any) (sql.Result, error) 32 | } 33 | 34 | // Tx is the implementation of TxInterface for managing database transactions. 35 | type Tx struct { 36 | internal *sql.Tx 37 | } 38 | 39 | // NewTx creates a new instance of Tx with the provided sql.Tx. 40 | func NewTx(tx *sql.Tx) TxInterface { 41 | return &Tx{ 42 | internal: tx, 43 | } 44 | } 45 | 46 | // Commit commits the transaction. 47 | func (t *Tx) Commit() error { 48 | return t.internal.Commit() 49 | } 50 | 51 | // Rollback rolls back the transaction. 52 | func (t *Tx) Rollback() error { 53 | return t.internal.Rollback() 54 | } 55 | 56 | // Exec executes a query with the given arguments. 57 | func (t *Tx) Exec(query string, args ...any) (sql.Result, error) { 58 | return t.internal.Exec(query, args...) 59 | } 60 | -------------------------------------------------------------------------------- /backend/internal/system/error/apierror/error.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package apierror defines the error structures for the API. 20 | package apierror 21 | 22 | // ErrorResponse defines a generic API error response. 23 | type ErrorResponse struct { 24 | Code string `json:"code"` 25 | Message string `json:"message"` 26 | Description string `json:"description"` 27 | } 28 | -------------------------------------------------------------------------------- /backend/internal/system/error/serviceerror/error.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package serviceerror defines the error structures for the service layer. 20 | package serviceerror 21 | 22 | // ServiceErrorType defines the type of service error. 23 | type ServiceErrorType string 24 | 25 | const ( 26 | // ClientErrorType denotes the client error type. 27 | ClientErrorType ServiceErrorType = "client_error" 28 | // ServerErrorType denotes the server error type. 29 | ServerErrorType ServiceErrorType = "server_error" 30 | ) 31 | 32 | // ServiceError defines a generic error structure that can be used across the service layer. 33 | type ServiceError struct { 34 | Code string `json:"code"` 35 | Type ServiceErrorType `json:"type"` 36 | Error string `json:"error"` 37 | ErrorDescription string `json:"error_description,omitempty"` 38 | } 39 | -------------------------------------------------------------------------------- /backend/internal/system/healthcheck/model/status.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package model defines the data structures for the health check module. 20 | package model 21 | 22 | // ServerStatus represents an liveliness details of the server. 23 | type ServerStatus struct { 24 | Status Status `json:"status,omitempty"` 25 | ServiceStatus []ServiceStatus `json:"service_status,omitempty"` 26 | } 27 | 28 | // ServiceStatus represents the status of a service in the system. 29 | type ServiceStatus struct { 30 | ServiceName string `json:"service_name,omitempty"` 31 | Status Status `json:"status,omitempty"` 32 | } 33 | 34 | // Status defines the status for service or server. 35 | type Status string 36 | 37 | // Status constants represent the possible statuses of a service. 38 | const ( 39 | // StatusUp indicates that the service is operational. 40 | StatusUp Status = "UP" 41 | // StatusDown indicates that the service is not operational. 42 | StatusDown Status = "DOWN" 43 | // StatusUnknown indicates that the service status is unknown. 44 | StatusUnknown Status = "UNKNOWN" 45 | ) 46 | -------------------------------------------------------------------------------- /backend/internal/system/healthcheck/provider/healthcheckprovider.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package provider provides functionality for managing health check service instances. 20 | package provider 21 | 22 | import ( 23 | "github.com/asgardeo/thunder/internal/system/healthcheck/service" 24 | ) 25 | 26 | // HealthCheckProviderInterface defines the interface for the health check provider. 27 | type HealthCheckProviderInterface interface { 28 | GetHealthCheckService() service.HealthCheckServiceInterface 29 | } 30 | 31 | // HealthCheckProvider is the default implementation of the HealthCheckProviderInterface. 32 | type HealthCheckProvider struct{} 33 | 34 | // NewHealthCheckProvider creates a new instance of HealthCheckProvider. 35 | func NewHealthCheckProvider() HealthCheckProviderInterface { 36 | return &HealthCheckProvider{} 37 | } 38 | 39 | // GetHealthCheckService returns the health check service instance. 40 | func (hcp *HealthCheckProvider) GetHealthCheckService() service.HealthCheckServiceInterface { 41 | return service.GetHealthCheckService() 42 | } 43 | -------------------------------------------------------------------------------- /backend/internal/system/healthcheck/service/dbconstants.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package service provides health check-related business logic and operations. 20 | package service 21 | 22 | import "github.com/asgardeo/thunder/internal/system/database/model" 23 | 24 | var queryConfigDBTable = model.DBQuery{ 25 | ID: "HLC-00001", 26 | Query: "SELECT ALLOWED_ORIGINS FROM IDN_OAUTH_ALLOWED_ORIGINS", 27 | } 28 | 29 | var queryRuntimeDBTable = model.DBQuery{ 30 | ID: "HLC-00002", 31 | Query: "SELECT CODE_ID FROM IDN_OAUTH2_AUTHZ_CODE", 32 | } 33 | -------------------------------------------------------------------------------- /backend/internal/system/log/constants.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package log 20 | 21 | const ( 22 | // LoggerKeyComponentName is the key used to identify the component name in the logger. 23 | LoggerKeyComponentName = "component" 24 | // LoggerKeyExecutorID is the key used to identify the executor ID in the logger. 25 | LoggerKeyExecutorID = "executorId" 26 | // LoggerKeyFlowID is the key used to identify the flow ID in the logger. 27 | LoggerKeyFlowID = "flowId" 28 | // LoggerKeyNodeID is the key used to identify the node ID in the logger. 29 | LoggerKeyNodeID = "nodeId" 30 | ) 31 | -------------------------------------------------------------------------------- /backend/internal/system/log/field.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package log 20 | 21 | // Field represents a key-value pair for structured logging. 22 | type Field struct { 23 | Key string 24 | Value interface{} 25 | } 26 | 27 | // String creates a Field with a string value. 28 | func String(key, value string) Field { 29 | return Field{Key: key, Value: value} 30 | } 31 | 32 | // Int creates a Field with an integer value. 33 | func Int(key string, value int) Field { 34 | return Field{Key: key, Value: value} 35 | } 36 | 37 | // Bool creates a Field with a boolean value. 38 | func Bool(key string, value bool) Field { 39 | return Field{Key: key, Value: value} 40 | } 41 | 42 | // Any creates a Field with any value. 43 | func Any(key string, value interface{}) Field { 44 | return Field{Key: key, Value: value} 45 | } 46 | 47 | // Error creates a Field with an error value. 48 | func Error(value error) Field { 49 | return Field{Key: "error", Value: value} 50 | } 51 | -------------------------------------------------------------------------------- /backend/internal/system/server/dbconstants.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package server 20 | 21 | import dbmodel "github.com/asgardeo/thunder/internal/system/database/model" 22 | 23 | // QueryAllowedOrigins is the query to retrieve allowed origins. 24 | var QueryAllowedOrigins = dbmodel.DBQuery{ 25 | ID: "SOQ-00001", 26 | Query: "SELECT ALLOWED_ORIGINS FROM IDN_OAUTH_ALLOWED_ORIGINS", 27 | } 28 | -------------------------------------------------------------------------------- /backend/internal/system/server/model.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package server 20 | 21 | // Cors represents the CORS configuration for the server requests. 22 | type Cors struct { 23 | AllowedMethods string 24 | AllowedHeaders string 25 | AllowCredentials bool 26 | } 27 | 28 | // RequestWrapOptions represents the options for wrapping requests. 29 | type RequestWrapOptions struct { 30 | Cors *Cors 31 | } 32 | -------------------------------------------------------------------------------- /backend/internal/system/services/authnservice.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package services 20 | 21 | import ( 22 | "net/http" 23 | 24 | "github.com/asgardeo/thunder/internal/authn" 25 | "github.com/asgardeo/thunder/internal/system/server" 26 | ) 27 | 28 | // AuthenticationService defines the service for handling authentication requests. 29 | type AuthenticationService struct { 30 | authHandler *authn.AuthenticationHandler 31 | } 32 | 33 | // NewAuthenticationService creates a new instance of AuthenticationService. 34 | func NewAuthenticationService(mux *http.ServeMux) *AuthenticationService { 35 | instance := &AuthenticationService{ 36 | authHandler: authn.NewAuthenticationHandler(), 37 | } 38 | instance.RegisterRoutes(mux) 39 | return instance 40 | } 41 | 42 | // RegisterRoutes registers the routes for the AuthenticationService. 43 | func (s *AuthenticationService) RegisterRoutes(mux *http.ServeMux) { 44 | opts := server.RequestWrapOptions{ 45 | Cors: &server.Cors{ 46 | AllowedMethods: "POST, GET", 47 | AllowedHeaders: "Content-Type, Authorization", 48 | AllowCredentials: true, 49 | }, 50 | } 51 | server.WrapHandleFunction(mux, "POST /flow/authn", &opts, s.authHandler.HandleAuthenticationRequest) 52 | server.WrapHandleFunction(mux, "GET /flow/authn", &opts, s.authHandler.HandleAuthenticationRequest) 53 | server.WrapHandleFunction(mux, "OPTIONS /flow/authn", &opts, func(w http.ResponseWriter, r *http.Request) { 54 | w.WriteHeader(http.StatusNoContent) 55 | }) 56 | } 57 | -------------------------------------------------------------------------------- /backend/internal/system/services/authorizationservice.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package services 20 | 21 | import ( 22 | "net/http" 23 | 24 | "github.com/asgardeo/thunder/internal/oauth/oauth2/authz" 25 | "github.com/asgardeo/thunder/internal/system/server" 26 | ) 27 | 28 | // AuthorizationService defines the service for handling OAuth2 authorization requests. 29 | type AuthorizationService struct { 30 | authHandler authz.AuthorizeHandlerInterface 31 | } 32 | 33 | // NewAuthorizationService creates a new instance of AuthorizationService. 34 | func NewAuthorizationService(mux *http.ServeMux) *AuthorizationService { 35 | instance := &AuthorizationService{ 36 | authHandler: authz.NewAuthorizeHandler(), 37 | } 38 | instance.RegisterRoutes(mux) 39 | 40 | return instance 41 | } 42 | 43 | // RegisterRoutes registers the routes for the AuthorizationService. 44 | func (s *AuthorizationService) RegisterRoutes(mux *http.ServeMux) { 45 | server.WrapHandleFunction(mux, "GET /oauth2/authorize", nil, s.authHandler.HandleAuthorizeRequest) 46 | } 47 | -------------------------------------------------------------------------------- /backend/internal/system/services/flowexecutionservice.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package services 20 | 21 | import ( 22 | "net/http" 23 | 24 | "github.com/asgardeo/thunder/internal/flow/handler" 25 | "github.com/asgardeo/thunder/internal/system/server" 26 | ) 27 | 28 | // FlowExecutionService defines the service for handling flow execution requests. 29 | type FlowExecutionService struct { 30 | flowExecutionHandler *handler.FlowExecutionHandler 31 | } 32 | 33 | // NewFlowExecutionService creates a new instance of FlowExecutionService. 34 | func NewFlowExecutionService(mux *http.ServeMux) *FlowExecutionService { 35 | instance := &FlowExecutionService{ 36 | flowExecutionHandler: handler.NewFlowExecutionHandler(), 37 | } 38 | instance.RegisterRoutes(mux) 39 | 40 | return instance 41 | } 42 | 43 | // RegisterRoutes registers the routes for the FlowExecutionService. 44 | func (s *FlowExecutionService) RegisterRoutes(mux *http.ServeMux) { 45 | // TODO: Ideally this should be renamed to "/flow/authn". Keeping it as "/flow/execute" until the 46 | // previous authenticator implementation is removed. 47 | opts := server.RequestWrapOptions{ 48 | Cors: &server.Cors{ 49 | AllowedMethods: "POST", 50 | AllowedHeaders: "Content-Type, Authorization", 51 | AllowCredentials: true, 52 | }, 53 | } 54 | server.WrapHandleFunction(mux, "POST /flow/execute", &opts, s.flowExecutionHandler.HandleFlowExecutionRequest) 55 | server.WrapHandleFunction(mux, "OPTIONS /flow/execute", &opts, func(w http.ResponseWriter, r *http.Request) { 56 | w.WriteHeader(http.StatusNoContent) 57 | }) 58 | } 59 | -------------------------------------------------------------------------------- /backend/internal/system/services/service.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package services provides a way to register and manage HTTP routes for the server. 20 | package services 21 | 22 | import "net/http" 23 | 24 | // The Route struct represents an HTTP route with its method, path, and handler function. 25 | type Route struct { 26 | Method string 27 | Path string 28 | HandlerFunc *http.HandlerFunc 29 | } 30 | 31 | // The ServiceInterface struct defines the service that will handle the routes. 32 | type ServiceInterface interface { 33 | RegisterRoutes(mux *http.ServeMux) 34 | } 35 | 36 | // The AbstractService struct is an empty struct that can be embedded in other services. 37 | type AbstractService struct{} 38 | 39 | // RegisterRoutes is a method that can be overridden by concrete services to register their routes. 40 | func (s *AbstractService) RegisterRoutes(mux *http.ServeMux) { 41 | // This method can be overridden by concrete services to register their routes. 42 | // For example: 43 | // opts := server.RequestWrapOptions{ 44 | // Cors: &server.Cors{ 45 | // AllowedMethods: "GET, POST", 46 | // AllowedHeaders: "Content-Type, Authorization", 47 | // AllowCredentials: true, 48 | // }, 49 | // } 50 | // server.WrapHandleFunction(mux, "GET /example", &opts, s.ExampleHandler) 51 | } 52 | -------------------------------------------------------------------------------- /backend/internal/system/services/tokenservice.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package services 20 | 21 | import ( 22 | "net/http" 23 | 24 | "github.com/asgardeo/thunder/internal/oauth/oauth2/token" 25 | "github.com/asgardeo/thunder/internal/system/server" 26 | ) 27 | 28 | // TokenService defines the service for handling OAuth2 token requests. 29 | type TokenService struct { 30 | tokenHandler *token.TokenHandler 31 | } 32 | 33 | // NewTokenService creates a new instance of TokenService. 34 | func NewTokenService(mux *http.ServeMux) *TokenService { 35 | instance := &TokenService{ 36 | tokenHandler: &token.TokenHandler{}, 37 | } 38 | instance.RegisterRoutes(mux) 39 | 40 | return instance 41 | } 42 | 43 | // RegisterRoutes registers the routes for the TokenService. 44 | func (s *TokenService) RegisterRoutes(mux *http.ServeMux) { 45 | opts := server.RequestWrapOptions{ 46 | Cors: &server.Cors{ 47 | AllowedMethods: "POST", 48 | AllowedHeaders: "Content-Type, Authorization", 49 | AllowCredentials: true, 50 | }, 51 | } 52 | server.WrapHandleFunction(mux, "POST /oauth2/token", &opts, s.tokenHandler.HandleTokenRequest) 53 | } 54 | -------------------------------------------------------------------------------- /backend/internal/system/utils/hashutil.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package utils 20 | 21 | import ( 22 | "crypto/rand" 23 | "crypto/sha256" 24 | "encoding/base64" 25 | "encoding/hex" 26 | ) 27 | 28 | // HashStringWithSalt hashes the input string with the given salt and returns the hex-encoded hash. 29 | func HashStringWithSalt(input, salt string) (string, error) { 30 | hasher := sha256.New() 31 | _, err := hasher.Write([]byte(input + salt)) 32 | if err != nil { 33 | return "", err 34 | } 35 | return hex.EncodeToString(hasher.Sum(nil)), nil 36 | } 37 | 38 | // GenerateSalt generates a random salt string. 39 | func GenerateSalt() (string, error) { 40 | salt := make([]byte, 16) 41 | _, err := rand.Read(salt) 42 | if err != nil { 43 | return "", err 44 | } 45 | return base64.StdEncoding.EncodeToString(salt), nil 46 | } 47 | -------------------------------------------------------------------------------- /backend/internal/system/utils/serverutils.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package utils provides utility functions for server wide operations. 20 | package utils 21 | 22 | import "strings" 23 | 24 | // GetAllowedOrigin checks if the redirect URI is allowed and returns the allowed origin. 25 | func GetAllowedOrigin(allowedOrigins []string, redirectURI string) string { 26 | if len(allowedOrigins) == 0 { 27 | return "" 28 | } 29 | 30 | for _, allowedOrigin := range allowedOrigins { 31 | if strings.Contains(redirectURI, allowedOrigin) { 32 | return allowedOrigin 33 | } 34 | } 35 | 36 | return "" 37 | } 38 | -------------------------------------------------------------------------------- /backend/internal/system/utils/uuidutil.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package utils 20 | 21 | import ( 22 | "crypto/rand" 23 | "fmt" 24 | "io" 25 | ) 26 | 27 | // GenerateUUID returns a UUID string in lowercase hexadecimal, following the canonical textual representation 28 | // as specified in RFC 9562. 29 | func GenerateUUID() string { 30 | var uuid [16]byte 31 | _, err := io.ReadFull(rand.Reader, uuid[:]) 32 | if err != nil { 33 | panic(fmt.Errorf("failed to generate random bytes: %w", err)) 34 | } 35 | 36 | uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4 37 | uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10 38 | 39 | return fmt.Sprintf("%x-%x-%x-%x-%x", 40 | uuid[0:4], 41 | uuid[4:6], 42 | uuid[6:8], 43 | uuid[8:10], 44 | uuid[10:], 45 | ) 46 | } 47 | -------------------------------------------------------------------------------- /backend/internal/user/model/user.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package model defines the data structures and interfaces for user management. 20 | package model 21 | 22 | import ( 23 | "encoding/json" 24 | "errors" 25 | ) 26 | 27 | // User represents a user in the system. 28 | type User struct { 29 | ID string `json:"id,omitempty"` 30 | OrganizationUnit string `json:"organizationUnit,omitempty"` 31 | Type string `json:"type,omitempty"` 32 | Attributes json.RawMessage `json:"attributes,omitempty"` 33 | } 34 | 35 | // Credentials represents the credentials of a user. 36 | type Credentials struct { 37 | CredentialType string `json:"credentialType"` 38 | StorageType string `json:"storageType"` 39 | StorageAlgo string `json:"storageAlgo"` 40 | Value string `json:"value"` 41 | Salt string `json:"salt"` 42 | } 43 | 44 | // ErrUserNotFound is returned when the user is not found in the system. 45 | var ErrUserNotFound = errors.New("user not found") 46 | 47 | // ErrBadAttributesInRequest is returned when the attributes in the request are invalid. 48 | var ErrBadAttributesInRequest = errors.New("failed to marshal attributes") 49 | -------------------------------------------------------------------------------- /backend/internal/user/provider/userprovider.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | // Package provider provides the implementation for user management operations. 20 | package provider 21 | 22 | import ( 23 | "github.com/asgardeo/thunder/internal/user/service" 24 | ) 25 | 26 | // UserProviderInterface defines the interface for the user provider. 27 | type UserProviderInterface interface { 28 | GetUserService() service.UserServiceInterface 29 | } 30 | 31 | // UserProvider is the default implementation of the UserProviderInterface. 32 | type UserProvider struct{} 33 | 34 | // NewUserProvider creates a new instance of UserProvider. 35 | func NewUserProvider() UserProviderInterface { 36 | return &UserProvider{} 37 | } 38 | 39 | // GetUserService returns the user service instance. 40 | func (ap *UserProvider) GetUserService() service.UserServiceInterface { 41 | return service.GetUserService() 42 | } 43 | -------------------------------------------------------------------------------- /frontend/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_style = space 8 | indent_size = 2 9 | insert_final_newline = true 10 | max_line_length = 120 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | max_line_length = off 15 | trim_trailing_whitespace = false 16 | 17 | [*.go] 18 | indent_size = 4 19 | -------------------------------------------------------------------------------- /frontend/.npmrc: -------------------------------------------------------------------------------- 1 | strict-peer-dependencies=false 2 | auto-install-peers=true 3 | -------------------------------------------------------------------------------- /frontend/.prettierignore: -------------------------------------------------------------------------------- 1 | # Add files here to ignore them from prettier formatting 2 | node_modules 3 | dist 4 | coverage 5 | .nx/cache 6 | .nx/workspace-data 7 | -------------------------------------------------------------------------------- /frontend/README.md: -------------------------------------------------------------------------------- 1 | # Project Thunder Frontend Apps 2 | 3 | - [Gate App](./apps/gate) 4 | -------------------------------------------------------------------------------- /frontend/apps/gate/.prettierignore: -------------------------------------------------------------------------------- 1 | # Add files here to ignore them from prettier formatting 2 | node_modules 3 | dist 4 | coverage 5 | .nx/cache 6 | .nx/workspace-data 7 | -------------------------------------------------------------------------------- /frontend/apps/gate/README.md: -------------------------------------------------------------------------------- 1 | # Thunder - Gate App 2 | 3 | This is the gate app for project thunder. Which serves UIs for Login, Registration and Recovery. 4 | 5 | ### ✅ Prerequisites 6 | 7 | - Node.js 14+ 8 | - PNPM 10+ 9 | 10 | --- 11 | 12 | ### 🛠 Step 1: Build and Run the Product 13 | 14 | ```bash 15 | 16 | pnpm i 17 | 18 | pnpm --filter gate dev 19 | ``` 20 | -------------------------------------------------------------------------------- /frontend/apps/gate/next.config.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import type { NextConfig } from "next"; 20 | 21 | const nextConfig: NextConfig = { 22 | transpilePackages: ['@oxygen-ui/react'], 23 | output: 'standalone', 24 | }; 25 | 26 | module.exports = nextConfig; 27 | -------------------------------------------------------------------------------- /frontend/apps/gate/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gate", 3 | "version": "0.1.0", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "dev": "NODE_ENV=development node server.js", 8 | "build": "pnpm ensure-certificates && NODE_ENV=production next build", 9 | "next_build": "next build", 10 | "ensure-certificates": "openssl req -newkey rsa:2048 -nodes -keyout server.key -x509 -days 365 -out server.cert -subj \"/C=US/ST=California/L=SanFrancisco/O=WSO2/OU=Dev/CN=localhost\"", 11 | "postbuild": "pnpm package", 12 | "package": "node scripts/package.js", 13 | "start": "node server.js", 14 | "lint": "next lint", 15 | "format": "prettier --write .", 16 | "clean": "rm -rf node_modules .next dist build out" 17 | }, 18 | "dependencies": { 19 | "@oxygen-ui/react": "file:../../packages/oxygen-ui", 20 | "@typescript-eslint/eslint-plugin": "^8.32.1", 21 | "@typescript-eslint/parser": "^8.32.1", 22 | "next": "15.3.1", 23 | "react": "^19.0.0", 24 | "react-dom": "^19.0.0" 25 | }, 26 | "devDependencies": { 27 | "@eslint/compat": "^1.2.9", 28 | "@eslint/eslintrc": "^3.3.1", 29 | "@next/eslint-plugin-next": "^15.1.8", 30 | "@types/node": "^20", 31 | "@types/react": "^19", 32 | "@types/react-dom": "^19", 33 | "@wso2/eslint-plugin": "https://gitpkg.now.sh/brionmario/wso2-ui-configs/packages/eslint-plugin?4ee6f6be232d7631999d709a86b91612f1d34ce7", 34 | "@wso2/prettier-config": "https://gitpkg.now.sh/brionmario/wso2-ui-configs/packages/prettier-config?4ee6f6be232d7631999d709a86b91612f1d34ce7", 35 | "@wso2/stylelint-config": "https://gitpkg.now.sh/brionmario/wso2-ui-configs/packages/stylelint-config?4ee6f6be232d7631999d709a86b91612f1d34ce7", 36 | "eslint": "^9.27.0", 37 | "eslint-config-next": "^15.1.8", 38 | "eslint-config-prettier": "^10.1.5", 39 | "eslint-plugin-headers": "^1.3.1", 40 | "eslint-plugin-prettier": "^5.4.0", 41 | "nx": "20.8.0", 42 | "prettier": "^3.5.3", 43 | "typescript": "^5" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /frontend/apps/gate/prettier.config.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2022, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | const MAX_LINE_LENGTH = 120; 20 | 21 | const config = { 22 | arrowParens: 'avoid', 23 | bracketSpacing: true, 24 | embeddedLanguageFormatting: 'auto', 25 | endOfLine: 'lf', 26 | htmlWhitespaceSensitivity: 'css', 27 | insertPragma: false, 28 | jsxBracketSameLine: false, 29 | jsxSingleQuote: false, 30 | printWidth: MAX_LINE_LENGTH, 31 | proseWrap: 'always', 32 | quoteProps: 'as-needed', 33 | requirePragma: false, 34 | semi: true, 35 | singleQuote: true, 36 | tabWidth: 2, 37 | trailingComma: 'all', 38 | useTabs: false, 39 | }; 40 | 41 | export default config; 42 | -------------------------------------------------------------------------------- /frontend/apps/gate/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asgardeo/thunder/a2cb977db6920e945fe8a3d25fc47dd4e7b4dfd5/frontend/apps/gate/public/favicon.ico -------------------------------------------------------------------------------- /frontend/apps/gate/src/app/error/page.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | 'use client'; 20 | 21 | import Alert from '@oxygen-ui/react/src/components/Alert/Alert'; 22 | import AlertTitle from '@oxygen-ui/react/src/components/AlertTitle/AlertTitle'; 23 | import Typography from '@oxygen-ui/react/src/components/Typography/Typography'; 24 | import React, { useState, useEffect, ReactElement } from 'react'; 25 | 26 | const FallbackErrorMessage: string = 'Sorry, but we encountered an error while processing your request.'; 27 | 28 | export default function ErrorPage(): ReactElement { 29 | const [errorCode, setErrorCode] = useState(''); 30 | const [errorMsg, setErrorMsg] = useState(FallbackErrorMessage); 31 | 32 | useEffect(() => { 33 | const params: URLSearchParams = new URLSearchParams(window.location.search); 34 | 35 | setErrorCode(params.get('oauthErrorCode') || ''); 36 | setErrorMsg(params.get('oauthErrorMsg') || FallbackErrorMessage); 37 | }, []); 38 | 39 | return ( 40 | 41 | 42 | Something didn't go as expected! 43 | 44 | 45 | {errorMsg} 46 | 47 | {errorCode !== '' && ( 48 | 49 | Error Code: {errorCode} 50 | 51 | )} 52 | 53 | ); 54 | } 55 | -------------------------------------------------------------------------------- /frontend/apps/gate/src/app/login/page.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import type { Metadata } from 'next'; 20 | import LoginPageContent from './content'; 21 | import { ReactElement } from 'react'; 22 | 23 | export const metadata: Metadata = { 24 | title: 'Login', 25 | description: 'Login to your application', 26 | }; 27 | 28 | export default function LoginPage(): ReactElement { 29 | return ; 30 | } 31 | -------------------------------------------------------------------------------- /frontend/apps/gate/src/app/not-found.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import Box from '@oxygen-ui/react/src/components/Box/Box'; 20 | import Typography from '@oxygen-ui/react/src/components/Typography/Typography'; 21 | import Link from 'next/link'; 22 | import { ReactElement } from 'react'; 23 | 24 | export default function NotFound(): ReactElement { 25 | return ( 26 | 27 | 28 | 404 - Page Not Found 29 | 30 | Sorry, the page you are looking for does not exist. 31 | 32 | Go back home 33 | 34 | 35 | ); 36 | } 37 | -------------------------------------------------------------------------------- /frontend/apps/gate/src/app/page.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import { redirect } from 'next/navigation'; 20 | 21 | export default function RootPage(): void { 22 | redirect('/login'); 23 | } 24 | -------------------------------------------------------------------------------- /frontend/apps/gate/src/components/Logo.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | 'use client'; 20 | 21 | import { useColorScheme } from '@oxygen-ui/react/src/hooks/useColorScheme'; 22 | import Image from 'next/image'; 23 | import { ReactElement } from 'react'; 24 | 25 | export default function Logo(): ReactElement { 26 | const { mode } = useColorScheme(); 27 | 28 | const logoSrc: string = mode === 'dark' ? '/images/logo-dark.svg' : '/images/logo-light.svg'; 29 | 30 | return Logo; 31 | } 32 | -------------------------------------------------------------------------------- /frontend/apps/gate/src/configs/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "productName": "WSO2 Thunder", 3 | "authenticationEndpoint": "https://localhost:8090/flow/authn" 4 | } 5 | -------------------------------------------------------------------------------- /frontend/apps/gate/src/images/layout-image.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | 'use client'; 20 | 21 | import Box from '@oxygen-ui/react/src/components/Box/Box'; 22 | import { useColorScheme } from '@oxygen-ui/react/src/hooks/useColorScheme'; 23 | import { useTheme } from '@oxygen-ui/react/src/hooks/useTheme'; 24 | import Image from 'next/image'; 25 | import { ReactNode } from 'react'; 26 | 27 | const SideImage = (): ReactNode => { 28 | const theme = useTheme(); 29 | const { mode, systemMode } = useColorScheme(); 30 | 31 | const resolvedMode = mode === 'system' ? systemMode : mode; 32 | const imageSrc = resolvedMode === 'dark' ? '/images/login/image-light.svg' : '/images/login/image-light.svg'; 33 | 34 | return ( 35 | 48 | Login Page Side Image 49 | 50 | ); 51 | }; 52 | 53 | export default SideImage; 54 | -------------------------------------------------------------------------------- /frontend/apps/gate/src/layouts/base.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import ThemeProvider from '@oxygen-ui/react/src/contexts/ThemeProvider'; 20 | import { InitColorSchemeScript } from '@oxygen-ui/react/src/components/InitColorSchemeScript/InitColorSchemeScript'; 21 | import { Geist, Geist_Mono } from 'next/font/google'; 22 | import { Metadata } from 'next'; 23 | import { NextFontWithVariable } from 'next/dist/compiled/@next/font'; 24 | import { ReactElement } from 'react'; 25 | import '../globals.css'; 26 | 27 | export const metadata: Metadata = { 28 | icons: { 29 | icon: '/favicon.ico', 30 | shortcut: '/favicon.ico', 31 | }, 32 | }; 33 | 34 | const geistSans: NextFontWithVariable = Geist({ 35 | variable: '--font-geist-sans', 36 | subsets: ['latin'], 37 | }); 38 | 39 | const geistMono: NextFontWithVariable = Geist_Mono({ 40 | variable: '--font-geist-mono', 41 | subsets: ['latin'], 42 | }); 43 | 44 | export default function RootLayout({ 45 | children, 46 | }: Readonly<{ 47 | children: React.ReactNode; 48 | }>): ReactElement { 49 | return ( 50 | 51 | 52 | 53 |
54 | {children} 55 | 56 | 57 | ); 58 | } 59 | -------------------------------------------------------------------------------- /frontend/apps/gate/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "preserve", 4 | "noEmit": true, 5 | "incremental": true, 6 | "resolveJsonModule": true, 7 | "esModuleInterop": true, 8 | "lib": [ 9 | "dom", 10 | "dom.iterable", 11 | "esnext" 12 | ], 13 | "allowJs": true, 14 | "isolatedModules": true, 15 | "plugins": [ 16 | { 17 | "name": "next" 18 | } 19 | ], 20 | "baseUrl": ".", 21 | "paths": { 22 | "@/*": [ 23 | "./src/*" 24 | ] 25 | }, 26 | "target": "ES2017", 27 | "skipLibCheck": true, 28 | "strict": false, 29 | "module": "esnext", 30 | "moduleResolution": "node" 31 | }, 32 | "include": [ 33 | "**/*.ts", 34 | "**/*.tsx", 35 | ".next/types/**/*.ts", 36 | "next-env.d.ts", 37 | ], 38 | "exclude": [ 39 | "dist", 40 | "node_modules" 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /frontend/nx.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/nx/schemas/nx-schema.json", 3 | "workspaceLayout": { 4 | "appsDir": "apps", 5 | "libsDir": "packages" 6 | }, 7 | "namedInputs": { 8 | "default": [ 9 | "{projectRoot}/**/*", 10 | "sharedGlobals" 11 | ], 12 | "production": [ 13 | "default" 14 | ], 15 | "sharedGlobals": [] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "thunder-source", 3 | "version": "0.1.0", 4 | "license": "Apache-2.0", 5 | "scripts": { 6 | "start": "pnpm run", 7 | "build": "pnpm i --yes && nx run-many --target=build --all", 8 | "lint": "nx run-many --target=lint --all", 9 | "test": "nx run-many --target=test --all", 10 | "graph": "nx graph", 11 | "gate:build": "pnpm i --yes && pnpm --filter gate build", 12 | "gate:dev": "pnpm --filter gate dev" 13 | }, 14 | "private": true, 15 | "devDependencies": { 16 | "@nx/workspace": "20.8.0", 17 | "nx": "20.8.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/README.md: -------------------------------------------------------------------------------- 1 | # Oxygen-UI - WSO2 Design System -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@oxygen-ui/react", 3 | "version": "0.0.0", 4 | "main": "modules/index.js", 5 | "types": "modules/index.d.ts", 6 | "type":"module", 7 | "files": [ 8 | "modules" 9 | ], 10 | "scripts": { 11 | "prebuild": "rm -rf modules", 12 | "build": "tsc" 13 | }, 14 | "dependencies": { 15 | "@emotion/react": "^11.11.0", 16 | "@emotion/styled": "^11.11.0", 17 | "@mui/icons-material": "^7.1.0", 18 | "@mui/material": "^7.0.2", 19 | "@mui/system": "^7.1.0", 20 | "react": "^19.1.0", 21 | "react-dom": "^19.1.0" 22 | }, 23 | "devDependencies": { 24 | "@types/react": "^19.1.5", 25 | "@types/react-dom": "^19.1.5", 26 | "typescript": "^5.0.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/scripts/generate-exports.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | const fs = require('fs'); 20 | const path = require('path'); 21 | 22 | const rootDir = path.resolve(__dirname, '..'); 23 | const componentsDir = path.join(rootDir, 'src', 'components'); 24 | const packageJsonPath = path.join(rootDir, 'package.json'); 25 | 26 | const packageJson = require(packageJsonPath); 27 | 28 | const exportsField = { 29 | '.': { 30 | import: './dist/index.js', 31 | require: './dist/index.js', 32 | }, 33 | }; 34 | 35 | fs.readdirSync(componentsDir).forEach((file) => { 36 | const ext = path.extname(file); 37 | const name = path.basename(file, ext); 38 | if (ext === '.ts' || ext === '.tsx') { 39 | exportsField[`./${name}`] = { 40 | import: `./dist/components/${name}.js`, 41 | require: `./dist/components/${name}.js`, 42 | }; 43 | } 44 | }); 45 | 46 | packageJson.exports = exportsField; 47 | 48 | fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2)); 49 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/components/Alert/Alert.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import React from 'react'; 20 | import { Alert as MUIAlert, AlertProps } from '@mui/material'; 21 | 22 | const Alert = (props: AlertProps): React.JSX.Element => { 23 | return ; 24 | }; 25 | 26 | export type { AlertProps }; 27 | 28 | export default Alert; 29 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/components/AlertTitle/AlertTitle.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import React from 'react'; 20 | import { AlertTitle as MUIAlertTitle, AlertTitleProps } from '@mui/material'; 21 | 22 | const AlertTitle = (props: AlertTitleProps): React.JSX.Element => { 23 | return ; 24 | }; 25 | 26 | export type { AlertTitleProps }; 27 | 28 | export default AlertTitle; 29 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/components/Box/Box.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import React from 'react'; 20 | import { Box as MUIBox, BoxProps } from '@mui/material'; 21 | 22 | const Box = (props: BoxProps): React.JSX.Element => { 23 | return ; 24 | }; 25 | 26 | export type { BoxProps }; 27 | 28 | export default Box; 29 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/components/Button/Button.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import React from 'react'; 20 | import { Button as MUIButton, ButtonProps } from '@mui/material'; 21 | 22 | const Button = (props: ButtonProps): React.JSX.Element => { 23 | return ; 24 | }; 25 | 26 | export type { ButtonProps }; 27 | 28 | export default Button; 29 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/components/Checkbox/Checkbox.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import React from 'react'; 20 | import { Checkbox as MUICheckbox, CheckboxProps } from '@mui/material'; 21 | 22 | const Checkbox = (props: CheckboxProps): React.JSX.Element => { 23 | return ; 24 | }; 25 | 26 | export type { CheckboxProps }; 27 | 28 | export default Checkbox; 29 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/components/CircularProgress/CircularProgress.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import CircularProgress from '@mui/material/CircularProgress'; 20 | 21 | export default function LoadingSpinner() { 22 | return ; 23 | } 24 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/components/Divider/Divider.tsx: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 4 | * 5 | * WSO2 LLC. licenses this file to you under the Apache License, 6 | * Version 2.0 (the "License"); you may not use this file except 7 | * in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | import React from 'react'; 21 | import { Divider as MUIDivider, DividerProps } from '@mui/material'; 22 | 23 | const Divider = (props: DividerProps): React.JSX.Element => { 24 | return ; 25 | }; 26 | 27 | export type { DividerProps }; 28 | 29 | export default Divider; 30 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/components/FormControl/FormControl.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import React from 'react'; 20 | import { FormControl as MUIFormControl, FormControlProps } from '@mui/material'; 21 | 22 | const FormControl = (props: FormControlProps): React.JSX.Element => { 23 | return ; 24 | }; 25 | 26 | export type { FormControlProps }; 27 | 28 | export default FormControl; 29 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/components/FormControlLabel/FormControlLabel.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import React from 'react'; 20 | import { FormControlLabel as MUIFormControlLabel, FormControlLabelProps } from '@mui/material'; 21 | 22 | const FormControlLabel = (props: FormControlLabelProps): React.JSX.Element => { 23 | return ; 24 | }; 25 | 26 | export type { FormControlLabelProps }; 27 | 28 | export default FormControlLabel; 29 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/components/FormLabel/FormLabel.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import React from 'react'; 20 | import { FormLabel as MUIFormLabel, FormLabelProps } from '@mui/material'; 21 | 22 | const FormLabel = (props: FormLabelProps): React.JSX.Element => { 23 | return ; 24 | }; 25 | 26 | export type { FormLabelProps }; 27 | 28 | export default FormLabel; 29 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/components/Grid/Grid.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import React from 'react'; 20 | import { Grid as MUIGrid, GridProps } from '@mui/material'; 21 | 22 | const Grid = (props: GridProps): React.JSX.Element => { 23 | return ; 24 | }; 25 | 26 | export type { GridProps }; 27 | 28 | export default Grid; 29 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/components/Icon/Icon.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | export * from '@mui/icons-material'; 20 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/components/IconButton/IconButton.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import React from 'react'; 20 | import { IconButton as MUIIconButton, IconButtonProps } from '@mui/material'; 21 | 22 | const IconButton = (props: IconButtonProps): React.JSX.Element => { 23 | return ; 24 | }; 25 | 26 | export type { IconButtonProps }; 27 | 28 | export default IconButton; 29 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/components/InitColorSchemeScript/InitColorSchemeScript.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | export { default as InitColorSchemeScript } from '@mui/material/InitColorSchemeScript'; 20 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/components/Input/Input.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import React from 'react'; 20 | import { Input as MUIInput, InputProps } from '@mui/material'; 21 | 22 | const Input = (props: InputProps): React.JSX.Element => { 23 | return ; 24 | }; 25 | 26 | export type { InputProps }; 27 | 28 | export default Input; 29 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/components/InputLabel/InputLabel.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import React from 'react'; 20 | import { InputLabel as MUIInputLabel, InputLabelProps } from '@mui/material'; 21 | 22 | const InputLabel = (props: InputLabelProps): React.JSX.Element => { 23 | return ; 24 | }; 25 | 26 | export type { InputLabelProps }; 27 | 28 | export default InputLabel; 29 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/components/Link/Link.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import React from 'react'; 20 | import { Link as MUILink, LinkProps } from '@mui/material'; 21 | 22 | const Link = (props: LinkProps): React.JSX.Element => { 23 | return ; 24 | }; 25 | 26 | export type { LinkProps }; 27 | 28 | export default Link; 29 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/components/OutlinedInput/OutlinedInput.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import React from 'react'; 20 | import { OutlinedInput as MUIOutlinedInput, OutlinedInputProps } from '@mui/material'; 21 | 22 | const OutlinedInput = (props: OutlinedInputProps): React.JSX.Element => { 23 | return ; 24 | }; 25 | 26 | export type { OutlinedInputProps }; 27 | 28 | export default OutlinedInput; 29 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/components/Paper/Paper.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import React from 'react'; 20 | import { Paper as MUIPaper, PaperProps } from '@mui/material'; 21 | 22 | const Paper = (props: PaperProps): React.JSX.Element => { 23 | return ; 24 | }; 25 | 26 | export type { PaperProps }; 27 | 28 | export default Paper; 29 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/components/Stack/Stack.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import React from 'react'; 20 | import { Stack as MUIStack, StackProps } from '@mui/material'; 21 | 22 | const Stack = (props: StackProps): React.JSX.Element => { 23 | return ; 24 | }; 25 | 26 | export type { StackProps }; 27 | 28 | export default Stack; 29 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/components/TextField/TextField.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import React from 'react'; 20 | import { TextField as MUITextField, TextFieldProps } from '@mui/material'; 21 | 22 | const TextField = (props: TextFieldProps): React.JSX.Element => { 23 | return ( 24 | 33 | ); 34 | }; 35 | 36 | export type { TextFieldProps }; 37 | 38 | export default TextField; 39 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/components/ThemeToggle/ThemeToggle.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | /* 4 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 5 | * 6 | * WSO2 LLC. licenses this file to you under the Apache License, 7 | * Version 2.0 (the "License"); you may not use this file except 8 | * in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, 14 | * software distributed under the License is distributed on an 15 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * KIND, either express or implied. See the License for the 17 | * specific language governing permissions and limitations 18 | * under the License. 19 | */ 20 | 21 | import { useColorScheme } from '@mui/material/styles'; 22 | import Button from '@mui/material/Button'; 23 | import CircularProgress from '@mui/material/CircularProgress'; 24 | import { DarkModeRounded, LightModeRounded, Monitor } from '@mui/icons-material'; 25 | import { useMounted } from '../../hooks/useMounted'; 26 | 27 | type Mode = 'light' | 'dark' | 'system'; 28 | 29 | export default function ThemeToggle() { 30 | const mounted = useMounted(); 31 | const { mode, setMode } = useColorScheme(); 32 | 33 | if (!mounted) { 34 | return ( 35 | 38 | ); 39 | } 40 | 41 | if (!mode) { 42 | return null; 43 | } 44 | 45 | const nextMode = (mode: Mode): Mode => { 46 | return mode === 'light' ? 'dark' : mode === 'dark' ? 'system' : 'light'; 47 | }; 48 | 49 | const currentMode: Mode = mode ?? 'system'; 50 | 51 | const ColorModeIcon = () => { 52 | switch (currentMode) { 53 | case 'light': 54 | return ; 55 | case 'dark': 56 | return ; 57 | default: 58 | return ; 59 | } 60 | }; 61 | 62 | return ( 63 | 66 | ); 67 | }; 68 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/components/Typography/Typography.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import React from 'react'; 20 | import { Typography as MUITypography, TypographyProps } from '@mui/material'; 21 | 22 | const Typography = (props: TypographyProps): React.JSX.Element => { 23 | return ; 24 | }; 25 | 26 | export type { TypographyProps }; 27 | 28 | export default Typography; 29 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/contexts/ThemeProvider.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | /* 4 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 5 | * 6 | * WSO2 LLC. licenses this file to you under the Apache License, 7 | * Version 2.0 (the "License"); you may not use this file except 8 | * in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, 14 | * software distributed under the License is distributed on an 15 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * KIND, either express or implied. See the License for the 17 | * specific language governing permissions and limitations 18 | * under the License. 19 | */ 20 | 21 | import { ThemeProvider as MUIThemeProvider } from '@mui/material/styles'; 22 | import CssBaseline from '@mui/material/CssBaseline'; 23 | import theme from '../theme'; 24 | 25 | export default function ThemeProvider({ children }: { children: React.ReactNode }) { 26 | return ( 27 | 28 | 29 | {children} 30 | 31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/hooks/useColorScheme.ts: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | /* 4 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 5 | * 6 | * WSO2 LLC. licenses this file to you under the Apache License, 7 | * Version 2.0 (the "License"); you may not use this file except 8 | * in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, 14 | * software distributed under the License is distributed on an 15 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * KIND, either express or implied. See the License for the 17 | * specific language governing permissions and limitations 18 | * under the License. 19 | */ 20 | 21 | export { useColorScheme } from '@mui/material/styles'; 22 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/hooks/useMounted.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import { useEffect, useState } from 'react'; 20 | 21 | export function useMounted() { 22 | const [mounted, setMounted] = useState(false); 23 | useEffect(() => { 24 | setMounted(true); 25 | }, []); 26 | return mounted; 27 | } 28 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/hooks/useTheme.ts: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | /* 4 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 5 | * 6 | * WSO2 LLC. licenses this file to you under the Apache License, 7 | * Version 2.0 (the "License"); you may not use this file except 8 | * in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, 14 | * software distributed under the License is distributed on an 15 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * KIND, either express or implied. See the License for the 17 | * specific language governing permissions and limitations 18 | * under the License. 19 | */ 20 | 21 | export { useTheme } from '@mui/material/styles'; 22 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | export * from './components/Alert/Alert'; 20 | export * from './components/AlertTitle/AlertTitle'; 21 | export * from './components/Box/Box'; 22 | export * from './components/Button/Button'; 23 | export * from './components/Checkbox/Checkbox'; 24 | export * from './components/CircularProgress/CircularProgress'; 25 | export * from './components/Divider/Divider'; 26 | export * from './components/FormControl/FormControl'; 27 | export * from './components/FormControlLabel/FormControlLabel'; 28 | export * from './components/FormLabel/FormLabel'; 29 | export * from './components/Grid/Grid'; 30 | export * from './components/IconButton/IconButton'; 31 | export * from './components/Input/Input'; 32 | export * from './components/InputLabel/InputLabel'; 33 | export * from './components/Link/Link'; 34 | export * from './components/OutlinedInput/OutlinedInput'; 35 | export * from './components/Paper/Paper'; 36 | export * from './components/Stack/Stack'; 37 | export * from './components/TextField/TextField'; 38 | export * from './components/ThemeToggle/ThemeToggle'; 39 | export * from './components/Typography/Typography'; 40 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/src/theme/components.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import { Components, Theme } from '@mui/material/styles'; 20 | 21 | const components = (theme: Theme): Components => ({ 22 | MuiLink: { 23 | styleOverrides: { 24 | root: { 25 | color: theme.palette.primary.main, 26 | textDecoration: 'none', 27 | '&:hover': { 28 | color: theme.palette.primary.dark, 29 | textDecoration: 'underline', 30 | }, 31 | }, 32 | }, 33 | }, 34 | }); 35 | 36 | export default components; 37 | -------------------------------------------------------------------------------- /frontend/packages/oxygen-ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "rootDir": "./src", 5 | "outDir": "./modules", 6 | "declaration": true, 7 | "declarationMap": true, 8 | "emitDeclarationOnly": false, 9 | "composite": true, 10 | "incremental": true, 11 | "module": "ESNext", 12 | "moduleResolution": "node", 13 | "target": "ES2017", 14 | "jsx": "react-jsx", 15 | "types": ["react", "react-dom"], 16 | "strict": true, 17 | "skipLibCheck": true, 18 | "typeRoots": ["node_modules/@types"] 19 | }, 20 | "include": ["src/**/*"], 21 | "exclude": ["modules", "node_modules"] 22 | } 23 | -------------------------------------------------------------------------------- /frontend/pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'apps/*' 3 | - 'packages/*' 4 | -------------------------------------------------------------------------------- /frontend/tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "target": "ES2020", 5 | "module": "ESNext", 6 | "moduleResolution": "node", 7 | "jsx": "react-jsx", 8 | "strict": true, 9 | "esModuleInterop": true, 10 | "skipLibCheck": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "allowSyntheticDefaultImports": true, 13 | "resolveJsonModule": true 14 | }, 15 | "include": ["packages/**/*", "apps/**/*"] 16 | } 17 | -------------------------------------------------------------------------------- /frontend/workspace.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "$schema": "./node_modules/nx/schemas/workspace-schema.json", 4 | "projects": { 5 | "oxygen-ui": { 6 | "root": "packages/oxygen-ui", 7 | "sourceRoot": "packages/oxygen-ui/src", 8 | "projectType": "library", 9 | "targets": { 10 | "build": { 11 | "executor": "nx:run-commands", 12 | "options": { 13 | "command": "tsc", 14 | "cwd": "packages/oxygen-ui" 15 | } 16 | } 17 | } 18 | }, 19 | "gate": { 20 | "root": "apps/gate", 21 | "targets": { 22 | "build": { 23 | "executor": "nx:run-commands", 24 | "options": { 25 | "command": "next build", 26 | "cwd": "apps/gate" 27 | } 28 | }, 29 | "serve": { 30 | "executor": "nx:run-commands", 31 | "options": { 32 | "command": "next dev", 33 | "cwd": "apps/gate" 34 | } 35 | }, 36 | "lint": { 37 | "executor": "nx:run-commands", 38 | "options": { 39 | "command": "next lint", 40 | "cwd": "apps/gate" 41 | } 42 | } 43 | } 44 | }, 45 | "admin": { 46 | "root": "apps/admin", 47 | "targets": { 48 | "build": { 49 | "executor": "nx:run-commands", 50 | "options": { 51 | "command": "next build", 52 | "cwd": "apps/admin" 53 | } 54 | }, 55 | "serve": { 56 | "executor": "nx:run-commands", 57 | "options": { 58 | "command": "next dev", 59 | "cwd": "apps/admin" 60 | } 61 | }, 62 | "lint": { 63 | "executor": "nx:run-commands", 64 | "options": { 65 | "command": "next lint", 66 | "cwd": "apps/admin" 67 | } 68 | } 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /samples/apps/oauth/.env.example: -------------------------------------------------------------------------------- 1 | ## General App Configuration 2 | 3 | # The base URL for the client application 4 | # E.g., https://localhost:3002 5 | VITE_REACT_APP_REDIRECT_URI=https://localhost:3000 6 | 7 | # Enable redirect-based login 8 | VITE_REACT_APP_REDIRECT_BASED_LOGIN=false 9 | 10 | 11 | ## Server Configuration 12 | 13 | # Applications endpoint 14 | # E.g., https://localhost:8090/applications 15 | VITE_REACT_APPLICATIONS_ENDPOINT=https://localhost:8090/applications 16 | 17 | # Flow endpoint for the server 18 | # E.g., https://localhost:8090/flow 19 | VITE_REACT_APP_SERVER_FLOW_ENDPOINT=https://localhost:8090/flow 20 | 21 | # Application ID registered in Thunder for Basic Authentication 22 | VITE_REACT_APP_AUTH_APP_ID= 23 | 24 | 25 | ## Server OAuth Configuration 26 | 27 | # Server authorization endpoint 28 | # E.g., https://localhost:8090/oauth2/authorize 29 | VITE_REACT_APP_SERVER_AUTHORIZATION_ENDPOINT=https://localhost:8090/oauth2/authorize 30 | 31 | # Server token endpoint 32 | # E.g., https://localhost:8090/oauth2/token 33 | VITE_REACT_APP_SERVER_TOKEN_ENDPOINT=https://localhost:8090/oauth2/token 34 | 35 | # Sever authentication endpoint 36 | # E.g., https://localhost:8090/oauth2/token 37 | VITE_REACT_AUTHENTICATION_ENDPOINT=https://localhost:8090/flow/authn 38 | 39 | # App client ID 40 | VITE_REACT_APP_CLIENT_ID= 41 | 42 | # App client secret 43 | VITE_REACT_APP_CLIENT_SECRET= 44 | 45 | # The base URL for the client application 46 | # E.g., https://localhost:3002 47 | VITE_REACT_APP_SCOPE=openid 48 | -------------------------------------------------------------------------------- /samples/apps/oauth/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | 26 | # Vite 27 | .vite 28 | -------------------------------------------------------------------------------- /samples/apps/oauth/README.md: -------------------------------------------------------------------------------- 1 | # Sample Client App 2 | 3 | This is a sample React application that demonstrates the Thunder login flow. The application allows users to log in using their credentials and retrieves an access token from the server. 4 | 5 | ## Hosting Options 6 | 7 | This sample application includes everything you need to run the Thunder login demo. The built package contains the compiled application (`dist` folder), along with a simple Node.js server implementation (`server.js`) for your convenience. You can choose to run the application using the provided server or host it on your preferred web server. 8 | 9 | ### Option 1: Using the Provided Node Server 10 | 11 | The sample application comes with a built-in Node.js server that serves the React app over HTTPS. Follow the steps below to set it up: 12 | 13 | **Prerequisites:** 14 | - Node.js 20+ 15 | 16 | 1. **Install dependencies:** 17 | ```bash 18 | npm i 19 | ``` 20 | 21 | 2. **Start the server:** 22 | ```bash 23 | npm start 24 | ``` 25 | 26 | 3. **Access the application:** 27 | Navigate to `https://localhost:3000` 28 | 29 | ### Option 2: Using Your Own Web Server 30 | 31 | The `dist` folder contains the built application that can be hosted on any web server. Configure your server to serve these static files and ensure proper HTTPS setup. 32 | 33 | **Generate Certificates:** 34 | 35 | Generate a self-signed SSL certificate by running the following command: 36 | 37 | ```bash 38 | openssl req -nodes -new -x509 -keyout server.key -out server.cert 39 | ``` 40 | 41 | **Configure environment variables:** 42 | 43 | Add the following environment variables to your web server configuration or `.env` file. Replace `` with your actual application ID. 44 | 45 | ```env 46 | VITE_REACT_APPLICATIONS_ENDPOINT=https://localhost:8090/applications 47 | VITE_REACT_APP_SERVER_FLOW_ENDPOINT=https://localhost:8090/flow 48 | VITE_REACT_APP_AUTH_APP_ID= 49 | ``` 50 | 51 | ## License 52 | 53 | Licenses this source under the Apache License, Version 2.0 LICENSE, You may not use this file except in compliance with the License. 54 | 55 | --------------------------------------------------------------------------- 56 | (c) Copyright 2025 WSO2 LLC. 57 | -------------------------------------------------------------------------------- /samples/apps/oauth/eslint.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import js from '@eslint/js' 20 | import globals from 'globals' 21 | import reactHooks from 'eslint-plugin-react-hooks' 22 | import reactRefresh from 'eslint-plugin-react-refresh' 23 | import tseslint from 'typescript-eslint' 24 | 25 | export default tseslint.config( 26 | { ignores: ['dist'] }, 27 | { 28 | extends: [js.configs.recommended, ...tseslint.configs.recommended], 29 | files: ['**/*.{ts,tsx}'], 30 | languageOptions: { 31 | ecmaVersion: 2020, 32 | globals: globals.browser, 33 | }, 34 | plugins: { 35 | 'react-hooks': reactHooks, 36 | 'react-refresh': reactRefresh, 37 | }, 38 | rules: { 39 | ...reactHooks.configs.recommended.rules, 40 | 'react-refresh/only-export-components': [ 41 | 'warn', 42 | { allowConstantExport: true }, 43 | ], 44 | }, 45 | }, 46 | ) 47 | -------------------------------------------------------------------------------- /samples/apps/oauth/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Thunder Sample App 8 | 40 | 41 | 42 |
43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /samples/apps/oauth/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-oauth-sample-app", 3 | "private": true, 4 | "version": "0.1.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc -b && vite build && npm run build:server", 9 | "start": "tsc -b && vite build && vite preview", 10 | "lint": "eslint .", 11 | "preview": "vite preview", 12 | "copy:app": "rm -rf server/app && mkdir -p server/app && cp -r dist/* server/app", 13 | "copy:certs": "cp -r server.key server.cert server ", 14 | "build:server": "npm run copy:app && npm run copy:certs && cd server && npm install" 15 | }, 16 | "dependencies": { 17 | "@emotion/react": "^11.11.0", 18 | "@emotion/styled": "^11.11.0", 19 | "@mui/icons-material": "^7.1.0", 20 | "@mui/material": "^7.0.2", 21 | "@mui/system": "^7.1.0", 22 | "axios": "^1.9.0", 23 | "react": "^19.1.0", 24 | "react-dom": "^19.1.0", 25 | "react-router-dom": "^7.6.1" 26 | }, 27 | "devDependencies": { 28 | "@eslint/js": "^9.25.0", 29 | "@types/node": "^22.15.29", 30 | "@types/react": "^19.1.2", 31 | "@types/react-dom": "^19.1.2", 32 | "@types/react-router-dom": "5", 33 | "@vitejs/plugin-react": "^4.4.1", 34 | "eslint": "^9.25.0", 35 | "eslint-plugin-react-hooks": "^5.2.0", 36 | "eslint-plugin-react-refresh": "^0.4.19", 37 | "globals": "^16.0.0", 38 | "typescript": "~5.8.3", 39 | "typescript-eslint": "^8.30.1", 40 | "vite": "^6.3.5" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /samples/apps/oauth/public/runtime.json: -------------------------------------------------------------------------------- 1 | { 2 | "applicationID": "550e8400-e29b-41d4-a716-446655440000", 3 | "flowEndpoint": "https://localhost:8090/flow" 4 | } 5 | -------------------------------------------------------------------------------- /samples/apps/oauth/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /samples/apps/oauth/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "0.1.0", 4 | "description": "Sample App Server for Thunder", 5 | "bin": "server.js", 6 | "main": "server.js", 7 | "pkg": { 8 | "assets": [ 9 | "app/**/*", 10 | "server.key", 11 | "server.cert" 12 | ], 13 | "scripts": [ 14 | "server.js" 15 | ], 16 | "outputPath": "executables" 17 | }, 18 | "scripts": { 19 | "start": "node server.js" 20 | }, 21 | "dependencies": { 22 | "express": "^4.18.2" 23 | }, 24 | "devDependencies": { 25 | "pkg": "^5.8.1" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /samples/apps/oauth/server/server.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | const express = require('express'); 20 | const path = require('path'); 21 | const https = require('https'); 22 | const fs = require('fs'); 23 | 24 | const app = express(); 25 | const PORT = process.env.PORT || 3000; 26 | 27 | // Use actual working directory to access certs 28 | const isRunningAsExecutable = process.pkg !== undefined; 29 | const certDir = isRunningAsExecutable 30 | ? path.dirname(process.execPath) 31 | : path.join(process.cwd()); 32 | 33 | const keyPath = path.join(certDir, 'server.key'); 34 | const certPath = path.join(certDir, 'server.cert'); 35 | 36 | // Serve static files from the 'dist' directory 37 | app.use(express.static(path.join(__dirname, 'app'))); 38 | 39 | // Handle SPA routing 40 | app.get('*', (req, res) => { 41 | res.sendFile(path.join(__dirname, 'app', 'index.html')); 42 | }); 43 | 44 | if (fs.existsSync(keyPath) && fs.existsSync(certPath)) { 45 | const sslOptions = { 46 | key: fs.readFileSync(keyPath), 47 | cert: fs.readFileSync(certPath), 48 | }; 49 | 50 | https.createServer(sslOptions, app).listen(PORT, () => { 51 | console.log(`✅ HTTPS server running at https://localhost:${PORT}`); 52 | console.log('Press Ctrl+C to stop the server.'); 53 | }); 54 | } else { 55 | app.listen(PORT, () => { 56 | console.log(`⚠️ HTTPS certs missing. Falling back to HTTP at http://localhost:${PORT}`); 57 | console.log('Press Ctrl+C to stop the server.'); 58 | }); 59 | } 60 | -------------------------------------------------------------------------------- /samples/apps/oauth/server/start.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | REM ---------------------------------------------------------------------------- 3 | REM Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 4 | REM 5 | REM WSO2 LLC. licenses this file to you under the Apache License, 6 | REM Version 2.0 (the "License"); you may not use this file except 7 | REM in compliance with the License. 8 | REM You may obtain a copy of the License at 9 | REM 10 | REM http://www.apache.org/licenses/LICENSE-2.0 11 | REM 12 | REM Unless required by applicable law or agreed to in writing, 13 | REM software distributed under the License is distributed on an 14 | REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | REM KIND, either express or implied. See the License for the 16 | REM specific language governing permissions and limitations 17 | REM under the License. 18 | REM ---------------------------------------------------------------------------- 19 | 20 | REM Server ports 21 | set SERVER_PORT=3000 22 | 23 | REM Kill processes using the port if any 24 | echo Checking for processes using port %SERVER_PORT%... 25 | for /f "tokens=5" %%p in ('netstat -ano ^| findstr :%SERVER_PORT%') do ( 26 | echo Found process using port %SERVER_PORT% with PID: %%p 27 | taskkill /F /PID %%p 2>NUL 28 | if not errorlevel 1 ( 29 | echo Process with PID %%p terminated successfully 30 | ) 31 | ) 32 | 33 | REM Run thunder 34 | echo [92m⚡ Starting App Server ...[0m 35 | set SERVER_PORT=%SERVER_PORT% 36 | start /B "" server.exe 37 | 38 | echo. 39 | echo [92m🚀 App Server running[0m 40 | echo [93mPress Ctrl+C to stop the server.[0m 41 | echo [93mIf Ctrl+C doesn't work, close this window and use Task Manager to end the thunder.exe process.[0m 42 | 43 | REM Keep the command window open 44 | cmd /k 45 | -------------------------------------------------------------------------------- /samples/apps/oauth/server/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # ---------------------------------------------------------------------------- 3 | # Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 4 | # 5 | # WSO2 LLC. licenses this file to you under the Apache License, 6 | # Version 2.0 (the "License"); you may not use this file except 7 | # in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | # ---------------------------------------------------------------------------- 19 | 20 | # Server port 21 | SERVER_PORT=3000 22 | 23 | set -e # Exit immediately if a command exits with a non-zero status 24 | 25 | # Kill known ports 26 | function kill_port() { 27 | local port=$1 28 | lsof -ti tcp:$port | xargs kill -9 2>/dev/null || true 29 | } 30 | 31 | # Kill ports before binding 32 | kill_port $SERVER_PORT 33 | 34 | # Run server 35 | echo "⚡ Starting App Server ..." 36 | SERVER_PORT=$SERVER_PORT ./server & 37 | NODE_PID=$! 38 | 39 | # Cleanup on Ctrl+C 40 | trap 'echo -e "\n🛑 Stopping server..."; kill $NODE_PID; exit' SIGINT 41 | 42 | # Status 43 | echo "" 44 | echo "🚀 App Server running" 45 | echo "Press Ctrl+C to stop the server." 46 | 47 | # Wait for background processes 48 | wait $NODE_PID 49 | -------------------------------------------------------------------------------- /samples/apps/oauth/src/App.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | #root { 20 | margin: 0 auto; 21 | padding: 0; 22 | } 23 | 24 | .logo { 25 | height: 6em; 26 | padding: 1.5em; 27 | will-change: filter; 28 | transition: filter 300ms; 29 | } 30 | 31 | .logo:hover { 32 | filter: drop-shadow(0 0 2em #646cffaa); 33 | } 34 | .logo.react:hover { 35 | filter: drop-shadow(0 0 2em #61dafbaa); 36 | } 37 | 38 | @keyframes logo-spin { 39 | from { 40 | transform: rotate(0deg); 41 | } 42 | to { 43 | transform: rotate(360deg); 44 | } 45 | } 46 | 47 | @media (prefers-reduced-motion: no-preference) { 48 | a:nth-of-type(2) .logo { 49 | animation: logo-spin infinite 20s linear; 50 | } 51 | } 52 | 53 | .card { 54 | padding: 2em; 55 | } 56 | 57 | .read-the-docs { 58 | color: #888; 59 | } 60 | 61 | hr { 62 | margin: 30px 0; 63 | } 64 | 65 | h1, h2, h3, h4, h5, h6 { 66 | font-weight: 500; 67 | } 68 | 69 | pre { 70 | background: #313131; 71 | color: #fefefe; 72 | padding: 20px; 73 | border-radius: 20px; 74 | text-align: left; 75 | font-size: 12px; 76 | } 77 | 78 | code { 79 | word-break: break-all; 80 | word-wrap: break-word; 81 | white-space: normal; 82 | font-size: 12px; 83 | } 84 | -------------------------------------------------------------------------------- /samples/apps/oauth/src/App.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import { Route, BrowserRouter as Router, Routes, useLocation } from 'react-router-dom'; 20 | import HomePage from './pages/HomePage'; 21 | import LoginPage from './pages/LoginPage'; 22 | import RedirectLoginPage from './pages/RedirectLoginPage'; 23 | import AuthProvider from './contexts/AuthProvider'; 24 | import useAuth from './hooks/useAuth'; 25 | import './App.css'; 26 | 27 | const App = () => { 28 | const { token } = useAuth(); 29 | const location = useLocation(); // Get the current location 30 | 31 | const renderContent = () => { 32 | if (token) { 33 | return ; 34 | } else { 35 | if (import.meta.env.VITE_REACT_APP_REDIRECT_BASED_LOGIN === "true") { 36 | return ; 37 | } else { 38 | return ; 39 | } 40 | } 41 | }; 42 | 43 | return ( 44 | 45 | 46 | 47 | ); 48 | }; 49 | 50 | const AppWrapper = () => ( 51 | 52 | 53 | 54 | 55 | 56 | ); 57 | 58 | export default AppWrapper; 59 | -------------------------------------------------------------------------------- /samples/apps/oauth/src/config.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | const response = await fetch('/runtime.json'); 20 | const runtimeConfig = await response.json(); 21 | 22 | const config = { 23 | applicationID: runtimeConfig.applicationID || import.meta.env.VITE_REACT_APP_AUTH_APP_ID, 24 | applicationsEndpoint: runtimeConfig.applicationsEndpoint || import.meta.env.VITE_REACT_APPLICATIONS_ENDPOINT, 25 | flowEndpoint: runtimeConfig.flowEndpoint || import.meta.env.VITE_REACT_APP_SERVER_FLOW_ENDPOINT, 26 | authorizationEndpoint: runtimeConfig.authorizationEndpoint || import.meta.env.VITE_REACT_APP_SERVER_AUTHORIZATION_ENDPOINT, 27 | tokenEndpoint: runtimeConfig.tokenEndpoint || import.meta.env.VITE_REACT_APP_SERVER_TOKEN_ENDPOINT, 28 | clientId: import.meta.env.VITE_REACT_APP_CLIENT_ID, 29 | clientSecret: import.meta.env.VITE_REACT_APP_CLIENT_SECRET, 30 | redirectUri: runtimeConfig.redirectUri || import.meta.env.VITE_REACT_APP_REDIRECT_URI, 31 | scope: import.meta.env.VITE_REACT_APP_SCOPE 32 | }; 33 | 34 | export default config; 35 | -------------------------------------------------------------------------------- /samples/apps/oauth/src/contexts/AuthContext.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import React, { createContext } from 'react'; 20 | 21 | /** 22 | * AuthContext provides authentication state management for the application. 23 | * It allows components to access the current authentication token and provides methods 24 | * to set and clear the token. 25 | */ 26 | type AuthContextType = { 27 | token: string | null; 28 | setToken: React.Dispatch>; 29 | clearToken: () => void; 30 | }; 31 | 32 | const AuthContext = createContext(undefined); 33 | 34 | export default AuthContext; 35 | -------------------------------------------------------------------------------- /samples/apps/oauth/src/contexts/AuthProvider.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import { useState, useEffect, useCallback } from 'react'; 20 | import type { ReactNode } from 'react'; 21 | import AuthContext from './AuthContext'; 22 | 23 | /** 24 | * AuthProvider component to manage authentication state. 25 | * 26 | * @param children - The children components to be wrapped by the AuthProvider. 27 | * @returns 28 | */ 29 | const AuthProvider = ({ children }: { children: ReactNode }) => { 30 | const [token, setToken] = useState(() => sessionStorage.getItem('authToken')); 31 | 32 | useEffect(() => { 33 | if (token === null) { 34 | sessionStorage.removeItem('authToken'); 35 | } else { 36 | sessionStorage.setItem('authToken', token); 37 | } 38 | }, [token]); 39 | 40 | const clearToken = useCallback(() => setToken(null), []); 41 | 42 | return ( 43 | 44 | {children} 45 | 46 | ); 47 | }; 48 | 49 | export default AuthProvider; 50 | -------------------------------------------------------------------------------- /samples/apps/oauth/src/hooks/useAuth.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import { useContext } from 'react'; 20 | import AuthContext from '../contexts/AuthContext'; 21 | 22 | const useAuth = () => { 23 | const context = useContext(AuthContext); 24 | if (!context) { 25 | throw new Error('useAuth must be used within an AuthProvider'); 26 | } 27 | return context; 28 | }; 29 | 30 | export default useAuth; 31 | -------------------------------------------------------------------------------- /samples/apps/oauth/src/index.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | html, 20 | body { 21 | max-width: 100vw; 22 | overflow-x: hidden; 23 | } 24 | -------------------------------------------------------------------------------- /samples/apps/oauth/src/main.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import { StrictMode } from 'react' 20 | import { createRoot } from 'react-dom/client' 21 | import './index.css' 22 | import App from './App.tsx' 23 | import ThemeProvider from './theme/ThemeProvider.tsx' 24 | 25 | createRoot(document.getElementById('root')!).render( 26 | 27 | 28 | 29 | 30 | , 31 | ) 32 | -------------------------------------------------------------------------------- /samples/apps/oauth/src/pages/ErrorPage.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import Alert from '@mui/material/Alert'; 20 | import AlertTitle from '@mui/material/AlertTitle'; 21 | import Box from '@mui/material/Box'; 22 | import Button from '@mui/material/Button'; 23 | import Typography from '@mui/material/Typography'; 24 | import Layout from '../components/Layout'; 25 | 26 | const ErrorPage = ({ errorCode, errorMessage }: { errorCode: string, errorMessage: string }) => { 27 | return ( 28 | 29 | 30 | 31 | Something didn't go as expected! 32 | 33 | {errorMessage} 34 | 35 | {errorCode !== '' && ( 36 | 37 | Error Code: {errorCode} 38 | 39 | )} 40 | 41 | 42 | 45 | 46 | 47 | 48 | ); 49 | }; 50 | 51 | export default ErrorPage; 52 | -------------------------------------------------------------------------------- /samples/apps/oauth/src/services/applicationsService.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import axios from 'axios'; 20 | import config from '../config'; 21 | 22 | const { applicationsEndpoint } = config; 23 | 24 | /** 25 | * Get applications list from the server. 26 | * 27 | * @returns A promise that resolves to the list of applications. 28 | */ 29 | export const getApplications = async () => { 30 | const headers = { 31 | 'Content-Type': 'application/json', 32 | 'Accept': 'application/json', 33 | }; 34 | 35 | try { 36 | const response = await axios.get(applicationsEndpoint, { 37 | headers, 38 | }); 39 | return response.data; 40 | } catch (error) { 41 | console.error('Error retrieving applications list:', error); 42 | throw error; 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /samples/apps/oauth/src/services/jwtService.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | const base64UrlDecode = (base64UrlString: string): string => { 20 | // Convert Base64URL → Base64 21 | let base64 = base64UrlString.replace(/-/g, '+').replace(/_/g, '/'); 22 | 23 | // Pad with `=` if necessary 24 | while (base64.length % 4 !== 0) { 25 | base64 += '='; 26 | } 27 | 28 | return atob(base64); 29 | } 30 | 31 | /** 32 | * Decodes a JWT token string into its header, payload, and signature components. 33 | * 34 | * @param token JWT token string to decode. 35 | * @returns An object containing the decoded header, payload, and signature. 36 | */ 37 | export const decodeJwt = (token: string) => { 38 | try { 39 | const [header, payload, signature] = token.split('.'); 40 | 41 | const decodedHeader = JSON.parse(base64UrlDecode(header)); 42 | const decodedPayload = JSON.parse(base64UrlDecode(payload)); 43 | return { 44 | header: decodedHeader, 45 | payload: decodedPayload, 46 | // Signature is not decoded as it's not base64-encoded JSON. 47 | signature, 48 | }; 49 | } catch (error) { 50 | console.error('Failed to decode token:', error); 51 | return null; 52 | } 53 | }; 54 | -------------------------------------------------------------------------------- /samples/apps/oauth/src/theme/ThemeProvider.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import { ThemeProvider as MUIThemeProvider } from '@mui/material/styles'; 20 | import CssBaseline from '@mui/material/CssBaseline'; 21 | import theme from './theme'; 22 | import './theme.css'; 23 | 24 | export default function ThemeProvider({ children }: { children: React.ReactNode }) { 25 | return ( 26 | 27 | 28 | {children} 29 | 30 | ); 31 | } 32 | -------------------------------------------------------------------------------- /samples/apps/oauth/src/theme/ThemeToggle.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import { useColorScheme } from '@mui/material/styles'; 20 | import Button from '@mui/material/Button'; 21 | import { DarkModeRounded, LightModeRounded, Monitor } from '@mui/icons-material'; 22 | 23 | type Mode = 'light' | 'dark' | 'system'; 24 | 25 | export default function ThemeToggle() { 26 | const { mode, setMode } = useColorScheme(); 27 | 28 | if (!mode) { 29 | return null; 30 | } 31 | 32 | const nextMode = (mode: Mode): Mode => { 33 | return mode === 'light' ? 'dark' : mode === 'dark' ? 'system' : 'light'; 34 | }; 35 | 36 | const currentMode: Mode = mode ?? 'system'; 37 | 38 | const ColorModeIcon = () => { 39 | switch (currentMode) { 40 | case 'light': 41 | return ; 42 | case 'dark': 43 | return ; 44 | default: 45 | return ; 46 | } 47 | }; 48 | 49 | return ( 50 | 53 | ); 54 | }; 55 | -------------------------------------------------------------------------------- /samples/apps/oauth/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /samples/apps/oauth/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 4 | "target": "ES2020", 5 | "useDefineForClassFields": true, 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "module": "ESNext", 8 | "skipLibCheck": true, 9 | 10 | /* Bundler mode */ 11 | "moduleResolution": "bundler", 12 | "allowImportingTsExtensions": true, 13 | "verbatimModuleSyntax": true, 14 | "moduleDetection": "force", 15 | "noEmit": true, 16 | "jsx": "react-jsx", 17 | 18 | /* Linting */ 19 | "strict": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "erasableSyntaxOnly": true, 23 | "noFallthroughCasesInSwitch": true, 24 | "noUncheckedSideEffectImports": true 25 | }, 26 | "include": ["src"] 27 | } 28 | -------------------------------------------------------------------------------- /samples/apps/oauth/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "./tsconfig.app.json" }, 5 | { "path": "./tsconfig.node.json" } 6 | ], 7 | "compilerOptions": { 8 | "jsx": "react-jsx", 9 | "types": ["node"] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /samples/apps/oauth/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 4 | "target": "ES2022", 5 | "lib": ["ES2023"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "verbatimModuleSyntax": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "erasableSyntaxOnly": true, 21 | "noFallthroughCasesInSwitch": true, 22 | "noUncheckedSideEffectImports": true 23 | }, 24 | "include": ["vite.config.ts"] 25 | } 26 | -------------------------------------------------------------------------------- /samples/apps/oauth/vite.config.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | import fs from 'fs' 20 | import { defineConfig } from 'vite' 21 | import react from '@vitejs/plugin-react' 22 | 23 | // https://vite.dev/config/ 24 | export default defineConfig({ 25 | plugins: [react()], 26 | server: { 27 | https: { 28 | key: fs.readFileSync('./server.key'), 29 | cert: fs.readFileSync('./server.cert'), 30 | }, 31 | port: 3000, 32 | host: 'localhost', 33 | }, 34 | preview: { 35 | port: 3000, 36 | host: 'localhost' 37 | }, 38 | build: { 39 | target: 'esnext', 40 | }, 41 | }) 42 | -------------------------------------------------------------------------------- /start.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | REM ---------------------------------------------------------------------------- 3 | REM Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 4 | REM 5 | REM WSO2 LLC. licenses this file to you under the Apache License, 6 | REM Version 2.0 (the "License"); you may not use this file except 7 | REM in compliance with the License. 8 | REM You may obtain a copy of the License at 9 | REM 10 | REM http://www.apache.org/licenses/LICENSE-2.0 11 | REM 12 | REM Unless required by applicable law or agreed to in writing, 13 | REM software distributed under the License is distributed on an 14 | REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | REM KIND, either express or implied. See the License for the 16 | REM specific language governing permissions and limitations 17 | REM under the License. 18 | REM ---------------------------------------------------------------------------- 19 | 20 | REM Server port 21 | set BACKEND_PORT=8090 22 | 23 | REM Kill processes using the port if any 24 | echo Checking for processes using port %BACKEND_PORT%... 25 | for /f "tokens=5" %%p in ('netstat -ano ^| findstr :%BACKEND_PORT%') do ( 26 | echo Found process using port %BACKEND_PORT% with PID: %%p 27 | taskkill /F /PID %%p 2>NUL 28 | if not errorlevel 1 ( 29 | echo Process with PID %%p terminated successfully 30 | ) 31 | ) 32 | 33 | REM Run thunder 34 | echo [92m⚡ Starting Thunder Server ...[0m 35 | set BACKEND_PORT=%BACKEND_PORT% 36 | start /B "" thunder.exe 37 | 38 | echo. 39 | echo [92m🚀 Server running[0m 40 | echo [93mPress Ctrl+C to stop the server.[0m 41 | echo [93mIf Ctrl+C doesn't work, close this window and use Task Manager to end the thunder.exe process.[0m 42 | 43 | REM Keep the command window open 44 | cmd /k 45 | -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # ---------------------------------------------------------------------------- 3 | # Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 4 | # 5 | # WSO2 LLC. licenses this file to you under the Apache License, 6 | # Version 2.0 (the "License"); you may not use this file except 7 | # in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | # ---------------------------------------------------------------------------- 19 | 20 | # Server port 21 | BACKEND_PORT=8090 22 | 23 | set -e # Exit immediately if a command exits with a non-zero status 24 | 25 | # Kill known ports 26 | function kill_port() { 27 | local port=$1 28 | lsof -ti tcp:$port | xargs kill -9 2>/dev/null || true 29 | } 30 | 31 | # Kill ports before binding 32 | kill_port $BACKEND_PORT 33 | 34 | # Run thunder 35 | echo "⚡ Starting Thunder Server ..." 36 | BACKEND_PORT=$BACKEND_PORT ./thunder & 37 | THUNDER_PID=$! 38 | 39 | # Cleanup on Ctrl+C 40 | trap 'echo -e "\n🛑 Stopping server..."; kill $THUNDER_PID; exit' SIGINT 41 | 42 | # Status 43 | echo "" 44 | echo "🚀 Server running" 45 | echo "Press Ctrl+C to stop the server." 46 | 47 | # Wait for background processes 48 | wait $THUNDER_PID 49 | -------------------------------------------------------------------------------- /tests/integration/application/model.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package application 20 | 21 | type Application struct { 22 | ID string `json:"id"` 23 | Name string `json:"name"` 24 | Description string `json:"description"` 25 | ClientID string `json:"client_id"` 26 | ClientSecret string `json:"client_secret"` 27 | CallbackURL []string `json:"callback_url"` 28 | SupportedGrantTypes []string `json:"supported_grant_types"` 29 | } 30 | 31 | func compareStringSlices(a, b []string) bool { 32 | 33 | if len(a) != len(b) { 34 | return false 35 | } 36 | for i := range a { 37 | if a[i] != b[i] { 38 | return false 39 | } 40 | } 41 | return true 42 | } 43 | 44 | func (app *Application) equals(expectedApp Application) bool { 45 | 46 | return app.ID == expectedApp.ID && app.Name == expectedApp.Name && app.Description == expectedApp.Description && 47 | app.ClientID == expectedApp.ClientID && compareStringSlices(app.CallbackURL, expectedApp.CallbackURL) && 48 | compareStringSlices(app.SupportedGrantTypes, expectedApp.SupportedGrantTypes) 49 | } 50 | -------------------------------------------------------------------------------- /tests/integration/flowauthn/model.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package flowauthn 20 | 21 | import "encoding/json" 22 | 23 | type FlowStep struct { 24 | FlowID string `json:"flowId"` 25 | FlowStatus string `json:"flowStatus"` 26 | Type string `json:"type,omitempty"` 27 | Data FlowData `json:"data,omitempty"` 28 | Assertion string `json:"assertion,omitempty"` 29 | FailureReason string `json:"failureReason,omitempty"` 30 | } 31 | 32 | type FlowData struct { 33 | Inputs []InputData `json:"inputs,omitempty"` 34 | RedirectURL string `json:"redirectURL,omitempty"` 35 | AdditionalData map[string]string `json:"additionalData,omitempty"` 36 | } 37 | 38 | type InputData struct { 39 | Name string `json:"name"` 40 | Type string `json:"type"` 41 | Required bool `json:"required"` 42 | } 43 | 44 | type User struct { 45 | Id string `json:"id,omitempty"` 46 | OrganizationUnit string `json:"organizationUnit"` 47 | Type string `json:"type"` 48 | Attributes json.RawMessage `json:"attributes"` 49 | } 50 | 51 | type ErrorResponse struct { 52 | Code string `json:"code"` 53 | Message string `json:"message"` 54 | Description string `json:"description"` 55 | } 56 | -------------------------------------------------------------------------------- /tests/integration/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/asgardeo/thunder/tests/integration 2 | 3 | go 1.24.2 4 | 5 | require github.com/stretchr/testify v1.10.0 6 | 7 | require ( 8 | github.com/davecgh/go-spew v1.1.1 // indirect 9 | github.com/pmezard/go-difflib v1.0.0 // indirect 10 | gopkg.in/yaml.v3 v3.0.1 // indirect 11 | ) 12 | -------------------------------------------------------------------------------- /tests/integration/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 8 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 9 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 10 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 11 | -------------------------------------------------------------------------------- /tests/integration/idp/model.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package idp 20 | 21 | import ( 22 | "encoding/json" 23 | ) 24 | 25 | type IDP struct { 26 | ID string `json:"id"` 27 | Name string `json:"name"` // Display name 28 | Description string `json:"description"` // Description shown in UI 29 | ClientID string `json:"client_id"` // OAuth client ID 30 | ClientSecret string `json:"client_secret"` // OAuth client secret 31 | RedirectURI string `json:"redirect_uri"` // OAuth redirect URI 32 | Scopes json.RawMessage `json:"scopes"` // JSON format scopes 33 | } 34 | 35 | func compareStringSlices(a, b []string) bool { 36 | 37 | if len(a) != len(b) { 38 | return false 39 | } 40 | for i := range a { 41 | if a[i] != b[i] { 42 | return false 43 | } 44 | } 45 | return true 46 | } 47 | 48 | // compare and validate whether two IdPs have equal content 49 | func (idp *IDP) equals(expectedIdp IDP) bool { 50 | if idp.ID != expectedIdp.ID || idp.Name != expectedIdp.Name || idp.Description != expectedIdp.Description || idp.ClientID != expectedIdp.ClientID || idp.ClientSecret != expectedIdp.ClientSecret || idp.RedirectURI != expectedIdp.RedirectURI { 51 | return false 52 | } 53 | 54 | // Compare the Scopes JSON 55 | var scopes1, scopes2 []string 56 | if err := json.Unmarshal(idp.Scopes, &scopes1); err != nil { 57 | return false 58 | } 59 | if err := json.Unmarshal(expectedIdp.Scopes, &scopes2); err != nil { 60 | return false 61 | } 62 | 63 | return compareStringSlices(scopes1, scopes2) 64 | } 65 | -------------------------------------------------------------------------------- /tests/integration/resources/dbscripts/runtimedb/sqlite.sql: -------------------------------------------------------------------------------- 1 | -- Table to store OAuth2 authorization codes. 2 | CREATE TABLE IDN_OAUTH2_AUTHZ_CODE ( 3 | ID INTEGER PRIMARY KEY AUTOINCREMENT, 4 | CODE_ID VARCHAR(36) UNIQUE NOT NULL, 5 | AUTHORIZATION_CODE VARCHAR(500) NOT NULL, 6 | CONSUMER_KEY VARCHAR(255) NOT NULL, 7 | CALLBACK_URL VARCHAR(500), 8 | AUTHZ_USER VARCHAR(255) NOT NULL, 9 | TIME_CREATED DATETIME NOT NULL, 10 | EXPIRY_TIME DATETIME NOT NULL, 11 | STATE VARCHAR(50) NOT NULL 12 | ); 13 | 14 | -- Table to store scopes associated with OAuth2 authorization codes. 15 | CREATE TABLE IDN_OAUTH2_AUTHZ_CODE_SCOPE ( 16 | ID INTEGER PRIMARY KEY AUTOINCREMENT, 17 | CODE_ID VARCHAR(36) NOT NULL REFERENCES IDN_OAUTH2_AUTHZ_CODE(CODE_ID) ON DELETE CASCADE, 18 | SCOPE VARCHAR(255) NOT NULL, 19 | UNIQUE (CODE_ID, SCOPE) 20 | ); 21 | -------------------------------------------------------------------------------- /tests/integration/resources/deployment.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | hostname: "localhost" 3 | port: 8095 4 | 5 | security: 6 | cert_file: "repository/resources/security/server.cert" 7 | key_file: "repository/resources/security/server.key" 8 | 9 | database: 10 | identity: 11 | type: "sqlite" 12 | path: "repository/database/thunderdb.db" 13 | options: "_journal_mode=WAL&_busy_timeout=60000" 14 | runtime: 15 | type: "sqlite" 16 | path: "repository/database/runtimedb.db" 17 | options: "_journal_mode=WAL&_busy_timeout=60000" 18 | 19 | user_store: 20 | default_user: 21 | username: "thor" 22 | password: "thor123" 23 | 24 | flow: 25 | graph_directory: "repository/resources/graphs/" 26 | authn: 27 | default_flow: "auth_flow_config_basic" 28 | -------------------------------------------------------------------------------- /tests/integration/user/model.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). 3 | * 4 | * WSO2 LLC. licenses this file to you under the Apache License, 5 | * Version 2.0 (the "License"); you may not use this file except 6 | * in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, 12 | * software distributed under the License is distributed on an 13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | * KIND, either express or implied. See the License for the 15 | * specific language governing permissions and limitations 16 | * under the License. 17 | */ 18 | 19 | package user 20 | 21 | import ( 22 | "encoding/json" 23 | "sort" 24 | ) 25 | 26 | type User struct { 27 | Id string `json:"id"` 28 | OrganizationUnit string `json:"organizationUnit"` 29 | Type string `json:"type"` 30 | Attributes json.RawMessage `json:"attributes"` 31 | } 32 | 33 | func compareStringSlices(a, b []string) bool { 34 | 35 | if len(a) != len(b) { 36 | return false 37 | } 38 | for i := range a { 39 | if a[i] != b[i] { 40 | return false 41 | } 42 | } 43 | return true 44 | } 45 | 46 | // compare and validate whether two users have equal content 47 | func (user *User) equals(expectedUser User) bool { 48 | if user.Id != expectedUser.Id || user.OrganizationUnit != expectedUser.OrganizationUnit || user.Type != expectedUser.Type { 49 | return false 50 | } 51 | 52 | // Compare the Attributes JSON 53 | var attr1, attr2 map[string]interface{} 54 | if err := json.Unmarshal(user.Attributes, &attr1); err != nil { 55 | return false 56 | } 57 | if err := json.Unmarshal(expectedUser.Attributes, &attr2); err != nil { 58 | return false 59 | } 60 | 61 | return compareStringSlices(user.getSortedKeys(attr1), user.getSortedKeys(attr2)) 62 | } 63 | 64 | // getSortedKeys returns the sorted keys of a map for consistent comparison 65 | func (user *User) getSortedKeys(m map[string]interface{}) []string { 66 | keys := make([]string, 0, len(m)) 67 | for k := range m { 68 | keys = append(keys, k) 69 | } 70 | sort.Strings(keys) 71 | return keys 72 | } 73 | -------------------------------------------------------------------------------- /version.txt: -------------------------------------------------------------------------------- 1 | 1.0.0-m1-SNAPSHOT --------------------------------------------------------------------------------