diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 31977b3..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,71 +0,0 @@ -# Common logic -defaults: &defaults - steps: - - attach_workspace: - at: ~/ - - run: - name: Replace Auth0 test credentials - command: | - mv $AUTH0_CFG.example $AUTH0_CFG - sed -i 's/{CLIENT_ID}/'$AUTH0_TEST_CLIENT_ID'/g' $AUTH0_CFG - sed -i 's/{DOMAIN}/'$AUTH0_TEST_DOMAIN'/g' $AUTH0_CFG - sed -i 's/{CLIENT_SECRET}/'$AUTH0_TEST_CLIENT_SECRET'/g' $AUTH0_CFG - - run: - name: Build pull request - command: | - docker build -t $CIRCLE_JOB ./$SAMPLE_PATH - docker run -d -p 3000:3000 --name $CIRCLE_SHA1 --env-file ./$AUTH0_CFG $CIRCLE_JOB - background: true - - run: - name: Wait for app to be available - command: | - sleep 20 - docker run --network host --rm appropriate/curl --retry 8 --retry-connrefused -v localhost:3000 - - run: - name: Run tests - command: | - docker create --network host --name tester codeceptjs/codeceptjs codeceptjs run-multiple --all --steps - docker cp $(pwd)/lock_login_test.js tester:/tests/lock_login_test.js - docker cp $(pwd)/codecept.conf.js tester:/tests/codecept.conf.js - docker start -i tester - working_directory: scripts - - run: - name: Copy app container logs - command: | - mkdir -p /tmp/out - docker logs $CIRCLE_SHA1 > /tmp/out/app_logs.log - docker cp tester:/tests/out /tmp/ - when: on_fail - - store_artifacts: - path: /tmp/out - -# Jobs and Workflows -version: 2 -jobs: - checkout: - machine: true - steps: - - checkout - - run: git clone https://github.com/auth0-samples/spa-quickstarts-tests scripts - - persist_to_workspace: - root: ~/ - paths: - - project - - scripts - 01-login: - machine: true - environment: - - AUTH0_CFG: 01-Login/.env - - SAMPLE_PATH: 01-Login - <<: *defaults - -workflows: - version: 2 - quickstarts_login: - jobs: - - checkout: - context: Quickstart Web App Test - - 01-login: - context: Quickstart Web App Test - requires: - - checkout diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 4f4d652..0000000 --- a/.editorconfig +++ /dev/null @@ -1,15 +0,0 @@ -root = true - -[*] -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true -charset = utf-8 - -[*.js] -indent_style = space -indent_size = 2 - -[{package.json,*.yml,*.cjson}] -indent_style = space -indent_size = 2 diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index 423bd62..0000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @auth0-samples/dx-sdks-engineer diff --git a/.github/ISSUE_TEMPLATE/Bug Report.yml b/.github/ISSUE_TEMPLATE/Bug Report.yml deleted file mode 100644 index 5718be1..0000000 --- a/.github/ISSUE_TEMPLATE/Bug Report.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: 🐞 Report a bug -description: Have you found a bug or issue? Create a bug report for this sample - -body: - - type: markdown - attributes: - value: | - **Please do not report security vulnerabilities here**. The [Responsible Disclosure Program](https://auth0.com/responsible-disclosure-policy) details the procedure for disclosing security issues. - - - type: checkboxes - id: checklist - attributes: - label: Checklist - options: - - label: I have looked into the [Readme](https://github.com/auth0-samples/auth0-nodejs-webapp-sample/tree/master/01-Login#readme) and have not found a suitable solution or answer. - required: true - - label: I have searched the [issues](https://github.com/auth0-samples/auth0-nodejs-webapp-sample/issues) and have not found a suitable solution or answer. - required: true - - label: I have searched the [Auth0 Community](https://community.auth0.com) forums and have not found a suitable solution or answer. - required: true - - label: I agree to the terms within the [Auth0 Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md). - required: true - - - type: textarea - id: description - attributes: - label: Description - description: Provide a clear and concise description of the issue, including what you expected to happen. - validations: - required: true - - - type: textarea - id: reproduction - attributes: - label: Reproduction - description: Detail the steps taken to reproduce this error, and whether this issue can be reproduced consistently or if it is intermittent. - placeholder: | - 1. Step 1... - 2. Step 2... - 3. ... - validations: - required: true - - - type: textarea - id: additional-context - attributes: - label: Additional context - description: Any other relevant information you think would be useful. - validations: - required: false diff --git a/.github/ISSUE_TEMPLATE/Feature Request.yml b/.github/ISSUE_TEMPLATE/Feature Request.yml deleted file mode 100644 index 816e275..0000000 --- a/.github/ISSUE_TEMPLATE/Feature Request.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: 🧩 Feature request -description: Suggest an idea or a feature for this sample -labels: ["feature request"] - -body: - - type: checkboxes - id: checklist - attributes: - label: Checklist - options: - - label: I have looked into the [Readme](https://github.com/auth0-samples/auth0-nodejs-webapp-sample/tree/master/01-Login#readme) and have not found a suitable solution or answer. - required: true - - label: I have searched the [issues](https://github.com/auth0-samples/auth0-nodejs-webapp-sample/issues) and have not found a suitable solution or answer. - required: true - - label: I have searched the [Auth0 Community](https://community.auth0.com) forums and have not found a suitable solution or answer. - required: true - - label: I agree to the terms within the [Auth0 Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md). - required: true - - - type: textarea - id: description - attributes: - label: Describe the problem you'd like to have solved - description: A clear and concise description of what the problem is. - validations: - required: true - - - type: textarea - id: ideal-solution - attributes: - label: Describe the ideal solution - description: A clear and concise description of what you want to happen. - validations: - required: true - - - type: textarea - id: alternatives-and-workarounds - attributes: - label: Alternatives and current workarounds - description: A clear and concise description of any alternatives you've considered or any workarounds that are currently in place. - validations: - required: false - - - type: textarea - id: additional-context - attributes: - label: Additional context - description: Add any other context or screenshots about the feature request here. - validations: - required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index 8ec523f..0000000 --- a/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,5 +0,0 @@ -blank_issues_enabled: false -contact_links: - - name: 🤔 Help & Questions - url: https://community.auth0.com - about: Ask general support or usage questions in the Auth0 Community forums. diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 679a06e..0000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,9 +0,0 @@ -version: 2 -updates: - - package-ecosystem: "npm" - directory: "/01-Login" - schedule: - interval: "daily" - ignore: - - dependency-name: "*" - update-types: ["version-update:semver-major", "version-update:semver-patch"] diff --git a/.github/stale.yml b/.github/stale.yml deleted file mode 100644 index b2e13fc..0000000 --- a/.github/stale.yml +++ /dev/null @@ -1,20 +0,0 @@ -# Configuration for probot-stale - https://github.com/probot/stale - -# Number of days of inactivity before an Issue or Pull Request becomes stale -daysUntilStale: 90 - -# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. -daysUntilClose: 7 - -# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable -exemptLabels: [] - -# Set to true to ignore issues with an assignee (defaults to false) -exemptAssignees: true - -# Label to use when marking as stale -staleLabel: closed:stale - -# Comment to post when marking as stale. Set to `false` to disable -markComment: > - This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you have not received a response for our team (apologies for the delay) and this is still a blocker, please reply with additional information or just a ping. Thank you for your contribution! 🙇‍♂️ \ No newline at end of file diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml deleted file mode 100644 index 916745e..0000000 --- a/.github/workflows/semgrep.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Semgrep - -on: - pull_request: {} - - push: - branches: ["master", "main"] - - schedule: - - cron: '30 0 1,15 * *' - -jobs: - semgrep: - name: Scan - runs-on: ubuntu-latest - container: - image: returntocorp/semgrep - # Skip any PR created by dependabot to avoid permission issues - if: (github.actor != 'dependabot[bot]') - steps: - - uses: actions/checkout@v3 - - - run: semgrep ci - env: - SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} diff --git a/01-Login/.dockerignore b/01-Login/.dockerignore deleted file mode 100644 index 6ab53dc..0000000 --- a/01-Login/.dockerignore +++ /dev/null @@ -1,6 +0,0 @@ -package-lock.json -node_modules -.gitignore -.env.example -exce.sh -exec.ps1 diff --git a/01-Login/.env.example b/01-Login/.env.example deleted file mode 100644 index 52a1949..0000000 --- a/01-Login/.env.example +++ /dev/null @@ -1,3 +0,0 @@ -AUTH0_CLIENT_ID={CLIENT_ID} -AUTH0_DOMAIN={DOMAIN} -AUTH0_CLIENT_SECRET={CLIENT_SECRET} \ No newline at end of file diff --git a/01-Login/.eslintrc b/01-Login/.eslintrc deleted file mode 100644 index 60bcc4d..0000000 --- a/01-Login/.eslintrc +++ /dev/null @@ -1,192 +0,0 @@ -{ - "parserOptions": { - "ecmaVersion": 8, - "ecmaFeatures": { - "experimentalObjectRestSpread": true, - "jsx": true - }, - "sourceType": "module" - }, - - "env": { - "es6": true, - "node": true, - "mocha": true - }, - - "plugins": [ - "import", - "node", - "promise", - "standard" - ], - - "globals": { - "document": false, - "navigator": false, - "window": false - }, - - "rules": { - "accessor-pairs": "error", - "arrow-spacing": ["error", { "before": true, "after": true }], - "block-spacing": ["error", "always"], - "brace-style": ["error", "1tbs", { "allowSingleLine": true }], - "camelcase": ["error", { "properties": "never" }], - "comma-dangle": ["error", { - "arrays": "never", - "objects": "never", - "imports": "never", - "exports": "never", - "functions": "never" - }], - "comma-spacing": ["error", { "before": false, "after": true }], - "comma-style": ["error", "last"], - "constructor-super": "error", - "curly": ["error", "multi-line"], - "dot-location": ["error", "property"], - "eol-last": "error", - "eqeqeq": ["error", "always", { "null": "ignore" }], - "func-call-spacing": ["error", "never"], - "generator-star-spacing": ["error", { "before": true, "after": true }], - "handle-callback-err": ["error", "^(err|error)$" ], - "indent": ["error", 2, { "SwitchCase": 1 }], - "key-spacing": ["error", { "beforeColon": false, "afterColon": true }], - "keyword-spacing": ["error", { "before": true, "after": true }], - "new-cap": ["error", { "newIsCap": true, "capIsNew": false }], - "new-parens": "error", - "no-array-constructor": "error", - "no-caller": "error", - "no-class-assign": "error", - "no-compare-neg-zero": "error", - "no-cond-assign": "error", - "no-const-assign": "error", - "no-constant-condition": ["error", { "checkLoops": false }], - "no-control-regex": "error", - "no-debugger": "error", - "no-delete-var": "error", - "no-dupe-args": "error", - "no-dupe-class-members": "error", - "no-dupe-keys": "error", - "no-duplicate-case": "error", - "no-empty-character-class": "error", - "no-empty-pattern": "error", - "no-eval": "error", - "no-ex-assign": "error", - "no-extend-native": "error", - "no-extra-bind": "error", - "no-extra-boolean-cast": "error", - "no-extra-parens": ["error", "functions"], - "no-fallthrough": "error", - "no-floating-decimal": "error", - "no-func-assign": "error", - "no-global-assign": "error", - "no-implied-eval": "error", - "no-inner-declarations": ["error", "functions"], - "no-invalid-regexp": "error", - "no-irregular-whitespace": "error", - "no-iterator": "error", - "no-label-var": "error", - "no-labels": ["error", { "allowLoop": false, "allowSwitch": false }], - "no-lone-blocks": "error", - "no-mixed-operators": ["error", { - "groups": [ - ["==", "!=", "===", "!==", ">", ">=", "<", "<="], - ["&&", "||"], - ["in", "instanceof"] - ], - "allowSamePrecedence": true - }], - "no-mixed-spaces-and-tabs": "error", - "no-multi-spaces": "error", - "no-multi-str": "error", - "no-multiple-empty-lines": ["error", { "max": 1, "maxEOF": 0 }], - "no-negated-in-lhs": "error", - "no-new": "error", - "no-new-func": "error", - "no-new-object": "error", - "no-new-require": "error", - "no-new-symbol": "error", - "no-new-wrappers": "error", - "no-obj-calls": "error", - "no-octal": "error", - "no-octal-escape": "error", - "no-path-concat": "error", - "no-proto": "error", - "no-redeclare": "error", - "no-regex-spaces": "error", - "no-return-assign": ["error", "except-parens"], - "no-return-await": "error", - "no-self-assign": "error", - "no-self-compare": "error", - "no-sequences": "error", - "no-shadow-restricted-names": "error", - "no-sparse-arrays": "error", - "no-tabs": "error", - "no-template-curly-in-string": "error", - "no-this-before-super": "error", - "no-throw-literal": "error", - "no-trailing-spaces": "error", - "no-undef": "error", - "no-undef-init": "error", - "no-unexpected-multiline": "error", - "no-unmodified-loop-condition": "error", - "no-unneeded-ternary": ["error", { "defaultAssignment": false }], - "no-unreachable": "error", - "no-unsafe-finally": "error", - "no-unsafe-negation": "error", - "no-unused-expressions": ["error", { "allowShortCircuit": true, "allowTernary": true, "allowTaggedTemplates": true }], - "no-unused-vars": ["error", { "vars": "all", "args": "none", "ignoreRestSiblings": true }], - "no-use-before-define": ["error", { "functions": false, "classes": false, "variables": false }], - "no-useless-call": "error", - "no-useless-computed-key": "error", - "no-useless-constructor": "error", - "no-useless-escape": "error", - "no-useless-rename": "error", - "no-useless-return": "error", - "no-whitespace-before-property": "error", - "no-with": "error", - "object-property-newline": ["error", { "allowMultiplePropertiesPerLine": true }], - "one-var": ["error", { "initialized": "never" }], - "operator-linebreak": ["error", "after", { "overrides": { "?": "before", ":": "before" } }], - "padded-blocks": ["error", { "blocks": "never", "switches": "never", "classes": "never" }], - "prefer-promise-reject-errors": "error", - "quotes": ["error", "single", { "avoidEscape": true, "allowTemplateLiterals": true }], - "rest-spread-spacing": ["error", "never"], - "semi": ["error", "always"], - "semi-spacing": ["error", { "before": false, "after": true }], - "space-before-blocks": ["error", "always"], - "space-before-function-paren": ["error", "always"], - "space-in-parens": ["error", "never"], - "space-infix-ops": "error", - "space-unary-ops": ["error", { "words": true, "nonwords": false }], - "spaced-comment": ["error", "always", { - "line": { "markers": ["*package", "!", "/", ",", "="] }, - "block": { "balanced": true, "markers": ["*package", "!", ",", ":", "::", "flow-include"], "exceptions": ["*"] } - }], - "symbol-description": "error", - "template-curly-spacing": ["error", "never"], - "template-tag-spacing": ["error", "never"], - "unicode-bom": ["error", "never"], - "use-isnan": "error", - "valid-typeof": ["error", { "requireStringLiterals": true }], - "wrap-iife": ["error", "any", { "functionPrototypeMethods": true }], - "yield-star-spacing": ["error", "both"], - "yoda": ["error", "never"], - - "import/export": "error", - "import/first": "error", - "import/no-duplicates": "error", - "import/no-webpack-loader-syntax": "error", - - "node/no-deprecated-api": "error", - "node/process-exit-as-throw": "error", - - "promise/param-names": "error", - - "standard/array-bracket-even-spacing": ["error", "either"], - "standard/computed-property-even-spacing": ["error", "even"], - "standard/no-callback-literal": "error", - "standard/object-curly-even-spacing": ["error", "either"] - } -} diff --git a/01-Login/.gitignore b/01-Login/.gitignore deleted file mode 100644 index 071a8e6..0000000 --- a/01-Login/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules/ -.env -npm-debug.log diff --git a/01-Login/Dockerfile b/01-Login/Dockerfile deleted file mode 100644 index 758081f..0000000 --- a/01-Login/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM node:20-alpine - -WORKDIR /home/app - -ADD package.json /home/app -RUN npm install -ADD . /home/app - -CMD ["npm", "start"] - -EXPOSE 3000 diff --git a/01-Login/README.md b/01-Login/README.md deleted file mode 100644 index 56fe16d..0000000 --- a/01-Login/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# 01-Login - -## Running the Sample - -Install the dependencies. - -```bash -npm install -``` - -Rename `.env.example` to `.env` and replace the values for `AUTH0_CLIENT_ID`, `AUTH0_DOMAIN`, and `AUTH0_CLIENT_SECRET` with your Auth0 credentials. If you don't yet have an Auth0 account, [sign up](https://auth0.com/signup) for free. - -```bash -# copy configuration and replace with your own -cp .env.example .env -``` - -If you're using a hosting provider that uses a proxy in front of Node.js, comment in the `trust proxy` configuration in [app.js](https://github.com/auth0-samples/auth0-nodejs-webapp-sample/blob/812bb41fa655a1178f6a33ba54b0aee2397b1917/01-Login/app.js#L63-L70). This is a [`express-session` configuration setting](https://www.npmjs.com/package/express-session#cookiesecure) that allows for trusting this first proxy. - -Run the app. - -```bash -npm start -``` - -The app will be served at `localhost:3000`. - -## Running the Sample With Docker - -In order to run the example with docker you need to have `docker` installed. - -You also need to set the environment variables as explained [previously](#running-the-sample). - -Execute in command line `sh exec.sh` to run the Docker in Linux, or `.\exec.ps1` to run the Docker in Windows. - -## What is Auth0? - -Auth0 helps you to: - -* Add authentication with [multiple authentication sources](https://auth0.com/docs/identityproviders), either social like **Google, Facebook, Microsoft Account, LinkedIn, GitHub, Twitter, Box, Salesforce, among others**, or enterprise identity systems like **Windows Azure AD, Google Apps, Active Directory, ADFS or any SAML Identity Provider**. -* Add authentication through more traditional **[username/password databases](https://auth0.com/docs/mysql-connection-tutorial)**. -* Add support for **[linking different user accounts](https://auth0.com/docs/link-accounts)** with the same user. -* Support for generating signed [Json Web Tokens](https://auth0.com/docs/jwt) to call your APIs and **flow the user identity** securely. -* Analytics of how, when and where users are logging in. -* Pull data from other sources and add it to the user profile, through [JavaScript rules](https://auth0.com/docs/rules). - -## Create a free account in Auth0 - -1. Go to [Auth0](https://auth0.com) and click Sign Up. -2. Use Google, GitHub or Microsoft Account to login. - -## Issue Reporting - -If you have found a bug or if you have a feature request, please report them at this repository issues section. Please do not report security vulnerabilities on the public GitHub issue tracker. The [Responsible Disclosure Program](https://auth0.com/whitehat) details the procedure for disclosing security issues. - -## Author - -[Auth0](https://auth0.com) - -## License - -This project is licensed under the MIT license. See the [LICENSE](LICENSE) file for more info. diff --git a/01-Login/app.js b/01-Login/app.js deleted file mode 100644 index 3a2b4ec..0000000 --- a/01-Login/app.js +++ /dev/null @@ -1,130 +0,0 @@ -var express = require('express'); -var path = require('path'); -var logger = require('morgan'); -var cookieParser = require('cookie-parser'); -var session = require('express-session'); -var dotenv = require('dotenv'); -var passport = require('passport'); -var Auth0Strategy = require('passport-auth0'); -var flash = require('connect-flash'); -var userInViews = require('./lib/middleware/userInViews'); -var authRouter = require('./routes/auth'); -var indexRouter = require('./routes/index'); -var usersRouter = require('./routes/users'); - -dotenv.config(); - -// Configure Passport to use Auth0 -var strategy = new Auth0Strategy( - { - domain: process.env.AUTH0_DOMAIN, - clientID: process.env.AUTH0_CLIENT_ID, - clientSecret: process.env.AUTH0_CLIENT_SECRET, - callbackURL: - process.env.AUTH0_CALLBACK_URL || 'http://localhost:3000/callback' - }, - function (accessToken, refreshToken, extraParams, profile, done) { - // accessToken is the token to call Auth0 API (not needed in the most cases) - // extraParams.id_token has the JSON Web Token - // profile has all the information from the user - return done(null, profile); - } -); - -passport.use(strategy); - -// You can use this section to keep a smaller payload -passport.serializeUser(function (user, done) { - done(null, user); -}); - -passport.deserializeUser(function (user, done) { - done(null, user); -}); - -const app = express(); - -// View engine setup -app.set('views', path.join(__dirname, 'views')); -app.set('view engine', 'pug'); - -app.use(logger('dev')); -app.use(cookieParser()); - -// config express-session -var sess = { - secret: 'CHANGE THIS SECRET', - cookie: {}, - resave: false, - saveUninitialized: true -}; - -if (app.get('env') === 'production') { - // If you are using a hosting provider which uses a proxy (eg. Heroku), - // comment in the following app.set configuration command - // - // Trust first proxy, to prevent "Unable to verify authorization request state." - // errors with passport-auth0. - // Ref: https://github.com/auth0/passport-auth0/issues/70#issuecomment-480771614 - // Ref: https://www.npmjs.com/package/express-session#cookiesecure - // app.set('trust proxy', 1); - - sess.cookie.secure = true; // serve secure cookies, requires https -} - -app.use(session(sess)); - -app.use(passport.initialize()); -app.use(passport.session()); -app.use(express.static(path.join(__dirname, 'public'))); - -app.use(flash()); - -// Handle auth failure error messages -app.use(function (req, res, next) { - if (req && req.query && req.query.error) { - req.flash('error', req.query.error); - } - if (req && req.query && req.query.error_description) { - req.flash('error_description', req.query.error_description); - } - next(); -}); - -app.use(userInViews()); -app.use('/', authRouter); -app.use('/', indexRouter); -app.use('/', usersRouter); - -// Catch 404 and forward to error handler -app.use(function (req, res, next) { - const err = new Error('Not Found'); - err.status = 404; - next(err); -}); - -// Error handlers - -// Development error handler -// Will print stacktrace -if (app.get('env') === 'development') { - app.use(function (err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: err - }); - }); -} - -// Production error handler -// No stacktraces leaked to user -app.use(function (err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: {} - }); -}); - -module.exports = app; diff --git a/01-Login/bin/www b/01-Login/bin/www deleted file mode 100755 index ed167f7..0000000 --- a/01-Login/bin/www +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env node - -/** - * Module dependencies. - */ - -var app = require('../app'); -var debug = require('debug')('nodejs-regular-webapp2:server'); -var http = require('http'); - -/** - * Get port from environment and store in Express. - */ - -var port = normalizePort(process.env.PORT || '3000'); -app.set('port', port); - -/** - * Create HTTP server. - */ - -var server = http.createServer(app); - -/** - * Listen on provided port, on all network interfaces. - */ - -server.listen(port); -server.on('error', onError); -server.on('listening', onListening); - -/** - * Normalize a port into a number, string, or false. - */ - -function normalizePort(val) { - var port = parseInt(val, 10); - - if (isNaN(port)) { - // named pipe - return val; - } - - if (port >= 0) { - // port number - return port; - } - - return false; -} - -/** - * Event listener for HTTP server "error" event. - */ - -function onError(error) { - if (error.syscall !== 'listen') { - throw error; - } - - var bind = typeof port === 'string' - ? 'Pipe ' + port - : 'Port ' + port; - - // handle specific listen errors with friendly messages - switch (error.code) { - case 'EACCES': - console.error(bind + ' requires elevated privileges'); - process.exit(1); - break; - case 'EADDRINUSE': - console.error(bind + ' is already in use'); - process.exit(1); - break; - default: - throw error; - } -} - -/** - * Event listener for HTTP server "listening" event. - */ - -function onListening() { - var addr = server.address(); - var bind = typeof addr === 'string' - ? 'pipe ' + addr - : 'port ' + addr.port; - debug('Listening on ' + bind); - console.log('Listening on ' + bind); -} diff --git a/01-Login/exec.ps1 b/01-Login/exec.ps1 deleted file mode 100644 index 27e7dcf..0000000 --- a/01-Login/exec.ps1 +++ /dev/null @@ -1,2 +0,0 @@ -docker build -t auth0-nodejs-webapp-01-login . -docker run --env-file .env -p 3000:3000 -it auth0-nodejs-webapp-01-login diff --git a/01-Login/exec.sh b/01-Login/exec.sh deleted file mode 100644 index d5862e0..0000000 --- a/01-Login/exec.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash -docker build -t auth0-nodejs-webapp-01-login . -docker run --env-file .env -p 3000:3000 -it auth0-nodejs-webapp-01-login diff --git a/01-Login/lib/middleware/secured.js b/01-Login/lib/middleware/secured.js deleted file mode 100644 index 37917bd..0000000 --- a/01-Login/lib/middleware/secured.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * This is an example middleware that checks if the user is logged in. - * - * If the user is not logged in, it stores the requested url in `returnTo` attribute - * and then redirects to `/login`. - * - */ -module.exports = function () { - return function secured (req, res, next) { - if (req.user) { return next(); } - req.session.returnTo = req.originalUrl; - res.redirect('/login'); - }; -}; diff --git a/01-Login/lib/middleware/userInViews.js b/01-Login/lib/middleware/userInViews.js deleted file mode 100644 index 98a1779..0000000 --- a/01-Login/lib/middleware/userInViews.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * The purpose of this middleware is to have the `user` - * object available for all views. - * - * This is important because the user is used in layout.pug. - */ -module.exports = function () { - return function (req, res, next) { - res.locals.user = req.user; - next(); - }; -}; diff --git a/01-Login/package-lock.json b/01-Login/package-lock.json deleted file mode 100644 index 723e280..0000000 --- a/01-Login/package-lock.json +++ /dev/null @@ -1,1421 +0,0 @@ -{ - "name": "auth0-nodejs-webapp-sample-new-test", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "auth0-nodejs-webapp-sample-new-test", - "version": "0.0.0", - "dependencies": { - "connect-flash": "^0.1.1", - "cookie-parser": "^1.4.6", - "debug": "~4.3.4", - "dotenv": "^16.3.0", - "express": "~4.18.2", - "express-session": "^1.17.3", - "http-errors": "~2.0.0", - "morgan": "~1.10.0", - "passport": "^0.7.0", - "passport-auth0": "^1.4.4", - "pug": "^3.0.2" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", - "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/types": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", - "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", - "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" - }, - "node_modules/assert-never": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz", - "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/axios": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz", - "integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==", - "dependencies": { - "follow-redirects": "^1.15.4", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/babel-walk": { - "version": "3.0.0-canary-5", - "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", - "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", - "dependencies": { - "@babel/types": "^7.9.6" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/base64url": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", - "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", - "dependencies": { - "safe-buffer": "5.1.2" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/basic-auth/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", - "dependencies": { - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/character-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", - "integrity": "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==", - "dependencies": { - "is-regex": "^1.0.3" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/connect-flash": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/connect-flash/-/connect-flash-0.1.1.tgz", - "integrity": "sha512-2rcfELQt/ZMP+SM/pG8PyhJRaLKp+6Hk2IUBNkEit09X+vwn3QsAL3ZbYtxUn7NVPzbMTSLRDhqe0B/eh30RYA==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/constantinople": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", - "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", - "dependencies": { - "@babel/parser": "^7.6.0", - "@babel/types": "^7.6.1" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-parser": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", - "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", - "dependencies": { - "cookie": "0.4.1", - "cookie-signature": "1.0.6" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", - "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/doctypes": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", - "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==" - }, - "node_modules/dotenv": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", - "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express-session": { - "version": "1.17.3", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz", - "integrity": "sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==", - "dependencies": { - "cookie": "0.4.2", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~2.0.0", - "on-headers": "~1.0.2", - "parseurl": "~1.3.3", - "safe-buffer": "5.2.1", - "uid-safe": "~2.1.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/express-session/node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express-session/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express-session/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/express/node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/follow-redirects": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", - "dependencies": { - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", - "dependencies": { - "get-intrinsic": "^1.2.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-expression": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", - "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", - "dependencies": { - "acorn": "^7.1.1", - "object-assign": "^4.1.1" - } - }, - "node_modules/is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/js-stringify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", - "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==" - }, - "node_modules/jstransformer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", - "integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==", - "dependencies": { - "is-promise": "^2.0.0", - "promise": "^7.0.1" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/morgan": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", - "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", - "dependencies": { - "basic-auth": "~2.0.1", - "debug": "2.6.9", - "depd": "~2.0.0", - "on-finished": "~2.3.0", - "on-headers": "~1.0.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/morgan/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/morgan/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/morgan/node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/oauth": { - "version": "0.9.15", - "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", - "integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==" - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/passport": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/passport/-/passport-0.7.0.tgz", - "integrity": "sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==", - "dependencies": { - "passport-strategy": "1.x.x", - "pause": "0.0.1", - "utils-merge": "^1.0.1" - }, - "engines": { - "node": ">= 0.4.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/jaredhanson" - } - }, - "node_modules/passport-auth0": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/passport-auth0/-/passport-auth0-1.4.4.tgz", - "integrity": "sha512-PFkjMfsfXSwgn94QCrZl2hObRHiqrAJffyeUvI8e8HqTG7MfOlyzWO3wSL5dlH+MUGR5+DQr+vtXFFu6Sx8cfg==", - "dependencies": { - "axios": "^1.6.0", - "passport-oauth": "^1.0.0", - "passport-oauth2": "^1.6.0" - } - }, - "node_modules/passport-oauth": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/passport-oauth/-/passport-oauth-1.0.0.tgz", - "integrity": "sha512-4IZNVsZbN1dkBzmEbBqUxDG8oFOIK81jqdksE3HEb/vI3ib3FMjbiZZ6MTtooyYZzmKu0BfovjvT1pdGgIq+4Q==", - "dependencies": { - "passport-oauth1": "1.x.x", - "passport-oauth2": "1.x.x" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/passport-oauth1": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/passport-oauth1/-/passport-oauth1-1.3.0.tgz", - "integrity": "sha512-8T/nX4gwKTw0PjxP1xfD0QhrydQNakzeOpZ6M5Uqdgz9/a/Ag62RmJxnZQ4LkbdXGrRehQHIAHNAu11rCP46Sw==", - "dependencies": { - "oauth": "0.9.x", - "passport-strategy": "1.x.x", - "utils-merge": "1.x.x" - }, - "engines": { - "node": ">= 0.4.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/jaredhanson" - } - }, - "node_modules/passport-oauth2": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.7.0.tgz", - "integrity": "sha512-j2gf34szdTF2Onw3+76alNnaAExlUmHvkc7cL+cmaS5NzHzDP/BvFHJruueQ9XAeNOdpI+CH+PWid8RA7KCwAQ==", - "dependencies": { - "base64url": "3.x.x", - "oauth": "0.9.x", - "passport-strategy": "1.x.x", - "uid2": "0.0.x", - "utils-merge": "1.x.x" - }, - "engines": { - "node": ">= 0.4.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/jaredhanson" - } - }, - "node_modules/passport-strategy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", - "integrity": "sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "node_modules/pause": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", - "integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==" - }, - "node_modules/promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "dependencies": { - "asap": "~2.0.3" - } - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "node_modules/pug": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.2.tgz", - "integrity": "sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==", - "dependencies": { - "pug-code-gen": "^3.0.2", - "pug-filters": "^4.0.0", - "pug-lexer": "^5.0.1", - "pug-linker": "^4.0.0", - "pug-load": "^3.0.0", - "pug-parser": "^6.0.0", - "pug-runtime": "^3.0.1", - "pug-strip-comments": "^2.0.0" - } - }, - "node_modules/pug-attrs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", - "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", - "dependencies": { - "constantinople": "^4.0.1", - "js-stringify": "^1.0.2", - "pug-runtime": "^3.0.0" - } - }, - "node_modules/pug-code-gen": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.2.tgz", - "integrity": "sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==", - "dependencies": { - "constantinople": "^4.0.1", - "doctypes": "^1.1.0", - "js-stringify": "^1.0.2", - "pug-attrs": "^3.0.0", - "pug-error": "^2.0.0", - "pug-runtime": "^3.0.0", - "void-elements": "^3.1.0", - "with": "^7.0.0" - } - }, - "node_modules/pug-error": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz", - "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==" - }, - "node_modules/pug-filters": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", - "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", - "dependencies": { - "constantinople": "^4.0.1", - "jstransformer": "1.0.0", - "pug-error": "^2.0.0", - "pug-walk": "^2.0.0", - "resolve": "^1.15.1" - } - }, - "node_modules/pug-lexer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", - "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", - "dependencies": { - "character-parser": "^2.2.0", - "is-expression": "^4.0.0", - "pug-error": "^2.0.0" - } - }, - "node_modules/pug-linker": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", - "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", - "dependencies": { - "pug-error": "^2.0.0", - "pug-walk": "^2.0.0" - } - }, - "node_modules/pug-load": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", - "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", - "dependencies": { - "object-assign": "^4.1.1", - "pug-walk": "^2.0.0" - } - }, - "node_modules/pug-parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", - "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", - "dependencies": { - "pug-error": "^2.0.0", - "token-stream": "1.0.0" - } - }, - "node_modules/pug-runtime": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", - "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==" - }, - "node_modules/pug-strip-comments": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", - "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", - "dependencies": { - "pug-error": "^2.0.0" - } - }, - "node_modules/pug-walk": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", - "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==" - }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/random-bytes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", - "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-function-length": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", - "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", - "dependencies": { - "define-data-property": "^1.1.1", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.2", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "engines": { - "node": ">=4" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/token-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", - "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==" - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/uid-safe": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", - "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", - "dependencies": { - "random-bytes": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/uid2": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.4.tgz", - "integrity": "sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==" - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/void-elements": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", - "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/with": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", - "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", - "dependencies": { - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", - "assert-never": "^1.2.1", - "babel-walk": "3.0.0-canary-5" - }, - "engines": { - "node": ">= 10.0.0" - } - } - } -} diff --git a/01-Login/package.json b/01-Login/package.json deleted file mode 100644 index a6f187c..0000000 --- a/01-Login/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "auth0-nodejs-webapp-sample-new-test", - "version": "0.0.0", - "private": true, - "scripts": { - "start": "node ./bin/www" - }, - "dependencies": { - "connect-flash": "^0.1.1", - "cookie-parser": "^1.4.6", - "debug": "~4.3.4", - "dotenv": "^16.3.0", - "express": "~4.18.2", - "express-session": "^1.17.3", - "http-errors": "~2.0.0", - "morgan": "~1.10.0", - "passport": "^0.7.0", - "passport-auth0": "^1.4.4", - "pug": "^3.0.2" - } -} diff --git a/01-Login/public/stylesheets/style.css b/01-Login/public/stylesheets/style.css deleted file mode 100644 index c17f88f..0000000 --- a/01-Login/public/stylesheets/style.css +++ /dev/null @@ -1,18 +0,0 @@ -.w3-container a { - color: #337ab7; - text-decoration: none; -} - -pre { - text-align: left; - font-family: 'Courier New', Courier, monospace; - background-color: #343f5f; - color: #fdfeff; - overflow: scroll; - border: 1px #929090 solid; - padding: 15px -} - -.w3-card-4 { - padding: 15px; -} \ No newline at end of file diff --git a/01-Login/routes/auth.js b/01-Login/routes/auth.js deleted file mode 100644 index 6664023..0000000 --- a/01-Login/routes/auth.js +++ /dev/null @@ -1,54 +0,0 @@ -var express = require('express'); -var router = express.Router(); -var passport = require('passport'); -var dotenv = require('dotenv'); -var util = require('util'); -var url = require('url'); -var querystring = require('querystring'); - -dotenv.config(); - -// Perform the login, after login Auth0 will redirect to callback -router.get('/login', passport.authenticate('auth0', { - scope: 'openid email profile' -}), function (req, res) { - res.redirect('/'); -}); - -// Perform the final stage of authentication and redirect to previously requested URL or '/user' -router.get('/callback', function (req, res, next) { - passport.authenticate('auth0', function (err, user, info) { - if (err) { return next(err); } - if (!user) { return res.redirect('/login'); } - req.logIn(user, function (err) { - if (err) { return next(err); } - const returnTo = req.session.returnTo; - delete req.session.returnTo; - res.redirect(returnTo || '/user'); - }); - })(req, res, next); -}); - -// Perform session logout and redirect to homepage -router.get('/logout', (req, res) => { - req.logout(); - - var returnTo = req.protocol + '://' + req.hostname; - var port = req.connection.localPort; - if (port !== undefined && port !== 80 && port !== 443) { - returnTo += ':' + port; - } - - var logoutURL = new url.URL( - util.format('https://%s/v2/logout', process.env.AUTH0_DOMAIN) - ); - var searchString = querystring.stringify({ - client_id: process.env.AUTH0_CLIENT_ID, - returnTo: returnTo - }); - logoutURL.search = searchString; - - res.redirect(logoutURL); -}); - -module.exports = router; diff --git a/01-Login/routes/index.js b/01-Login/routes/index.js deleted file mode 100644 index 0c69448..0000000 --- a/01-Login/routes/index.js +++ /dev/null @@ -1,9 +0,0 @@ -var express = require('express'); -var router = express.Router(); - -/* GET home page. */ -router.get('/', function (req, res, next) { - res.render('index', { title: 'Auth0 Webapp sample Nodejs' }); -}); - -module.exports = router; diff --git a/01-Login/routes/users.js b/01-Login/routes/users.js deleted file mode 100644 index 5b95fc3..0000000 --- a/01-Login/routes/users.js +++ /dev/null @@ -1,14 +0,0 @@ -var express = require('express'); -var secured = require('../lib/middleware/secured'); -var router = express.Router(); - -/* GET user profile. */ -router.get('/user', secured(), function (req, res, next) { - const { _raw, _json, ...userProfile } = req.user; - res.render('user', { - userProfile: JSON.stringify(userProfile, null, 2), - title: 'Profile page' - }); -}); - -module.exports = router; diff --git a/01-Login/views/error.pug b/01-Login/views/error.pug deleted file mode 100644 index 51ec12c..0000000 --- a/01-Login/views/error.pug +++ /dev/null @@ -1,6 +0,0 @@ -extends layout - -block content - h1= message - h2= error.status - pre #{error.stack} diff --git a/01-Login/views/failure.pug b/01-Login/views/failure.pug deleted file mode 100644 index d446b25..0000000 --- a/01-Login/views/failure.pug +++ /dev/null @@ -1,5 +0,0 @@ -extends layout - -block content - h1= error - pre #{error_description} diff --git a/01-Login/views/index.pug b/01-Login/views/index.pug deleted file mode 100644 index 25b3028..0000000 --- a/01-Login/views/index.pug +++ /dev/null @@ -1,8 +0,0 @@ -extends layout - -block content - .w3-container - if locals.user - h4 You are logged in! - else - h4 You are not logged in! Please #[a(href="/login") Log In] to continue. diff --git a/01-Login/views/layout.pug b/01-Login/views/layout.pug deleted file mode 100644 index 4042fb2..0000000 --- a/01-Login/views/layout.pug +++ /dev/null @@ -1,18 +0,0 @@ -doctype html -html - head - title= title - link(rel='stylesheet', href='/stylesheets/style.css') - link(rel='stylesheet', href='https://www.w3schools.com/w3css/4/w3.css') - link(rel='shortcut icon', href='//cdn2.auth0.com/styleguide/latest/lib/logos/img/favicon.png') - - body - nav.w3-bar.w3-border.w3-light-grey( role="navigation" ) - .w3-bar-item.w3-text-grey Auth0 - NodeJS - a(href="/").w3-bar-item.w3-button Home - if locals.user - a(href="/user" id="profileDropDown").w3-bar-item.w3-button Profile - a(id="qsLogoutBtn" href="/logout").w3-bar-item.w3-button Log Out - else - a(id="qsLoginBtn" href="/login").w3-bar-item.w3-button Log In - block content diff --git a/01-Login/views/user.pug b/01-Login/views/user.pug deleted file mode 100644 index b404c5d..0000000 --- a/01-Login/views/user.pug +++ /dev/null @@ -1,11 +0,0 @@ -extends layout - -block content - .w3-card-4 - h1 Welcome #{user.nickname} - img(src=user.picture) - h2 User profile - p This is the content of req.user. - p Note: _raw and _json properties have been ommited. - pre - code #{userProfile} diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 8dfefda..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 Auth0 Samples - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index d9f8b73..0000000 --- a/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# Auth0 Node Web App Samples - -[![CircleCI](https://circleci.com/gh/auth0-samples/auth0-nodejs-webapp-sample.svg?style=svg)](https://circleci.com/gh/auth0-samples/auth0-nodejs-webapp-sample) - -These samples demonstrate how to add authentication to a Node.js application with Auth0. Each folder contains a distinct application so that various Auth0 features can be viewed in isolation. - -## Embedded Integration Samples - -These samples use Auth0's [hosted login page](https://auth0.com/docs/hosted-pages/login) which offers the fastest, most secure, and most feature-rich way to add authentication to your app. - -For samples which demonstrate how to embed the Lock widget or a custom login form directly into your application, see the [embedded-login](https://github.com/auth0-samples/auth0-nodejs-webapp-sample/tree/embedded-login) branch. - -## What is Auth0? - -Auth0 helps you to: - -* Add authentication with [multiple authentication sources](https://auth0.com/docs/identityproviders), either social like **Google, Facebook, Microsoft Account, LinkedIn, GitHub, Twitter, Box, Salesforce, among others**, or enterprise identity systems like **Windows Azure AD, Google Apps, Active Directory, ADFS or any SAML Identity Provider**. -* Add authentication through more traditional **[username/password databases](https://auth0.com/docs/connections/database/custom-db)**. -* Add support for **[linking different user accounts](https://auth0.com/docs/users/user-account-linking)** with the same user. -* Support for generating signed [Json Web Tokens](https://auth0.com/docs/tokens/json-web-tokens) to call your APIs and **flow the user identity** securely. -* Analytics of how, when and where users are logging in. -* Pull data from other sources and add it to the user profile, through [JavaScript rules](https://auth0.com/docs/rules). - -## Create a free Auth0 account - -1. Go to [Auth0](https://auth0.com/signup) and click Sign Up. -2. Use Google, GitHub or Microsoft Account to login. - -## Issue Reporting - -If you have found a bug or if you have a feature request, please report them at this repository issues section. Please do not report security vulnerabilities on the public GitHub issue tracker. The [Responsible Disclosure Program](https://auth0.com/whitehat) details the procedure for disclosing security issues. - -## Author - -[Auth0](auth0.com) - -## License - -This project is licensed under the MIT license. See the [LICENSE](LICENSE.txt) file for more info. diff --git a/csharp/m2m.cs b/csharp/m2m.cs new file mode 100644 index 0000000..e46d7a3 --- /dev/null +++ b/csharp/m2m.cs @@ -0,0 +1,36 @@ +using System.Net.Http; +using System.Text.Json; + +var client = new HttpClient(); + +Console.WriteLine("Requesting access token from https://%AUTH0_DOMAIN%/oauth/token..."); + +var secret = Environment.GetEnvironmentVariable("AUTH0_CLIENT_SECRET"); +var tokenRes = await client.PostAsync("https://%AUTH0_DOMAIN%/oauth/token", + new StringContent( + "{\"client_id\":\"%AUTH0_CLIENT_ID%\"," + + "\"client_secret\":\"" + secret + "\"," + + "\"audience\":\"%AUTH0_AUDIENCE%\"," + + "\"scope\":\"%AUTH0_SCOPE%\"," + + "\"grant_type\":\"client_credentials\"}", + System.Text.Encoding.UTF8, "application/json")); + +tokenRes.EnsureSuccessStatusCode(); +var token = JsonDocument.Parse(await tokenRes.Content.ReadAsStringAsync()).RootElement; +var accessToken = token.GetProperty("access_token").GetString()!; +var parts = accessToken.Split('.'); +Console.WriteLine($"Access token obtained. Scopes: {token.GetProperty("scope")}. Expires in {token.GetProperty("expires_in")} seconds.\n"); +// In production, cache this token and only renew it before it expires -- +// no need to request a new one for every API call. + +Console.WriteLine("Calling API at %API_ENDPOINT%..."); +var apiReq = new HttpRequestMessage(new HttpMethod("%HTTP_METHOD%"), "%API_ENDPOINT%"); +apiReq.Headers.Add("Authorization", $"{token.GetProperty("token_type")} {accessToken}"); +var apiRes = await client.SendAsync(apiReq); +apiRes.EnsureSuccessStatusCode(); + +Console.WriteLine("API response:"); +using (var w = new Utf8JsonWriter(Console.OpenStandardOutput(), new JsonWriterOptions { Indented = true })) { + JsonDocument.Parse(await apiRes.Content.ReadAsStringAsync()).WriteTo(w); +} +Console.WriteLine($"\n\ninspect the token at https://jwt.io/#value={parts[0]}.{parts[1]}"); diff --git a/csharp/run.sh b/csharp/run.sh new file mode 100644 index 0000000..38f83ab --- /dev/null +++ b/csharp/run.sh @@ -0,0 +1 @@ +dotnet run m2m.cs diff --git a/go/m2m.go b/go/m2m.go new file mode 100644 index 0000000..5213309 --- /dev/null +++ b/go/m2m.go @@ -0,0 +1,64 @@ +package main + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "log" + "net/http" + "os" + "strings" +) + +func main() { + fmt.Println("Requesting access token from https://%AUTH0_DOMAIN%/oauth/token...") + + tokenRes, err := http.Post("https://%AUTH0_DOMAIN%/oauth/token", "application/json", strings.NewReader(`{ + "client_id": "%AUTH0_CLIENT_ID%", + "client_secret": "`+os.Getenv("AUTH0_CLIENT_SECRET")+`", + "audience": "%AUTH0_AUDIENCE%", + "scope": "%AUTH0_SCOPE%", + "grant_type": "client_credentials" + }`)) + if err != nil { + log.Fatalf("Request failed: %v", err) + } + defer tokenRes.Body.Close() + + if tokenRes.StatusCode != http.StatusOK { + body, _ := io.ReadAll(tokenRes.Body) + log.Fatalf("Failed to get token (%d): %s", tokenRes.StatusCode, body) + } + + var token map[string]interface{} + json.NewDecoder(tokenRes.Body).Decode(&token) + + fmt.Printf("Access token obtained. Scopes: %s. Expires in %.0f seconds.\n", token["scope"], token["expires_in"]) + // In production, cache this token and only renew it before it expires — + // no need to request a new one for every API call. + + fmt.Println("Calling API at %API_ENDPOINT%...") + apiReq, _ := http.NewRequest("%HTTP_METHOD%", "%API_ENDPOINT%", nil) + apiReq.Header.Set("Authorization", token["token_type"].(string)+" "+token["access_token"].(string)) + + apiRes, err := http.DefaultClient.Do(apiReq) + if err != nil { + log.Fatalf("Request failed: %v", err) + } + defer apiRes.Body.Close() + + if apiRes.StatusCode != http.StatusOK { + body, _ := io.ReadAll(apiRes.Body) + log.Fatalf("API error (%d): %s", apiRes.StatusCode, body) + } + + apiBody, _ := io.ReadAll(apiRes.Body) + var pretty bytes.Buffer + json.Indent(&pretty, apiBody, "", " ") + fmt.Println("API response:") + fmt.Println(pretty.String()) + + parts := strings.SplitN(token["access_token"].(string), ".", 3) + fmt.Printf("\ninspect the token at https://jwt.io/#value=%s.%s\n", parts[0], parts[1]) +} diff --git a/go/run.sh b/go/run.sh new file mode 100644 index 0000000..4400370 --- /dev/null +++ b/go/run.sh @@ -0,0 +1 @@ +go run m2m.go diff --git a/java/m2m.java b/java/m2m.java new file mode 100644 index 0000000..6f47f09 --- /dev/null +++ b/java/m2m.java @@ -0,0 +1,65 @@ +import java.net.*; +import java.net.http.*; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse.BodyHandlers; +import java.util.regex.*; + +public class m2m { + public static void main(String[] args) throws Exception { + System.out.println("Requesting access token from https://%AUTH0_DOMAIN%/oauth/token..."); + + var client = HttpClient.newHttpClient(); + + var tokenRes = client.send(HttpRequest.newBuilder() + .uri(URI.create("https://%AUTH0_DOMAIN%/oauth/token")) + .header("content-type", "application/json") + .POST(BodyPublishers.ofString("{" + + "\"client_id\": \"%AUTH0_CLIENT_ID%\"," + + "\"client_secret\": \"" + System.getenv("AUTH0_CLIENT_SECRET") + "\"," + + "\"audience\": \"%AUTH0_AUDIENCE%\"," + + "\"scope\": \"%AUTH0_SCOPE%\"," + + "\"grant_type\": \"client_credentials\"" + + "}")) + .build(), BodyHandlers.ofString()); + + if (tokenRes.statusCode() != 200) { + System.err.println("Failed to get token (" + tokenRes.statusCode() + "): " + tokenRes.body()); + System.exit(1); + } + + // Normally you'd use a JSON library (e.g. Jackson, Gson) to parse this. + // Regex here just to keep the quickstart dependency-free. + var m = Pattern.compile("\"access_token\"\\s*:\\s*\"([^\"]+)\"").matcher(tokenRes.body()); + if (!m.find()) { + System.err.println("No access_token in response"); + System.exit(1); + } + var accessToken = m.group(1); + + var scopeM = Pattern.compile("\"scope\"\\s*:\\s*\"([^\"]+)\"").matcher(tokenRes.body()); + var scope = scopeM.find() ? scopeM.group(1) : ""; + var expiresM = Pattern.compile("\"expires_in\"\\s*:\\s*(\\d+)").matcher(tokenRes.body()); + var expiresIn = expiresM.find() ? expiresM.group(1) : "0"; + + var parts = accessToken.split("\\."); + System.out.println("Access token obtained. Scopes: " + scope + ". Expires in " + expiresIn + " seconds.\n"); + // In production, cache this token and only renew it before it expires -- + // no need to request a new one for every API call. + + System.out.println("Calling API at %API_ENDPOINT%..."); + var apiRes = client.send(HttpRequest.newBuilder() + .uri(URI.create("%API_ENDPOINT%")) + .header("Authorization", "Bearer " + accessToken) + .method("%HTTP_METHOD%", BodyPublishers.noBody()) + .build(), BodyHandlers.ofString()); + + if (apiRes.statusCode() != 200) { + System.err.println("API error (" + apiRes.statusCode() + "): " + apiRes.body()); + System.exit(1); + } + + System.out.println("API response:"); + System.out.println(apiRes.body()); + System.out.println("\ninspect the token at https://jwt.io/#value=" + parts[0] + "." + parts[1]); + } +} diff --git a/java/run.sh b/java/run.sh new file mode 100644 index 0000000..eba6ae6 --- /dev/null +++ b/java/run.sh @@ -0,0 +1 @@ +java m2m.java diff --git a/node/m2m.js b/node/m2m.js new file mode 100644 index 0000000..49d0621 --- /dev/null +++ b/node/m2m.js @@ -0,0 +1,39 @@ +console.log("Requesting access token from https://%AUTH0_DOMAIN%/oauth/token..."); + +const tokenResponse = await fetch("https://%AUTH0_DOMAIN%/oauth/token", { + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ + client_id: "%AUTH0_CLIENT_ID%", + client_secret: process.env.AUTH0_CLIENT_SECRET, + audience: "%AUTH0_AUDIENCE%", + scope: "%AUTH0_SCOPE%", + grant_type: "client_credentials", + }), +}); + +if (!tokenResponse.ok) { + console.error(`Failed to get token (${tokenResponse.status}):`, await tokenResponse.text()); + process.exit(1); +} + +const { access_token, expires_in, scope, token_type } = await tokenResponse.json(); +const [header, payload] = access_token.split("."); +console.log(`Access token obtained. Scopes: ${scope}. Expires in ${expires_in} seconds.\n`); +// In production, cache this token and only renew it before it expires — +// no need to request a new one for every API call. + +console.log("Calling API at %API_ENDPOINT%..."); +const apiResponse = await fetch("%API_ENDPOINT%", { + method: "%HTTP_METHOD%", + headers: { authorization: `${token_type} ${access_token}` }, +}); + +if (!apiResponse.ok) { + console.error(`API error (${apiResponse.status}):`, await apiResponse.text()); + process.exit(1); +} + +console.log("API response:"); +console.log(JSON.stringify(await apiResponse.json(), null, 2)); +console.log(`\ninspect the token at https://jwt.io/#value=${header}.${payload}`); diff --git a/node/run.sh b/node/run.sh new file mode 100644 index 0000000..8aaebda --- /dev/null +++ b/node/run.sh @@ -0,0 +1 @@ +node m2m.js diff --git a/php/m2m.php b/php/m2m.php new file mode 100644 index 0000000..a8b7d4e --- /dev/null +++ b/php/m2m.php @@ -0,0 +1,34 @@ + [ + "method" => "POST", + "header" => "content-type: application/json", + "content" => json_encode([ + "client_id" => "%AUTH0_CLIENT_ID%", + "client_secret" => getenv("AUTH0_CLIENT_SECRET"), + "audience" => "%AUTH0_AUDIENCE%", + "scope" => "%AUTH0_SCOPE%", + "grant_type" => "client_credentials" + ]) + ] +])), true); + +[$header, $payload] = explode('.', $token['access_token']); +echo "Access token obtained. Scopes: {$token['scope']}. Expires in {$token['expires_in']} seconds.\n\n"; +// In production, cache this token and only renew it before it expires -- +// no need to request a new one for every API call. + +echo "Calling API at %API_ENDPOINT%...\n"; + +$apiRes = file_get_contents("%API_ENDPOINT%", false, stream_context_create([ + "http" => [ + "method" => "%HTTP_METHOD%", + "header" => "authorization: {$token['token_type']} {$token['access_token']}" + ] +])); + +echo "API response:\n" . json_encode(json_decode($apiRes), JSON_PRETTY_PRINT) . "\n"; +echo "\ninspect the token at https://jwt.io/#value={$header}.{$payload}\n"; diff --git a/php/run.sh b/php/run.sh new file mode 100644 index 0000000..442d86b --- /dev/null +++ b/php/run.sh @@ -0,0 +1 @@ +php m2m.php diff --git a/python/m2m.py b/python/m2m.py new file mode 100644 index 0000000..6fa2392 --- /dev/null +++ b/python/m2m.py @@ -0,0 +1,35 @@ +import os +import json +from urllib.request import Request, urlopen + +print("Requesting access token from https://%AUTH0_DOMAIN%/oauth/token...") + +token_res = urlopen(Request( + "https://%AUTH0_DOMAIN%/oauth/token", + headers={"content-type": "application/json"}, + data=json.dumps({ + "client_id": "%AUTH0_CLIENT_ID%", + "client_secret": os.getenv("AUTH0_CLIENT_SECRET"), + "audience": "%AUTH0_AUDIENCE%", + "scope": "%AUTH0_SCOPE%", + "grant_type": "client_credentials" + }).encode() +)) + +token = json.loads(token_res.read()) +header, payload = token["access_token"].split(".")[:2] +print(f"Access token obtained. Scopes: {token['scope']}. Expires in {token['expires_in']} seconds.\n") +# In production, cache this token and only renew it before it expires -- +# no need to request a new one for every API call. + +print("Calling API at %API_ENDPOINT%...") + +api_res = urlopen(Request( + "%API_ENDPOINT%", + method="%HTTP_METHOD%", + headers={"authorization": token["token_type"] + " " + token["access_token"]} +)) + +print("API response:") +print(json.dumps(json.loads(api_res.read().decode()), indent=2)) +print(f"\ninspect the token at https://jwt.io/#value={header}.{payload}") diff --git a/python/run.sh b/python/run.sh new file mode 100644 index 0000000..712e8d2 --- /dev/null +++ b/python/run.sh @@ -0,0 +1 @@ +python m2m.py diff --git a/quickstart/quickstart-login.yaml b/quickstart/quickstart-login.yaml index 44a3246..b4e3c2f 100644 --- a/quickstart/quickstart-login.yaml +++ b/quickstart/quickstart-login.yaml @@ -1,15 +1,17 @@ appType: "m2m" technology: "m2m" technologyLabel: "Machine-to-Machine" -defaultEnvFileName: &defaultEnvFileName ".env.local" inputs: auth0Domain: auth0ClientId: auth0ClientSecret: auth0Audience: + auth0Scope: selectedApi: apiEndpoint: + httpMethod: + default: "GET" placeholders: "%AUTH0_DOMAIN%": @@ -20,167 +22,125 @@ placeholders: inputKey: "auth0ClientSecret" "%AUTH0_AUDIENCE%": inputKey: "auth0Audience" + "%AUTH0_SCOPE%": + inputKey: "auth0Scope" "%SELECTED_API%": inputKey: "selectedApi" "%API_ENDPOINT%": inputKey: "apiEndpoint" + "%HTTP_METHOD%": + inputKey: "httpMethod" snippets: - env: &env - fileName: *defaultEnvFileName + envBash: &envBash + label: "macOS / Linux" + platform: "unix" content: | - AUTH0_DOMAIN=%AUTH0_DOMAIN% - AUTH0_CLIENT_ID=%AUTH0_CLIENT_ID% - AUTH0_CLIENT_SECRET=%AUTH0_CLIENT_SECRET% - AUTH0_AUDIENCE=%AUTH0_AUDIENCE% + export AUTH0_CLIENT_SECRET="%AUTH0_CLIENT_SECRET%" language: "bash" - curlGetToken: &curlGetToken - source: "quickstart/snippets/curl-get-token.sh" + envPowershell: &envPowershell + label: "PowerShell" + platform: "windows" + content: | + $env:AUTH0_CLIENT_SECRET="%AUTH0_CLIENT_SECRET%" language: "bash" - curlCallApi: &curlCallApi - source: "quickstart/snippets/curl-call-api.sh" + envCmd: &envCmd + label: "Windows CMD" + content: | + set AUTH0_CLIENT_SECRET=%AUTH0_CLIENT_SECRET% language: "bash" - csharpGetToken: &csharpGetToken - source: "quickstart/snippets/csharp-get-token.cs" - language: "csharp" - csharpCallApi: &csharpCallApi - source: "quickstart/snippets/csharp-call-api.cs" - language: "csharp" - goGetToken: &goGetToken - source: "quickstart/snippets/go-get-token.go" + m2mCsharp: &m2mCsharp + source: "csharp/m2m.cs" + language: "cs" + technology: "csharp" + m2mGo: &m2mGo + source: "go/m2m.go" language: "go" - goCallApi: &goCallApi - source: "quickstart/snippets/go-call-api.go" - language: "go" - javaGetToken: &javaGetToken - source: "quickstart/snippets/java-get-token.java" - language: "java" - javaCallApi: &javaCallApi - source: "quickstart/snippets/java-call-api.java" + technology: "go" + m2mJava: &m2mJava + source: "java/m2m.java" language: "java" - nodeGetToken: &nodeGetToken - source: "quickstart/snippets/node-get-token.js" + technology: "java" + m2mNode: &m2mNode + source: "node/m2m.js" language: "nodejs" - nodeCallApi: &nodeCallApi - source: "quickstart/snippets/node-call-api.js" - language: "nodejs" - phpGetToken: &phpGetToken - source: "quickstart/snippets/php-get-token.php" - language: "php" - phpCallApi: &phpCallApi - source: "quickstart/snippets/php-call-api.php" + technology: "nodejs" + m2mPhp: &m2mPhp + source: "php/m2m.php" language: "php" - pythonGetToken: &pythonGetToken - source: "quickstart/snippets/python-get-token.py" - language: "python" - pythonCallApi: &pythonCallApi - source: "quickstart/snippets/python-call-api.py" + technology: "php" + m2mPython: &m2mPython + source: "python/m2m.py" language: "python" - rubyGetToken: &rubyGetToken - source: "quickstart/snippets/ruby-get-token.rb" + technology: "python" + m2mRuby: &m2mRuby + source: "ruby/m2m.rb" language: "ruby" - rubyCallApi: &rubyCallApi - source: "quickstart/snippets/ruby-call-api.rb" - language: "ruby" - - # m2mCurl: &m2mCurl - # source: "quickstart/snippets/curl-m2m.sh" - # language: "bash" - # csharp: &m2mCsharp - # source: "quickstart/snippets/csharp-m2m.cs" - # language: "csharp" - # go: &m2mGo - # source: "quickstart/snippets/go-m2m.go" - # language: "go" - # java: &m2mJava - # source: "quickstart/snippets/java-m2m.java" - # language: "java" - # node: &m2mNode - # source: "quickstart/snippets/node-m2m.js" - # language: "nodejs" - # php: &m2mPhp - # source: "quickstart/snippets/php-m2m.php" - # language: "php" - # python: &m2mPython - # source: "quickstart/snippets/python-m2m.py" - # language: "python" - # ruby: &m2mRuby - # source: "quickstart/snippets/ruby-m2m.rb" - # language: "ruby" - -# steps: -# - title: "Configure environment variables" -# contentBlocks: -# - type: markdown -# source: "quickstart/markdown/env-config.md" -# - type: snippet -# <<: *env -# - title: "Obtaining an Access Token & Calling your API" -# contentBlocks: -# - type: markdown -# source: "quickstart/markdown/obtain-access-token.md" -# - type: markdown -# source: "quickstart/markdown/access-api.md" -# - type: snippet -# sources: -# - <<: *m2mCurl -# - <<: *m2mCsharp -# - <<: *m2mGo -# - <<: *m2mJava -# - <<: *m2mNode -# - <<: *m2mPhp -# - <<: *m2mPython -# - <<: *m2mRuby + technology: "ruby" + runCsharp: &runCsharp + source: "csharp/run.sh" + language: "bash" + technology: "csharp" + runGo: &runGo + source: "go/run.sh" + language: "bash" + technology: "go" + runJava: &runJava + source: "java/run.sh" + language: "bash" + technology: "java" + runNode: &runNode + source: "node/run.sh" + language: "bash" + technology: "nodejs" + runPhp: &runPhp + source: "php/run.sh" + language: "bash" + technology: "php" + runPython: &runPython + source: "python/run.sh" + language: "bash" + technology: "python" + runRuby: &runRuby + source: "ruby/run.sh" + language: "bash" + technology: "ruby" steps: - - title: "Configure environment variables" + - title: "Set your credentials" contentBlocks: - - type: markdown - source: "quickstart/markdown/env-config.md" - type: snippet - <<: *env - - title: "Obtaining an Access Token" + group: "os" + sources: + - <<: *envBash + - <<: *envPowershell + - <<: *envCmd + - title: "Obtaining an Access Token & Calling your API" contentBlocks: - type: markdown source: "quickstart/markdown/obtain-access-token.md" + - type: markdown + source: "quickstart/markdown/access-api.md" - type: snippet sources: - - <<: *curlGetToken - - <<: *csharpGetToken - - <<: *goGetToken - - <<: *javaGetToken - - <<: *nodeGetToken - - <<: *phpGetToken - - <<: *pythonGetToken - - <<: *rubyGetToken - - title: "Calling your API" + - <<: *m2mCsharp + - <<: *m2mGo + - <<: *m2mJava + - <<: *m2mNode + - <<: *m2mPhp + - <<: *m2mPython + - <<: *m2mRuby + - title: "Run" contentBlocks: - - type: markdown - source: "quickstart/markdown/access-api.md" - type: snippet sources: - - <<: *curlCallApi - - <<: *csharpCallApi - - <<: *goCallApi - - <<: *javaCallApi - - <<: *nodeCallApi - - <<: *phpCallApi - - <<: *pythonCallApi - - <<: *rubyCallApi - -# curl: -# - title: "Obtaining an Access Token" -# contentBlocks: -# - type: markdown -# source: "quickstart/markdown/obtain-access-token.md" -# - type: snippet -# <<: *curlGetToken -# - title: "Calling your API" -# contentBlocks: -# - type: markdown -# source: "quickstart/markdown/access-api.md" -# - type: snippet -# <<: *curlCallApi + - <<: *runCsharp + - <<: *runGo + - <<: *runJava + - <<: *runNode + - <<: *runPhp + - <<: *runPython + - <<: *runRuby nextSteps: links: @@ -188,5 +148,3 @@ nextSteps: url: "https://auth0.com/docs/get-started/onboarding/self-service-m2m" - label: "Using Machine to Machine (M2M) Authorization" url: "https://auth0.com/blog/using-m2m-authorization/" - -envSnippet: *env diff --git a/quickstart/snippets/csharp-call-api.cs b/quickstart/snippets/csharp-call-api.cs deleted file mode 100644 index 4913add..0000000 --- a/quickstart/snippets/csharp-call-api.cs +++ /dev/null @@ -1,13 +0,0 @@ -using RestSharp; - -var apiClient = new RestClient("%API_ENDPOINT%"); -var apiRequest = new RestRequest(Method.Get); -apiRequest.AddHeader("Authorization", "Bearer "); -RestResponse apiResponse = apiClient.Execute(apiRequest); - -if (!apiResponse.IsSuccessful) -{ - throw new Exception("Error calling API: " + apiResponse.Content); -} - -Console.WriteLine("Response: " + apiResponse.Content); diff --git a/quickstart/snippets/csharp-get-token.cs b/quickstart/snippets/csharp-get-token.cs deleted file mode 100644 index dc27404..0000000 --- a/quickstart/snippets/csharp-get-token.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Newtonsoft.Json; -using RestSharp; - -var client = new RestClient($"https://{Environment.GetEnvironmentVariable("AUTH0_DOMAIN")}/oauth/token"); -var request = new RestRequest(Method.Post); -var tokenRequest = new -{ - client_id = Environment.GetEnvironmentVariable("AUTH0_CLIENT_ID"), - client_secret = Environment.GetEnvironmentVariable("AUTH0_CLIENT_SECRET"), - audience = Environment.GetEnvironmentVariable("AUTH0_AUDIENCE"), - grant_type = "client_credentials" -}; - -request.AddJsonBody(tokenRequest); -RestResponse response = client.Execute(request); - -if (!response.IsSuccessful) -{ - throw new Exception("Error getting token: " + response.Content); -} - -var tokenResponse = JsonConvert.DeserializeObject(response.Content); -string accessToken = (string)tokenResponse.access_token; - -Console.WriteLine("Access Token: " + accessToken); diff --git a/quickstart/snippets/csharp-m2m.cs b/quickstart/snippets/csharp-m2m.cs deleted file mode 100644 index 7b153f3..0000000 --- a/quickstart/snippets/csharp-m2m.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Newtonsoft.Json; -using RestSharp; - -string GetAccessToken() -{ - var client = new RestClient($"https://{Environment.GetEnvironmentVariable("AUTH0_DOMAIN")}/oauth/token"); - var request = new RestRequest(Method.Post); - var tokenRequest = new - { - client_id = Environment.GetEnvironmentVariable("AUTH0_CLIENT_ID"), - client_secret = Environment.GetEnvironmentVariable("AUTH0_CLIENT_SECRET"), - audience = Environment.GetEnvironmentVariable("AUTH0_AUDIENCE"), - grant_type = "client_credentials" - }; - - request.AddJsonBody(tokenRequest); - RestResponse response = client.Execute(request); - - if (!response.IsSuccessful) - { - throw new Exception("Error getting token: " + response.Content); - } - - var tokenResponse = JsonConvert.DeserializeObject(response.Content); - return (string)tokenResponse.access_token; -} - -string CallApi(string accessToken) -{ - var apiClient = new RestClient("%API_ENDPOINT%"); - var apiRequest = new RestRequest(Method.Get); - apiRequest.AddHeader("Authorization", $"Bearer {accessToken}"); - RestResponse apiResponse = apiClient.Execute(apiRequest); - - if (!apiResponse.IsSuccessful) - { - throw new Exception("Error calling API: " + apiResponse.Content); - } - - return apiResponse.Content; -} - -var accessToken = GetAccessToken(); -var result = CallApi(accessToken); -Console.WriteLine("Response: " + result); diff --git a/quickstart/snippets/curl-call-api.sh b/quickstart/snippets/curl-call-api.sh deleted file mode 100644 index 58a3b3f..0000000 --- a/quickstart/snippets/curl-call-api.sh +++ /dev/null @@ -1,3 +0,0 @@ -curl --request GET \ - --url %API_ENDPOINT% \ - --header 'authorization: Bearer ' diff --git a/quickstart/snippets/curl-get-token.sh b/quickstart/snippets/curl-get-token.sh deleted file mode 100644 index d19eaa5..0000000 --- a/quickstart/snippets/curl-get-token.sh +++ /dev/null @@ -1,9 +0,0 @@ -curl --request POST \ - --url "https://${AUTH0_DOMAIN}/oauth/token" \ - --header 'content-type: application/json' \ - --data "{ - \"client_id\":\"${AUTH0_CLIENT_ID}\", - \"client_secret\":\"${AUTH0_CLIENT_SECRET}\", - \"audience\":\"${AUTH0_AUDIENCE}\", - \"grant_type\":\"client_credentials\" - }" diff --git a/quickstart/snippets/curl-m2m.sh b/quickstart/snippets/curl-m2m.sh deleted file mode 100644 index 1f9182a..0000000 --- a/quickstart/snippets/curl-m2m.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash - -# Get access token from Auth0 -RESPONSE=$(curl --request POST \ - --url "https://${AUTH0_DOMAIN}/oauth/token" \ - --header 'content-type: application/json' \ - --data "{ - \"client_id\":\"${AUTH0_CLIENT_ID}\", - \"client_secret\":\"${AUTH0_CLIENT_SECRET}\", - \"audience\":\"${AUTH0_AUDIENCE}\", - \"grant_type\":\"client_credentials\" - }") - -# Extract access token from response -# Note: This snippet uses jq to parse the JSON response -ACCESS_TOKEN=$(echo "$RESPONSE" | jq -r '.access_token') - -if [ -z "$ACCESS_TOKEN" ] || [ "$ACCESS_TOKEN" = "null" ]; then - echo "Error: Failed to get access token. Response: $RESPONSE" >&2 - exit 1 -fi - -# Use the access token in the API request -curl --request GET \ - --url %API_ENDPOINT% \ - --header "authorization: Bearer ${ACCESS_TOKEN}" diff --git a/quickstart/snippets/go-call-api.go b/quickstart/snippets/go-call-api.go deleted file mode 100644 index bb86411..0000000 --- a/quickstart/snippets/go-call-api.go +++ /dev/null @@ -1,22 +0,0 @@ -package main - -import ( - "fmt" - "io" - "log" - "net/http" -) - -func main() { - apiReq, _ := http.NewRequest("GET", "%API_ENDPOINT%", nil) - apiReq.Header.Add("authorization", "Bearer ") - apiRes, _ := http.DefaultClient.Do(apiReq) - defer apiRes.Body.Close() - apiBody, _ := io.ReadAll(apiRes.Body) - - if apiRes.StatusCode != http.StatusOK { - log.Fatalf("Error calling API: %s", string(apiBody)) - } - - fmt.Println("Response:", string(apiBody)) -} diff --git a/quickstart/snippets/go-get-token.go b/quickstart/snippets/go-get-token.go deleted file mode 100644 index 7350ae5..0000000 --- a/quickstart/snippets/go-get-token.go +++ /dev/null @@ -1,38 +0,0 @@ -package main - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "log" - "net/http" - "os" -) - -func main() { - url := "https://" + os.Getenv("AUTH0_DOMAIN") + "/oauth/token" - - payloadData := map[string]string{ - "client_id": os.Getenv("AUTH0_CLIENT_ID"), - "client_secret": os.Getenv("AUTH0_CLIENT_SECRET"), - "audience": os.Getenv("AUTH0_AUDIENCE"), - "grant_type": "client_credentials", - } - payloadBytes, _ := json.Marshal(payloadData) - req, _ := http.NewRequest("POST", url, bytes.NewReader(payloadBytes)) - req.Header.Add("content-type", "application/json") - - res, _ := http.DefaultClient.Do(req) - defer res.Body.Close() - body, _ := io.ReadAll(res.Body) - - var result map[string]interface{} - json.Unmarshal(body, &result) - accessToken, ok := result["access_token"].(string) - if !ok { - log.Fatalf("Error getting token: %s", string(body)) - } - - fmt.Println("Access Token:", accessToken) -} diff --git a/quickstart/snippets/go-m2m.go b/quickstart/snippets/go-m2m.go deleted file mode 100644 index 88c0ddd..0000000 --- a/quickstart/snippets/go-m2m.go +++ /dev/null @@ -1,57 +0,0 @@ -package main - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "log" - "net/http" - "os" -) - -func getAccessToken() string { - url := "https://" + os.Getenv("AUTH0_DOMAIN") + "/oauth/token" - - payloadData := map[string]string{ - "client_id": os.Getenv("AUTH0_CLIENT_ID"), - "client_secret": os.Getenv("AUTH0_CLIENT_SECRET"), - "audience": os.Getenv("AUTH0_AUDIENCE"), - "grant_type": "client_credentials", - } - payloadBytes, _ := json.Marshal(payloadData) - req, _ := http.NewRequest("POST", url, bytes.NewReader(payloadBytes)) - req.Header.Add("content-type", "application/json") - - res, _ := http.DefaultClient.Do(req) - defer res.Body.Close() - body, _ := io.ReadAll(res.Body) - - var result map[string]interface{} - json.Unmarshal(body, &result) - accessToken, ok := result["access_token"].(string) - if !ok { - log.Fatalf("Error getting token: %s", string(body)) - } - - return accessToken -} - -func callAPI(accessToken string) { - apiReq, _ := http.NewRequest("GET", "%API_ENDPOINT%", nil) - apiReq.Header.Add("authorization", "Bearer "+accessToken) - apiRes, _ := http.DefaultClient.Do(apiReq) - defer apiRes.Body.Close() - apiBody, _ := io.ReadAll(apiRes.Body) - - if apiRes.StatusCode != http.StatusOK { - log.Fatalf("Error calling API: %s", string(apiBody)) - } - - fmt.Println("Response:", string(apiBody)) -} - -func main() { - accessToken := getAccessToken() - callAPI(accessToken) -} diff --git a/quickstart/snippets/java-call-api.java b/quickstart/snippets/java-call-api.java deleted file mode 100644 index b3dd3d2..0000000 --- a/quickstart/snippets/java-call-api.java +++ /dev/null @@ -1,17 +0,0 @@ -import kong.unirest.HttpResponse; -import kong.unirest.Unirest; - -public class CallApi { - public static void main(String[] args) { - HttpResponse apiResponse = Unirest.get("%API_ENDPOINT%") - .header("authorization", "Bearer ") - .asString(); - - if (apiResponse.getStatus() != 200) { - System.err.println("Error calling API: " + apiResponse.getBody()); - return; - } - - System.out.println("Response: " + apiResponse.getBody()); - } -} diff --git a/quickstart/snippets/java-get-token.java b/quickstart/snippets/java-get-token.java deleted file mode 100644 index d34821c..0000000 --- a/quickstart/snippets/java-get-token.java +++ /dev/null @@ -1,26 +0,0 @@ -import kong.unirest.HttpResponse; -import kong.unirest.Unirest; -import org.json.JSONObject; - -public class GetToken { - public static void main(String[] args) { - JSONObject tokenRequestBody = new JSONObject() - .put("client_id", System.getenv("AUTH0_CLIENT_ID")) - .put("client_secret", System.getenv("AUTH0_CLIENT_SECRET")) - .put("audience", System.getenv("AUTH0_AUDIENCE")) - .put("grant_type", "client_credentials"); - - HttpResponse response = Unirest.post("https://" + System.getenv("AUTH0_DOMAIN") + "/oauth/token") - .header("content-type", "application/json") - .body(tokenRequestBody.toString()) - .asString(); - - if (response.getStatus() != 200) { - System.err.println("Error getting token: " + response.getBody()); - return; - } - - String accessToken = new JSONObject(response.getBody()).getString("access_token"); - System.out.println("Access Token: " + accessToken); - } -} diff --git a/quickstart/snippets/java-m2m.java b/quickstart/snippets/java-m2m.java deleted file mode 100644 index 2f9a79b..0000000 --- a/quickstart/snippets/java-m2m.java +++ /dev/null @@ -1,45 +0,0 @@ -import kong.unirest.HttpResponse; -import kong.unirest.Unirest; -import org.json.JSONObject; - -public class M2M { - public static String getAccessToken() { - JSONObject tokenRequestBody = new JSONObject() - .put("client_id", System.getenv("AUTH0_CLIENT_ID")) - .put("client_secret", System.getenv("AUTH0_CLIENT_SECRET")) - .put("audience", System.getenv("AUTH0_AUDIENCE")) - .put("grant_type", "client_credentials"); - - HttpResponse response = Unirest.post("https://" + System.getenv("AUTH0_DOMAIN") + "/oauth/token") - .header("content-type", "application/json") - .body(tokenRequestBody.toString()) - .asString(); - - if (response.getStatus() != 200) { - System.err.println("Error getting token: " + response.getBody()); - return null; - } - - return new JSONObject(response.getBody()).getString("access_token"); - } - - public static void callAPI(String accessToken) { - HttpResponse apiResponse = Unirest.get("%API_ENDPOINT%") - .header("authorization", "Bearer " + accessToken) - .asString(); - - if (apiResponse.getStatus() != 200) { - System.err.println("Error calling API: " + apiResponse.getBody()); - return; - } - - System.out.println("Response: " + apiResponse.getBody()); - } - - public static void main(String[] args) { - String accessToken = getAccessToken(); - if (accessToken != null) { - callAPI(accessToken); - } - } -} diff --git a/quickstart/snippets/node-call-api.js b/quickstart/snippets/node-call-api.js deleted file mode 100644 index 7cda293..0000000 --- a/quickstart/snippets/node-call-api.js +++ /dev/null @@ -1,18 +0,0 @@ -async function callApi() { - const apiResponse = await fetch("%API_ENDPOINT%", { - method: "GET", - headers: { - authorization: "Bearer ", - }, - }); - - if (!apiResponse.ok) { - const error = await apiResponse.text(); - throw new Error("Error calling API: " + error); - } - - const apiData = await apiResponse.json(); - console.log("Response:", apiData); -} - -callApi().catch(console.error); diff --git a/quickstart/snippets/node-get-token.js b/quickstart/snippets/node-get-token.js deleted file mode 100644 index b71bff9..0000000 --- a/quickstart/snippets/node-get-token.js +++ /dev/null @@ -1,25 +0,0 @@ -async function getToken() { - const response = await fetch( - `https://${process.env.AUTH0_DOMAIN}/oauth/token`, - { - method: "POST", - headers: { "content-type": "application/json" }, - body: JSON.stringify({ - client_id: process.env.AUTH0_CLIENT_ID, - client_secret: process.env.AUTH0_CLIENT_SECRET, - audience: process.env.AUTH0_AUDIENCE, - grant_type: "client_credentials", - }), - }, - ); - - if (!response.ok) { - const error = await response.text(); - throw new Error("Error getting token: " + error); - } - - const tokenData = await response.json(); - console.log("Access Token:", tokenData.access_token); -} - -getToken().catch(console.error); diff --git a/quickstart/snippets/node-m2m.js b/quickstart/snippets/node-m2m.js deleted file mode 100644 index 050abea..0000000 --- a/quickstart/snippets/node-m2m.js +++ /dev/null @@ -1,51 +0,0 @@ -async function getAccessToken() { - const response = await fetch( - `https://${process.env.AUTH0_DOMAIN}/oauth/token`, - { - method: "POST", - headers: { "content-type": "application/json" }, - body: JSON.stringify({ - client_id: process.env.AUTH0_CLIENT_ID, - client_secret: process.env.AUTH0_CLIENT_SECRET, - audience: process.env.AUTH0_AUDIENCE, - grant_type: "client_credentials", - }), - }, - ); - - if (!response.ok) { - const error = await response.text(); - throw new Error("Error getting token: " + error); - } - - const tokenData = await response.json(); - return tokenData.access_token; -} - -async function callAPI(accessToken) { - const apiResponse = await fetch("%API_ENDPOINT%", { - method: "GET", - headers: { - authorization: `Bearer ${accessToken}`, - }, - }); - - if (!apiResponse.ok) { - const error = await apiResponse.text(); - throw new Error("Error calling API: " + error); - } - - const apiData = await apiResponse.json(); - console.log("Response:", apiData); -} - -async function main() { - try { - const accessToken = await getAccessToken(); - await callAPI(accessToken); - } catch (error) { - console.error("Error:", error); - } -} - -main(); diff --git a/quickstart/snippets/php-call-api.php b/quickstart/snippets/php-call-api.php deleted file mode 100644 index b6b5c2e..0000000 --- a/quickstart/snippets/php-call-api.php +++ /dev/null @@ -1,29 +0,0 @@ - "%API_ENDPOINT%", - CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", - CURLOPT_MAXREDIRS => 10, - CURLOPT_TIMEOUT => 30, - CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "GET", - CURLOPT_HTTPHEADER => array( - "authorization: Bearer " - ), -)); - -$apiResponse = curl_exec($apiCurl); -$apiErr = curl_error($apiCurl); -$apiHttpCode = curl_getinfo($apiCurl, CURLINFO_HTTP_CODE); -curl_close($apiCurl); - -if ($apiErr) { - fwrite(STDERR, "cURL Error: " . $apiErr . "\n"); -} elseif ($apiHttpCode !== 200) { - fwrite(STDERR, "Error calling API: HTTP " . $apiHttpCode . " - " . $apiResponse . "\n"); -} else { - echo "Response: " . $apiResponse; -} diff --git a/quickstart/snippets/php-get-token.php b/quickstart/snippets/php-get-token.php deleted file mode 100644 index bf2b405..0000000 --- a/quickstart/snippets/php-get-token.php +++ /dev/null @@ -1,36 +0,0 @@ - "https://" . getenv("AUTH0_DOMAIN") . "/oauth/token", - CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", - CURLOPT_MAXREDIRS => 10, - CURLOPT_TIMEOUT => 30, - CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "POST", - CURLOPT_POSTFIELDS => json_encode(array( - "client_id" => getenv("AUTH0_CLIENT_ID"), - "client_secret" => getenv("AUTH0_CLIENT_SECRET"), - "audience" => getenv("AUTH0_AUDIENCE"), - "grant_type" => "client_credentials" - )), - CURLOPT_HTTPHEADER => array( - "content-type: application/json" - ), -)); - -$response = curl_exec($curl); -$err = curl_error($curl); -$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); -curl_close($curl); - -if ($err) { - fwrite(STDERR, "cURL Error: " . $err . "\n"); -} elseif ($httpCode !== 200) { - fwrite(STDERR, "Error getting token: HTTP " . $httpCode . " - " . $response . "\n"); -} else { - $accessToken = json_decode($response, true)['access_token']; - echo "Access Token: " . $accessToken; -} diff --git a/quickstart/snippets/php-m2m.php b/quickstart/snippets/php-m2m.php deleted file mode 100644 index 6addca4..0000000 --- a/quickstart/snippets/php-m2m.php +++ /dev/null @@ -1,74 +0,0 @@ - "https://" . getenv("AUTH0_DOMAIN") . "/oauth/token", - CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", - CURLOPT_MAXREDIRS => 10, - CURLOPT_TIMEOUT => 30, - CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "POST", - CURLOPT_POSTFIELDS => json_encode(array( - "client_id" => getenv("AUTH0_CLIENT_ID"), - "client_secret" => getenv("AUTH0_CLIENT_SECRET"), - "audience" => getenv("AUTH0_AUDIENCE"), - "grant_type" => "client_credentials" - )), - CURLOPT_HTTPHEADER => array( - "content-type: application/json" - ), - )); - - $response = curl_exec($curl); - $err = curl_error($curl); - $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); - curl_close($curl); - - if ($err) { - fwrite(STDERR, "cURL Error: " . $err . "\n"); - return null; - } elseif ($httpCode !== 200) { - fwrite(STDERR, "Error getting token: HTTP " . $httpCode . " - " . $response . "\n"); - return null; - } - - return json_decode($response, true)['access_token']; -} - -function callAPI($accessToken) { - $apiCurl = curl_init(); - - curl_setopt_array($apiCurl, array( - CURLOPT_URL => "%API_ENDPOINT%", - CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", - CURLOPT_MAXREDIRS => 10, - CURLOPT_TIMEOUT => 30, - CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "GET", - CURLOPT_HTTPHEADER => array( - "authorization: Bearer " . $accessToken - ), - )); - - $apiResponse = curl_exec($apiCurl); - $apiErr = curl_error($apiCurl); - $apiHttpCode = curl_getinfo($apiCurl, CURLINFO_HTTP_CODE); - curl_close($apiCurl); - - if ($apiErr) { - fwrite(STDERR, "cURL Error: " . $apiErr . "\n"); - } elseif ($apiHttpCode !== 200) { - fwrite(STDERR, "Error calling API: HTTP " . $apiHttpCode . " - " . $apiResponse . "\n"); - } else { - echo "Response: " . $apiResponse; - } -} - -$accessToken = getAccessToken(); -if ($accessToken) { - callAPI($accessToken); -} diff --git a/quickstart/snippets/python-call-api.py b/quickstart/snippets/python-call-api.py deleted file mode 100644 index 4d41124..0000000 --- a/quickstart/snippets/python-call-api.py +++ /dev/null @@ -1,12 +0,0 @@ -import requests - -api_response = requests.get( - "%API_ENDPOINT%", - headers={"authorization": "Bearer "} -) - -if not api_response.ok: - print("Error calling API:", api_response.text) - exit(1) - -print("Response:", api_response.text) diff --git a/quickstart/snippets/python-get-token.py b/quickstart/snippets/python-get-token.py deleted file mode 100644 index dd7e1ed..0000000 --- a/quickstart/snippets/python-get-token.py +++ /dev/null @@ -1,20 +0,0 @@ -import os -import requests - -response = requests.post( - f"https://{os.getenv('AUTH0_DOMAIN')}/oauth/token", - headers={"content-type": "application/json"}, - json={ - "client_id": os.getenv("AUTH0_CLIENT_ID"), - "client_secret": os.getenv("AUTH0_CLIENT_SECRET"), - "audience": os.getenv("AUTH0_AUDIENCE"), - "grant_type": "client_credentials" - } -) - -if not response.ok: - print("Error getting token:", response.text) - exit(1) - -access_token = response.json()["access_token"] -print("Access Token:", access_token) diff --git a/quickstart/snippets/python-m2m.py b/quickstart/snippets/python-m2m.py deleted file mode 100644 index afff1d9..0000000 --- a/quickstart/snippets/python-m2m.py +++ /dev/null @@ -1,35 +0,0 @@ -import os -import requests - -def get_access_token(): - response = requests.post( - f"https://{os.getenv('AUTH0_DOMAIN')}/oauth/token", - headers={"content-type": "application/json"}, - json={ - "client_id": os.getenv("AUTH0_CLIENT_ID"), - "client_secret": os.getenv("AUTH0_CLIENT_SECRET"), - "audience": os.getenv("AUTH0_AUDIENCE"), - "grant_type": "client_credentials" - } - ) - - if not response.ok: - print("Error getting token:", response.text) - exit(1) - - return response.json()["access_token"] - -def call_api(access_token): - api_response = requests.get( - "%API_ENDPOINT%", - headers={"authorization": "Bearer " + access_token} - ) - - if not api_response.ok: - print("Error calling API:", api_response.text) - exit(1) - - print("Response:", api_response.text) - -access_token = get_access_token() -call_api(access_token) diff --git a/quickstart/snippets/ruby-call-api.rb b/quickstart/snippets/ruby-call-api.rb deleted file mode 100644 index b81bd67..0000000 --- a/quickstart/snippets/ruby-call-api.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'uri' -require 'net/http' - -api_url = URI("%API_ENDPOINT%") -api_http = Net::HTTP.new(api_url.host, api_url.port) -api_request = Net::HTTP::Get.new(api_url) -api_request["authorization"] = "Bearer " -api_response = api_http.request(api_request) - -unless api_response.is_a?(Net::HTTPSuccess) - $stderr.puts "Error calling API: #{api_response.body}" - exit 1 -end - -puts "Response: #{api_response.read_body}" diff --git a/quickstart/snippets/ruby-get-token.rb b/quickstart/snippets/ruby-get-token.rb deleted file mode 100644 index e92214b..0000000 --- a/quickstart/snippets/ruby-get-token.rb +++ /dev/null @@ -1,27 +0,0 @@ -require 'uri' -require 'net/http' -require 'json' - -url = URI("https://#{ENV['AUTH0_DOMAIN']}/oauth/token") - -http = Net::HTTP.new(url.host, url.port) -http.use_ssl = true - -request = Net::HTTP::Post.new(url) -request["content-type"] = 'application/json' -request.body = { - client_id: ENV['AUTH0_CLIENT_ID'], - client_secret: ENV['AUTH0_CLIENT_SECRET'], - audience: ENV['AUTH0_AUDIENCE'], - grant_type: "client_credentials" -}.to_json - -response = http.request(request) - -unless response.is_a?(Net::HTTPSuccess) - $stderr.puts "Error getting token: #{response.body}" - exit 1 -end - -access_token = JSON.parse(response.read_body)['access_token'] -puts "Access Token: #{access_token}" diff --git a/quickstart/snippets/ruby-m2m.rb b/quickstart/snippets/ruby-m2m.rb deleted file mode 100644 index d88a24c..0000000 --- a/quickstart/snippets/ruby-m2m.rb +++ /dev/null @@ -1,46 +0,0 @@ -require 'uri' -require 'net/http' -require 'json' - -def get_access_token - url = URI("https://#{ENV['AUTH0_DOMAIN']}/oauth/token") - - http = Net::HTTP.new(url.host, url.port) - http.use_ssl = true - - request = Net::HTTP::Post.new(url) - request["content-type"] = 'application/json' - request.body = { - client_id: ENV['AUTH0_CLIENT_ID'], - client_secret: ENV['AUTH0_CLIENT_SECRET'], - audience: ENV['AUTH0_AUDIENCE'], - grant_type: "client_credentials" - }.to_json - - response = http.request(request) - - unless response.is_a?(Net::HTTPSuccess) - $stderr.puts "Error getting token: #{response.body}" - exit 1 - end - - JSON.parse(response.read_body)['access_token'] -end - -def call_api(access_token) - api_url = URI("%API_ENDPOINT%") - api_http = Net::HTTP.new(api_url.host, api_url.port) - api_request = Net::HTTP::Get.new(api_url) - api_request["authorization"] = "Bearer #{access_token}" - api_response = api_http.request(api_request) - - unless api_response.is_a?(Net::HTTPSuccess) - $stderr.puts "Error calling API: #{api_response.body}" - exit 1 - end - - puts "Response: #{api_response.read_body}" -end - -access_token = get_access_token -call_api(access_token) diff --git a/ruby/m2m.rb b/ruby/m2m.rb new file mode 100644 index 0000000..6a7d342 --- /dev/null +++ b/ruby/m2m.rb @@ -0,0 +1,28 @@ +require 'uri' +require 'net/http' +require 'json' + +puts "Requesting access token from https://%AUTH0_DOMAIN%/oauth/token..." + +token = JSON.parse(Net::HTTP.post(URI("https://%AUTH0_DOMAIN%/oauth/token"), { + client_id: "%AUTH0_CLIENT_ID%", + client_secret: ENV['AUTH0_CLIENT_SECRET'], + audience: "%AUTH0_AUDIENCE%", + scope: "%AUTH0_SCOPE%", + grant_type: "client_credentials" +}.to_json, "content-type" => "application/json").body) + +header, payload = token['access_token'].split('.')[0..1] +puts "Access token obtained. Scopes: #{token['scope']}. Expires in #{token['expires_in'].to_i} seconds.\n\n" +# In production, cache this token and only renew it before it expires -- +# no need to request a new one for every API call. + +puts "Calling API at %API_ENDPOINT%..." + +api_uri = URI("%API_ENDPOINT%") +req = Net::HTTP.const_get("%HTTP_METHOD%".capitalize).new(api_uri) +req["authorization"] = "#{token['token_type']} #{token['access_token']}" +res = Net::HTTP.start(api_uri.hostname, api_uri.port, use_ssl: true) { |http| http.request(req) } +puts "API response:" +puts JSON.pretty_generate(JSON.parse(res.body)) +puts "\ninspect the token at https://jwt.io/#value=#{header}.#{payload}" diff --git a/ruby/run.sh b/ruby/run.sh new file mode 100644 index 0000000..4dec2fd --- /dev/null +++ b/ruby/run.sh @@ -0,0 +1 @@ +ruby m2m.rb