├── .editorconfig ├── .eslintrc.json ├── .gitignore ├── LICENSE ├── README.md ├── client ├── package-lock.json ├── package.json └── src │ ├── api │ ├── auth.js │ └── client.js │ ├── components │ ├── authForm.js │ └── withAuth.js │ ├── next.config.js │ ├── pages │ ├── index.js │ ├── login.js │ ├── private-perm-required.js │ ├── private.js │ └── register.js │ ├── server.js │ └── store.js └── server ├── config ├── default.json └── production.json ├── package-lock.json ├── package.json ├── public ├── favicon.ico └── index.html ├── src ├── app.hooks.js ├── app.js ├── authentication.js ├── channels.js ├── hooks │ └── logger.js ├── index.js ├── middleware │ └── index.js ├── models │ └── users.model.js └── services │ ├── counters │ ├── counters.class.js │ ├── counters.hooks.js │ └── counters.service.js │ ├── index.js │ └── users │ ├── users.hooks.js │ └── users.service.js └── test ├── app.test.js └── services ├── counters.test.js └── users.test.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "es6": true, 4 | "node": true, 5 | "mocha": true 6 | }, 7 | "parserOptions": { 8 | "ecmaVersion": 2017 9 | }, 10 | "extends": "eslint:recommended", 11 | "rules": { 12 | "indent": [ 13 | "error", 14 | 2 15 | ], 16 | "linebreak-style": [ 17 | "error", 18 | "unix" 19 | ], 20 | "quotes": [ 21 | "error", 22 | "single" 23 | ], 24 | "semi": [ 25 | "error", 26 | "always" 27 | ] 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # Compiled binary addons (http://nodejs.org/api/addons.html) 20 | build/Release 21 | 22 | # Dependency directory 23 | # Commenting this out is preferred by some people, see 24 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 25 | node_modules 26 | 27 | # Users Environment Variables 28 | .lock-wscript 29 | 30 | # IDEs and editors (shamelessly copied from @angular/cli's .gitignore) 31 | /.idea 32 | .project 33 | .classpath 34 | .c9/ 35 | *.launch 36 | .settings/ 37 | *.sublime-workspace 38 | 39 | # IDE - VSCode 40 | .vscode/* 41 | !.vscode/settings.json 42 | !.vscode/tasks.json 43 | !.vscode/launch.json 44 | !.vscode/extensions.json 45 | 46 | ### Linux ### 47 | *~ 48 | 49 | # temporary files which can be created if a process still has a handle open of a deleted file 50 | .fuse_hidden* 51 | 52 | # KDE directory preferences 53 | .directory 54 | 55 | # Linux trash folder which might appear on any partition or disk 56 | .Trash-* 57 | 58 | # .nfs files are created when an open file is removed but is still being accessed 59 | .nfs* 60 | 61 | ### OSX ### 62 | *.DS_Store 63 | .AppleDouble 64 | .LSOverride 65 | 66 | # Icon must end with two \r 67 | Icon 68 | 69 | 70 | # Thumbnails 71 | ._* 72 | 73 | # Files that might appear in the root of a volume 74 | .DocumentRevisions-V100 75 | .fseventsd 76 | .Spotlight-V100 77 | .TemporaryItems 78 | .Trashes 79 | .VolumeIcon.icns 80 | .com.apple.timemachine.donotpresent 81 | 82 | # Directories potentially created on remote AFP share 83 | .AppleDB 84 | .AppleDesktop 85 | Network Trash Folder 86 | Temporary Items 87 | .apdisk 88 | 89 | ### Windows ### 90 | # Windows thumbnail cache files 91 | Thumbs.db 92 | ehthumbs.db 93 | ehthumbs_vista.db 94 | 95 | # Folder config file 96 | Desktop.ini 97 | 98 | # Recycle Bin used on file shares 99 | $RECYCLE.BIN/ 100 | 101 | # Windows Installer files 102 | *.cab 103 | *.msi 104 | *.msm 105 | *.msp 106 | 107 | # Windows shortcuts 108 | *.lnk 109 | 110 | # Others 111 | lib/ 112 | data/ 113 | .vscode/ 114 | .idea/ 115 | .history/ 116 | .next/ 117 | client/.gitignore 118 | 119 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Feathers 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # feathers-next 2 | 3 | This project shows how to integrate a [Next.js](https://github.com/zeit/next.js) application with a [Feathers](http://feathersjs.com) backend, including authentication (with user name/password) and Redux. 4 | 5 | ## About 6 | 7 | The project was inspired by [feathers-next-example](https://github.com/Albert-Gao/feathers-next-example) 8 | and by [this](https://github.com/hugotox/next.js/tree/canary/examples/with-cookie-auth-redux) example for the authentication part. 9 | 10 | Contrary to [feathers-next-example](https://github.com/Albert-Gao/feathers-next-example), I decided to keep the Feathers backend (the API) separated from the "server" (SSR) part of the Next.js frontend. This means that we're running two separate server (node.js) processes. 11 | 12 | This might add a (tiny) bit of overhead, but ultimately it makes the app easier to develop and maintain (and configure) because we don't mingle Feathers API backend code with Next.js server rendering code. 13 | 14 | ## Getting Started 15 | 16 | The repository contains both the backend (Feathers) and the frontend (Next.js), in two separate directories ```server``` and ```client```. 17 | 18 | To install the app (backend and frontend), open a terminal and issue the following commands: 19 | 20 | ``` 21 | # Clone the repo: 22 | git clone https://github.com/leob/feathers-next 23 | # Now make sure that "nodemon" is installed, either as a global dependency, or as a local one - 24 | # for details see the section 'Installing nodemon' 25 | # Install and run the server part: 26 | cd server 27 | npm install 28 | npm run start 29 | # Then in another terminal, install and run the client part: 30 | cd .. 31 | cd client 32 | npm install 33 | npm run dev 34 | # The command above ("npm run dev") supports hot reload, and is perfect for developing. 35 | # For production however, be sure to do a "build" and "run" as follows: 36 | npm run build 37 | npm run start 38 | # Click through the app both in 'development' and 'production' mode, and notice how the app is MUCH faster in production mode! 39 | ``` 40 | To view the app, open your browser and go to `http://localhost:3000`. 41 | You should see the home page containing Login and Register links. 42 | 43 | ## Installing `nodemon` 44 | 45 | When installing the project, right after the first step ("Cloning the repo"), you should make sure that `nodemon` is available, because this is needed for the app to run. You can do this in two ways: install `nodemon` globally, or install it locally. 46 | 47 | If you want to install `nodemon` globally (so that it's available for all your node projects), then execute this command: 48 | 49 | ``` 50 | npm install nodemon -g 51 | ``` 52 | 53 | Alternatively, if you want to install it locally, add it as a dev dependency in `package.json` by executing: 54 | 55 | ``` 56 | npm install nodemon --save-dev 57 | ``` 58 | 59 | Both methods work, so this is a matter of preference (some people dislike global dependencies). 60 | 61 | ## Using the app 62 | 63 | The home page of the app contains "Login" and "Register" links. Click on "Register", enter a user name and password of your choosing (choose anything you want, there are no restrictions) and click "Submit". You are now registered, and logged in. 64 | 65 | Click on the other links (```private``` and ```private-perm-required```) to see if they work. The ```private``` page demonstrates how to call a Feathers service which requires authentication (in the Feathers backend we've implemented a simple "counters" service which always returns the same set of data). 66 | 67 | To access the ```private-perm-required``` page, you need an "admin" user. Click ```Logout``` on the home page and then click ```Register```, and register a new user with the user name "admin". You should now be able to access the ```private-perm-required``` page. 68 | -------------------------------------------------------------------------------- /client/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "feathers-next-client", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "version": "1.0.0", 9 | "dependencies": { 10 | "@feathersjs/authentication-client": "^1.0.2", 11 | "@feathersjs/feathers": "^3.1.0", 12 | "@feathersjs/socketio-client": "^1.0.2", 13 | "cookie": "^0.7.0", 14 | "express": "^4.21.2", 15 | "next": "^14.2.21", 16 | "next-redux-wrapper": "^1.0.0", 17 | "react": "^16.2.0", 18 | "react-dom": "^16.3.3", 19 | "react-redux": "^5.0.1", 20 | "redux": "^3.6.0", 21 | "redux-devtools-extension": "^2.13.2", 22 | "redux-thunk": "^2.1.0", 23 | "socket.io-client": "^4.7.5" 24 | } 25 | }, 26 | "node_modules/@feathersjs/authentication-client": { 27 | "version": "1.0.2", 28 | "resolved": "https://registry.npmjs.org/@feathersjs/authentication-client/-/authentication-client-1.0.2.tgz", 29 | "integrity": "sha512-uZfWWMLqNkXcGi5bCuvQwLjBWvUhHtGjK4yZJh3KIHFAESBlQ4/TlqI/JRz2RuswfGfbyNtj9ARPam71YCGOpw==", 30 | "dependencies": { 31 | "@feathersjs/errors": "^3.0.0", 32 | "debug": "^3.1.0", 33 | "jwt-decode": "^2.1.0" 34 | }, 35 | "engines": { 36 | "node": ">= 6" 37 | } 38 | }, 39 | "node_modules/@feathersjs/commons": { 40 | "version": "1.4.1", 41 | "resolved": "https://registry.npmjs.org/@feathersjs/commons/-/commons-1.4.1.tgz", 42 | "integrity": "sha512-hs3Tz0JV/nwd14B9s+mv4SG+Tll9pDxqEn2wuc5CzL4I2vc1+EnwnhpOkokvQMTAdzsaxwOLoQ4y1BPm6WmMNA==", 43 | "engines": { 44 | "node": ">= 6" 45 | } 46 | }, 47 | "node_modules/@feathersjs/errors": { 48 | "version": "3.3.0", 49 | "resolved": "https://registry.npmjs.org/@feathersjs/errors/-/errors-3.3.0.tgz", 50 | "integrity": "sha512-9oYAhAj4CKIix5KITRDEzvyNJNIaqNde5lGqmrQLw4pTuyWMvx9tgBhtXPA0l8lS1KnMKw4Qf1gHo6aKrM+OyQ==", 51 | "dependencies": { 52 | "debug": "^3.1.0" 53 | }, 54 | "engines": { 55 | "node": ">= 6" 56 | } 57 | }, 58 | "node_modules/@feathersjs/feathers": { 59 | "version": "3.1.4", 60 | "resolved": "https://registry.npmjs.org/@feathersjs/feathers/-/feathers-3.1.4.tgz", 61 | "integrity": "sha512-zFT8a28SoORxxWMHLC2IUSXa3UwKBMlBl1mSLCVALk5GsmnvJpf+P/SU8TMcuzh39Uew7Dj4tZSatu71mnY9cQ==", 62 | "dependencies": { 63 | "@feathersjs/commons": "^1.4.0", 64 | "debug": "^3.1.0", 65 | "events": "^2.0.0", 66 | "uberproto": "^1.2.0" 67 | }, 68 | "engines": { 69 | "node": ">= 6" 70 | } 71 | }, 72 | "node_modules/@feathersjs/socketio-client": { 73 | "version": "1.1.0", 74 | "resolved": "https://registry.npmjs.org/@feathersjs/socketio-client/-/socketio-client-1.1.0.tgz", 75 | "integrity": "sha512-2ry9vX8qIF1Nax3G3r121Utsnj5NQbGgBG7K0M3RTJc+93Gg46BrnLVMFKue5fz2YTIOpHfHDRu1qqbddTJLXQ==", 76 | "dependencies": { 77 | "@feathersjs/transport-commons": "^4.0.0" 78 | }, 79 | "engines": { 80 | "node": ">= 6.0.0" 81 | } 82 | }, 83 | "node_modules/@feathersjs/transport-commons": { 84 | "version": "4.0.0", 85 | "resolved": "https://registry.npmjs.org/@feathersjs/transport-commons/-/transport-commons-4.0.0.tgz", 86 | "integrity": "sha512-O+kuJWpdao0Lw5Pg/65eOuMIlxu+aP9bnK9jNlxfwVdqCxw4eX3Jh8WS0WmQpfZYILk5oyhP/IUdHgSqcjaXgw==", 87 | "dependencies": { 88 | "@feathersjs/commons": "^1.4.0", 89 | "@feathersjs/errors": "^3.0.0", 90 | "debug": "^3.1.0", 91 | "lodash": "^4.17.4", 92 | "radix-router": "^3.0.1" 93 | }, 94 | "engines": { 95 | "node": ">= 6" 96 | } 97 | }, 98 | "node_modules/@next/env": { 99 | "version": "14.2.21", 100 | "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.21.tgz", 101 | "integrity": "sha512-lXcwcJd5oR01tggjWJ6SrNNYFGuOOMB9c251wUNkjCpkoXOPkDeF/15c3mnVlBqrW4JJXb2kVxDFhC4GduJt2A==" 102 | }, 103 | "node_modules/@next/swc-darwin-arm64": { 104 | "version": "14.2.21", 105 | "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.21.tgz", 106 | "integrity": "sha512-HwEjcKsXtvszXz5q5Z7wCtrHeTTDSTgAbocz45PHMUjU3fBYInfvhR+ZhavDRUYLonm53aHZbB09QtJVJj8T7g==", 107 | "cpu": [ 108 | "arm64" 109 | ], 110 | "optional": true, 111 | "os": [ 112 | "darwin" 113 | ], 114 | "engines": { 115 | "node": ">= 10" 116 | } 117 | }, 118 | "node_modules/@next/swc-darwin-x64": { 119 | "version": "14.2.21", 120 | "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.21.tgz", 121 | "integrity": "sha512-TSAA2ROgNzm4FhKbTbyJOBrsREOMVdDIltZ6aZiKvCi/v0UwFmwigBGeqXDA97TFMpR3LNNpw52CbVelkoQBxA==", 122 | "cpu": [ 123 | "x64" 124 | ], 125 | "optional": true, 126 | "os": [ 127 | "darwin" 128 | ], 129 | "engines": { 130 | "node": ">= 10" 131 | } 132 | }, 133 | "node_modules/@next/swc-linux-arm64-gnu": { 134 | "version": "14.2.21", 135 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.21.tgz", 136 | "integrity": "sha512-0Dqjn0pEUz3JG+AImpnMMW/m8hRtl1GQCNbO66V1yp6RswSTiKmnHf3pTX6xMdJYSemf3O4Q9ykiL0jymu0TuA==", 137 | "cpu": [ 138 | "arm64" 139 | ], 140 | "optional": true, 141 | "os": [ 142 | "linux" 143 | ], 144 | "engines": { 145 | "node": ">= 10" 146 | } 147 | }, 148 | "node_modules/@next/swc-linux-arm64-musl": { 149 | "version": "14.2.21", 150 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.21.tgz", 151 | "integrity": "sha512-Ggfw5qnMXldscVntwnjfaQs5GbBbjioV4B4loP+bjqNEb42fzZlAaK+ldL0jm2CTJga9LynBMhekNfV8W4+HBw==", 152 | "cpu": [ 153 | "arm64" 154 | ], 155 | "optional": true, 156 | "os": [ 157 | "linux" 158 | ], 159 | "engines": { 160 | "node": ">= 10" 161 | } 162 | }, 163 | "node_modules/@next/swc-linux-x64-gnu": { 164 | "version": "14.2.21", 165 | "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.21.tgz", 166 | "integrity": "sha512-uokj0lubN1WoSa5KKdThVPRffGyiWlm/vCc/cMkWOQHw69Qt0X1o3b2PyLLx8ANqlefILZh1EdfLRz9gVpG6tg==", 167 | "cpu": [ 168 | "x64" 169 | ], 170 | "optional": true, 171 | "os": [ 172 | "linux" 173 | ], 174 | "engines": { 175 | "node": ">= 10" 176 | } 177 | }, 178 | "node_modules/@next/swc-linux-x64-musl": { 179 | "version": "14.2.21", 180 | "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.21.tgz", 181 | "integrity": "sha512-iAEBPzWNbciah4+0yI4s7Pce6BIoxTQ0AGCkxn/UBuzJFkYyJt71MadYQkjPqCQCJAFQ26sYh7MOKdU+VQFgPg==", 182 | "cpu": [ 183 | "x64" 184 | ], 185 | "optional": true, 186 | "os": [ 187 | "linux" 188 | ], 189 | "engines": { 190 | "node": ">= 10" 191 | } 192 | }, 193 | "node_modules/@next/swc-win32-arm64-msvc": { 194 | "version": "14.2.21", 195 | "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.21.tgz", 196 | "integrity": "sha512-plykgB3vL2hB4Z32W3ktsfqyuyGAPxqwiyrAi2Mr8LlEUhNn9VgkiAl5hODSBpzIfWweX3er1f5uNpGDygfQVQ==", 197 | "cpu": [ 198 | "arm64" 199 | ], 200 | "optional": true, 201 | "os": [ 202 | "win32" 203 | ], 204 | "engines": { 205 | "node": ">= 10" 206 | } 207 | }, 208 | "node_modules/@next/swc-win32-ia32-msvc": { 209 | "version": "14.2.21", 210 | "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.21.tgz", 211 | "integrity": "sha512-w5bacz4Vxqrh06BjWgua3Yf7EMDb8iMcVhNrNx8KnJXt8t+Uu0Zg4JHLDL/T7DkTCEEfKXO/Er1fcfWxn2xfPA==", 212 | "cpu": [ 213 | "ia32" 214 | ], 215 | "optional": true, 216 | "os": [ 217 | "win32" 218 | ], 219 | "engines": { 220 | "node": ">= 10" 221 | } 222 | }, 223 | "node_modules/@next/swc-win32-x64-msvc": { 224 | "version": "14.2.21", 225 | "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.21.tgz", 226 | "integrity": "sha512-sT6+llIkzpsexGYZq8cjjthRyRGe5cJVhqh12FmlbxHqna6zsDDK8UNaV7g41T6atFHCJUPeLb3uyAwrBwy0NA==", 227 | "cpu": [ 228 | "x64" 229 | ], 230 | "optional": true, 231 | "os": [ 232 | "win32" 233 | ], 234 | "engines": { 235 | "node": ">= 10" 236 | } 237 | }, 238 | "node_modules/@socket.io/component-emitter": { 239 | "version": "3.1.2", 240 | "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", 241 | "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==" 242 | }, 243 | "node_modules/@swc/counter": { 244 | "version": "0.1.3", 245 | "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", 246 | "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==" 247 | }, 248 | "node_modules/@swc/helpers": { 249 | "version": "0.5.5", 250 | "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", 251 | "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", 252 | "dependencies": { 253 | "@swc/counter": "^0.1.3", 254 | "tslib": "^2.4.0" 255 | } 256 | }, 257 | "node_modules/accepts": { 258 | "version": "1.3.8", 259 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 260 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 261 | "dependencies": { 262 | "mime-types": "~2.1.34", 263 | "negotiator": "0.6.3" 264 | }, 265 | "engines": { 266 | "node": ">= 0.6" 267 | } 268 | }, 269 | "node_modules/array-flatten": { 270 | "version": "1.1.1", 271 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 272 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 273 | }, 274 | "node_modules/asap": { 275 | "version": "2.0.6", 276 | "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", 277 | "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" 278 | }, 279 | "node_modules/body-parser": { 280 | "version": "1.20.3", 281 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", 282 | "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", 283 | "dependencies": { 284 | "bytes": "3.1.2", 285 | "content-type": "~1.0.5", 286 | "debug": "2.6.9", 287 | "depd": "2.0.0", 288 | "destroy": "1.2.0", 289 | "http-errors": "2.0.0", 290 | "iconv-lite": "0.4.24", 291 | "on-finished": "2.4.1", 292 | "qs": "6.13.0", 293 | "raw-body": "2.5.2", 294 | "type-is": "~1.6.18", 295 | "unpipe": "1.0.0" 296 | }, 297 | "engines": { 298 | "node": ">= 0.8", 299 | "npm": "1.2.8000 || >= 1.4.16" 300 | } 301 | }, 302 | "node_modules/body-parser/node_modules/debug": { 303 | "version": "2.6.9", 304 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 305 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 306 | "dependencies": { 307 | "ms": "2.0.0" 308 | } 309 | }, 310 | "node_modules/body-parser/node_modules/iconv-lite": { 311 | "version": "0.4.24", 312 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 313 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 314 | "dependencies": { 315 | "safer-buffer": ">= 2.1.2 < 3" 316 | }, 317 | "engines": { 318 | "node": ">=0.10.0" 319 | } 320 | }, 321 | "node_modules/busboy": { 322 | "version": "1.6.0", 323 | "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", 324 | "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", 325 | "dependencies": { 326 | "streamsearch": "^1.1.0" 327 | }, 328 | "engines": { 329 | "node": ">=10.16.0" 330 | } 331 | }, 332 | "node_modules/bytes": { 333 | "version": "3.1.2", 334 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 335 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 336 | "engines": { 337 | "node": ">= 0.8" 338 | } 339 | }, 340 | "node_modules/call-bind": { 341 | "version": "1.0.8", 342 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", 343 | "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", 344 | "dependencies": { 345 | "call-bind-apply-helpers": "^1.0.0", 346 | "es-define-property": "^1.0.0", 347 | "get-intrinsic": "^1.2.4", 348 | "set-function-length": "^1.2.2" 349 | }, 350 | "engines": { 351 | "node": ">= 0.4" 352 | }, 353 | "funding": { 354 | "url": "https://github.com/sponsors/ljharb" 355 | } 356 | }, 357 | "node_modules/call-bind-apply-helpers": { 358 | "version": "1.0.1", 359 | "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", 360 | "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", 361 | "dependencies": { 362 | "es-errors": "^1.3.0", 363 | "function-bind": "^1.1.2" 364 | }, 365 | "engines": { 366 | "node": ">= 0.4" 367 | } 368 | }, 369 | "node_modules/call-bind-apply-helpers/node_modules/function-bind": { 370 | "version": "1.1.2", 371 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 372 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 373 | "funding": { 374 | "url": "https://github.com/sponsors/ljharb" 375 | } 376 | }, 377 | "node_modules/call-bound": { 378 | "version": "1.0.2", 379 | "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.2.tgz", 380 | "integrity": "sha512-0lk0PHFe/uz0vl527fG9CgdE9WdafjDbCXvBbs+LUv000TVt2Jjhqbs4Jwm8gz070w8xXyEAxrPOMullsxXeGg==", 381 | "dependencies": { 382 | "call-bind": "^1.0.8", 383 | "get-intrinsic": "^1.2.5" 384 | }, 385 | "engines": { 386 | "node": ">= 0.4" 387 | }, 388 | "funding": { 389 | "url": "https://github.com/sponsors/ljharb" 390 | } 391 | }, 392 | "node_modules/caniuse-lite": { 393 | "version": "1.0.30001690", 394 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz", 395 | "integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==", 396 | "funding": [ 397 | { 398 | "type": "opencollective", 399 | "url": "https://opencollective.com/browserslist" 400 | }, 401 | { 402 | "type": "tidelift", 403 | "url": "https://tidelift.com/funding/github/npm/caniuse-lite" 404 | }, 405 | { 406 | "type": "github", 407 | "url": "https://github.com/sponsors/ai" 408 | } 409 | ] 410 | }, 411 | "node_modules/client-only": { 412 | "version": "0.0.1", 413 | "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", 414 | "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" 415 | }, 416 | "node_modules/content-disposition": { 417 | "version": "0.5.4", 418 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 419 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 420 | "dependencies": { 421 | "safe-buffer": "5.2.1" 422 | }, 423 | "engines": { 424 | "node": ">= 0.6" 425 | } 426 | }, 427 | "node_modules/content-type": { 428 | "version": "1.0.5", 429 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 430 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 431 | "engines": { 432 | "node": ">= 0.6" 433 | } 434 | }, 435 | "node_modules/cookie": { 436 | "version": "0.7.0", 437 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.0.tgz", 438 | "integrity": "sha512-qCf+V4dtlNhSRXGAZatc1TasyFO6GjohcOul807YOb5ik3+kQSnb4d7iajeCL8QHaJ4uZEjCgiCJerKXwdRVlQ==", 439 | "engines": { 440 | "node": ">= 0.6" 441 | } 442 | }, 443 | "node_modules/cookie-signature": { 444 | "version": "1.0.6", 445 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 446 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 447 | }, 448 | "node_modules/debug": { 449 | "version": "3.1.0", 450 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 451 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 452 | "dependencies": { 453 | "ms": "2.0.0" 454 | } 455 | }, 456 | "node_modules/define-data-property": { 457 | "version": "1.1.4", 458 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", 459 | "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", 460 | "dependencies": { 461 | "es-define-property": "^1.0.0", 462 | "es-errors": "^1.3.0", 463 | "gopd": "^1.0.1" 464 | }, 465 | "engines": { 466 | "node": ">= 0.4" 467 | }, 468 | "funding": { 469 | "url": "https://github.com/sponsors/ljharb" 470 | } 471 | }, 472 | "node_modules/define-properties": { 473 | "version": "1.1.2", 474 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", 475 | "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", 476 | "dependencies": { 477 | "foreach": "^2.0.5", 478 | "object-keys": "^1.0.8" 479 | }, 480 | "engines": { 481 | "node": ">= 0.4" 482 | } 483 | }, 484 | "node_modules/depd": { 485 | "version": "2.0.0", 486 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 487 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 488 | "engines": { 489 | "node": ">= 0.8" 490 | } 491 | }, 492 | "node_modules/destroy": { 493 | "version": "1.2.0", 494 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 495 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", 496 | "engines": { 497 | "node": ">= 0.8", 498 | "npm": "1.2.8000 || >= 1.4.16" 499 | } 500 | }, 501 | "node_modules/dunder-proto": { 502 | "version": "1.0.0", 503 | "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.0.tgz", 504 | "integrity": "sha512-9+Sj30DIu+4KvHqMfLUGLFYL2PkURSYMVXJyXe92nFRvlYq5hBjLEhblKB+vkd/WVlUYMWigiY07T91Fkk0+4A==", 505 | "dependencies": { 506 | "call-bind-apply-helpers": "^1.0.0", 507 | "es-errors": "^1.3.0", 508 | "gopd": "^1.2.0" 509 | }, 510 | "engines": { 511 | "node": ">= 0.4" 512 | } 513 | }, 514 | "node_modules/ee-first": { 515 | "version": "1.1.1", 516 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 517 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 518 | }, 519 | "node_modules/encodeurl": { 520 | "version": "2.0.0", 521 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", 522 | "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", 523 | "engines": { 524 | "node": ">= 0.8" 525 | } 526 | }, 527 | "node_modules/encoding": { 528 | "version": "0.1.12", 529 | "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", 530 | "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", 531 | "dependencies": { 532 | "iconv-lite": "~0.4.13" 533 | } 534 | }, 535 | "node_modules/engine.io-client": { 536 | "version": "6.5.4", 537 | "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.4.tgz", 538 | "integrity": "sha512-GeZeeRjpD2qf49cZQ0Wvh/8NJNfeXkXXcoGh+F77oEAgo9gUHwT1fCRxSNU+YEEaysOJTnsFHmM5oAcPy4ntvQ==", 539 | "dependencies": { 540 | "@socket.io/component-emitter": "~3.1.0", 541 | "debug": "~4.3.1", 542 | "engine.io-parser": "~5.2.1", 543 | "ws": "~8.17.1", 544 | "xmlhttprequest-ssl": "~2.0.0" 545 | } 546 | }, 547 | "node_modules/engine.io-client/node_modules/debug": { 548 | "version": "4.3.5", 549 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", 550 | "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", 551 | "dependencies": { 552 | "ms": "2.1.2" 553 | }, 554 | "engines": { 555 | "node": ">=6.0" 556 | }, 557 | "peerDependenciesMeta": { 558 | "supports-color": { 559 | "optional": true 560 | } 561 | } 562 | }, 563 | "node_modules/engine.io-client/node_modules/ms": { 564 | "version": "2.1.2", 565 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 566 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 567 | }, 568 | "node_modules/engine.io-parser": { 569 | "version": "5.2.2", 570 | "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", 571 | "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", 572 | "engines": { 573 | "node": ">=10.0.0" 574 | } 575 | }, 576 | "node_modules/es-define-property": { 577 | "version": "1.0.1", 578 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", 579 | "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", 580 | "engines": { 581 | "node": ">= 0.4" 582 | } 583 | }, 584 | "node_modules/es-errors": { 585 | "version": "1.3.0", 586 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", 587 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", 588 | "engines": { 589 | "node": ">= 0.4" 590 | } 591 | }, 592 | "node_modules/es-object-atoms": { 593 | "version": "1.0.0", 594 | "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", 595 | "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", 596 | "dependencies": { 597 | "es-errors": "^1.3.0" 598 | }, 599 | "engines": { 600 | "node": ">= 0.4" 601 | } 602 | }, 603 | "node_modules/escape-html": { 604 | "version": "1.0.3", 605 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 606 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 607 | }, 608 | "node_modules/etag": { 609 | "version": "1.8.1", 610 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 611 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", 612 | "engines": { 613 | "node": ">= 0.6" 614 | } 615 | }, 616 | "node_modules/events": { 617 | "version": "2.0.0", 618 | "resolved": "https://registry.npmjs.org/events/-/events-2.0.0.tgz", 619 | "integrity": "sha512-r/M5YkNg9zwI8QbSf7tsDWWJvO3PGwZXyG7GpFAxtMASnHL2eblFd7iHiGPtyGKKFPZ59S63NeX10Ws6WqGDcg==", 620 | "engines": { 621 | "node": ">=0.4.x" 622 | } 623 | }, 624 | "node_modules/express": { 625 | "version": "4.21.2", 626 | "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", 627 | "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", 628 | "dependencies": { 629 | "accepts": "~1.3.8", 630 | "array-flatten": "1.1.1", 631 | "body-parser": "1.20.3", 632 | "content-disposition": "0.5.4", 633 | "content-type": "~1.0.4", 634 | "cookie": "0.7.1", 635 | "cookie-signature": "1.0.6", 636 | "debug": "2.6.9", 637 | "depd": "2.0.0", 638 | "encodeurl": "~2.0.0", 639 | "escape-html": "~1.0.3", 640 | "etag": "~1.8.1", 641 | "finalhandler": "1.3.1", 642 | "fresh": "0.5.2", 643 | "http-errors": "2.0.0", 644 | "merge-descriptors": "1.0.3", 645 | "methods": "~1.1.2", 646 | "on-finished": "2.4.1", 647 | "parseurl": "~1.3.3", 648 | "path-to-regexp": "0.1.12", 649 | "proxy-addr": "~2.0.7", 650 | "qs": "6.13.0", 651 | "range-parser": "~1.2.1", 652 | "safe-buffer": "5.2.1", 653 | "send": "0.19.0", 654 | "serve-static": "1.16.2", 655 | "setprototypeof": "1.2.0", 656 | "statuses": "2.0.1", 657 | "type-is": "~1.6.18", 658 | "utils-merge": "1.0.1", 659 | "vary": "~1.1.2" 660 | }, 661 | "engines": { 662 | "node": ">= 0.10.0" 663 | }, 664 | "funding": { 665 | "type": "opencollective", 666 | "url": "https://opencollective.com/express" 667 | } 668 | }, 669 | "node_modules/express/node_modules/cookie": { 670 | "version": "0.7.1", 671 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", 672 | "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", 673 | "engines": { 674 | "node": ">= 0.6" 675 | } 676 | }, 677 | "node_modules/express/node_modules/debug": { 678 | "version": "2.6.9", 679 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 680 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 681 | "dependencies": { 682 | "ms": "2.0.0" 683 | } 684 | }, 685 | "node_modules/fbjs": { 686 | "version": "0.8.16", 687 | "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz", 688 | "integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=", 689 | "dependencies": { 690 | "core-js": "^1.0.0", 691 | "isomorphic-fetch": "^2.1.1", 692 | "loose-envify": "^1.0.0", 693 | "object-assign": "^4.1.0", 694 | "promise": "^7.1.1", 695 | "setimmediate": "^1.0.5", 696 | "ua-parser-js": "^0.7.9" 697 | } 698 | }, 699 | "node_modules/fbjs/node_modules/core-js": { 700 | "version": "1.2.7", 701 | "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", 702 | "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=", 703 | "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js." 704 | }, 705 | "node_modules/finalhandler": { 706 | "version": "1.3.1", 707 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", 708 | "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", 709 | "dependencies": { 710 | "debug": "2.6.9", 711 | "encodeurl": "~2.0.0", 712 | "escape-html": "~1.0.3", 713 | "on-finished": "2.4.1", 714 | "parseurl": "~1.3.3", 715 | "statuses": "2.0.1", 716 | "unpipe": "~1.0.0" 717 | }, 718 | "engines": { 719 | "node": ">= 0.8" 720 | } 721 | }, 722 | "node_modules/finalhandler/node_modules/debug": { 723 | "version": "2.6.9", 724 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 725 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 726 | "dependencies": { 727 | "ms": "2.0.0" 728 | } 729 | }, 730 | "node_modules/foreach": { 731 | "version": "2.0.5", 732 | "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", 733 | "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" 734 | }, 735 | "node_modules/forwarded": { 736 | "version": "0.2.0", 737 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 738 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 739 | "engines": { 740 | "node": ">= 0.6" 741 | } 742 | }, 743 | "node_modules/fresh": { 744 | "version": "0.5.2", 745 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 746 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", 747 | "engines": { 748 | "node": ">= 0.6" 749 | } 750 | }, 751 | "node_modules/function-bind": { 752 | "version": "1.1.1", 753 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 754 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 755 | }, 756 | "node_modules/get-intrinsic": { 757 | "version": "1.2.6", 758 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz", 759 | "integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==", 760 | "dependencies": { 761 | "call-bind-apply-helpers": "^1.0.1", 762 | "dunder-proto": "^1.0.0", 763 | "es-define-property": "^1.0.1", 764 | "es-errors": "^1.3.0", 765 | "es-object-atoms": "^1.0.0", 766 | "function-bind": "^1.1.2", 767 | "gopd": "^1.2.0", 768 | "has-symbols": "^1.1.0", 769 | "hasown": "^2.0.2", 770 | "math-intrinsics": "^1.0.0" 771 | }, 772 | "engines": { 773 | "node": ">= 0.4" 774 | }, 775 | "funding": { 776 | "url": "https://github.com/sponsors/ljharb" 777 | } 778 | }, 779 | "node_modules/get-intrinsic/node_modules/function-bind": { 780 | "version": "1.1.2", 781 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 782 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 783 | "funding": { 784 | "url": "https://github.com/sponsors/ljharb" 785 | } 786 | }, 787 | "node_modules/get-intrinsic/node_modules/has-symbols": { 788 | "version": "1.1.0", 789 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", 790 | "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", 791 | "engines": { 792 | "node": ">= 0.4" 793 | }, 794 | "funding": { 795 | "url": "https://github.com/sponsors/ljharb" 796 | } 797 | }, 798 | "node_modules/gopd": { 799 | "version": "1.2.0", 800 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", 801 | "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", 802 | "engines": { 803 | "node": ">= 0.4" 804 | }, 805 | "funding": { 806 | "url": "https://github.com/sponsors/ljharb" 807 | } 808 | }, 809 | "node_modules/graceful-fs": { 810 | "version": "4.2.11", 811 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", 812 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" 813 | }, 814 | "node_modules/has-property-descriptors": { 815 | "version": "1.0.2", 816 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", 817 | "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", 818 | "dependencies": { 819 | "es-define-property": "^1.0.0" 820 | }, 821 | "funding": { 822 | "url": "https://github.com/sponsors/ljharb" 823 | } 824 | }, 825 | "node_modules/has-symbols": { 826 | "version": "1.0.0", 827 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", 828 | "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", 829 | "engines": { 830 | "node": ">= 0.4" 831 | } 832 | }, 833 | "node_modules/hasown": { 834 | "version": "2.0.2", 835 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 836 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 837 | "dependencies": { 838 | "function-bind": "^1.1.2" 839 | }, 840 | "engines": { 841 | "node": ">= 0.4" 842 | } 843 | }, 844 | "node_modules/hasown/node_modules/function-bind": { 845 | "version": "1.1.2", 846 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 847 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 848 | "funding": { 849 | "url": "https://github.com/sponsors/ljharb" 850 | } 851 | }, 852 | "node_modules/http-errors": { 853 | "version": "2.0.0", 854 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 855 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 856 | "dependencies": { 857 | "depd": "2.0.0", 858 | "inherits": "2.0.4", 859 | "setprototypeof": "1.2.0", 860 | "statuses": "2.0.1", 861 | "toidentifier": "1.0.1" 862 | }, 863 | "engines": { 864 | "node": ">= 0.8" 865 | } 866 | }, 867 | "node_modules/iconv-lite": { 868 | "version": "0.4.19", 869 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", 870 | "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", 871 | "engines": { 872 | "node": ">=0.10.0" 873 | } 874 | }, 875 | "node_modules/inherits": { 876 | "version": "2.0.4", 877 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 878 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 879 | }, 880 | "node_modules/invariant": { 881 | "version": "2.2.4", 882 | "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", 883 | "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", 884 | "dependencies": { 885 | "loose-envify": "^1.0.0" 886 | } 887 | }, 888 | "node_modules/ipaddr.js": { 889 | "version": "1.9.1", 890 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 891 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 892 | "engines": { 893 | "node": ">= 0.10" 894 | } 895 | }, 896 | "node_modules/is-stream": { 897 | "version": "1.1.0", 898 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", 899 | "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", 900 | "engines": { 901 | "node": ">=0.10.0" 902 | } 903 | }, 904 | "node_modules/isomorphic-fetch": { 905 | "version": "2.2.1", 906 | "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", 907 | "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", 908 | "dependencies": { 909 | "node-fetch": "^1.0.1", 910 | "whatwg-fetch": ">=0.10.0" 911 | } 912 | }, 913 | "node_modules/js-tokens": { 914 | "version": "3.0.2", 915 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", 916 | "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" 917 | }, 918 | "node_modules/jwt-decode": { 919 | "version": "2.2.0", 920 | "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-2.2.0.tgz", 921 | "integrity": "sha1-fYa9VmefWM5qhHBKZX3TkruoGnk=" 922 | }, 923 | "node_modules/lodash": { 924 | "version": "4.17.21", 925 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 926 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" 927 | }, 928 | "node_modules/lodash-es": { 929 | "version": "4.17.21", 930 | "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", 931 | "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", 932 | "license": "MIT" 933 | }, 934 | "node_modules/loose-envify": { 935 | "version": "1.3.1", 936 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", 937 | "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", 938 | "dependencies": { 939 | "js-tokens": "^3.0.0" 940 | }, 941 | "bin": { 942 | "loose-envify": "cli.js" 943 | } 944 | }, 945 | "node_modules/math-intrinsics": { 946 | "version": "1.0.0", 947 | "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.0.0.tgz", 948 | "integrity": "sha512-4MqMiKP90ybymYvsut0CH2g4XWbfLtmlCkXmtmdcDCxNB+mQcu1w/1+L/VD7vi/PSv7X2JYV7SCcR+jiPXnQtA==", 949 | "engines": { 950 | "node": ">= 0.4" 951 | } 952 | }, 953 | "node_modules/media-typer": { 954 | "version": "0.3.0", 955 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 956 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", 957 | "engines": { 958 | "node": ">= 0.6" 959 | } 960 | }, 961 | "node_modules/merge-descriptors": { 962 | "version": "1.0.3", 963 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", 964 | "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", 965 | "funding": { 966 | "url": "https://github.com/sponsors/sindresorhus" 967 | } 968 | }, 969 | "node_modules/methods": { 970 | "version": "1.1.2", 971 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 972 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", 973 | "engines": { 974 | "node": ">= 0.6" 975 | } 976 | }, 977 | "node_modules/mime": { 978 | "version": "1.6.0", 979 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 980 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 981 | "bin": { 982 | "mime": "cli.js" 983 | }, 984 | "engines": { 985 | "node": ">=4" 986 | } 987 | }, 988 | "node_modules/mime-db": { 989 | "version": "1.52.0", 990 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 991 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 992 | "engines": { 993 | "node": ">= 0.6" 994 | } 995 | }, 996 | "node_modules/mime-types": { 997 | "version": "2.1.35", 998 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 999 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 1000 | "dependencies": { 1001 | "mime-db": "1.52.0" 1002 | }, 1003 | "engines": { 1004 | "node": ">= 0.6" 1005 | } 1006 | }, 1007 | "node_modules/ms": { 1008 | "version": "2.0.0", 1009 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1010 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 1011 | }, 1012 | "node_modules/nanoid": { 1013 | "version": "3.3.8", 1014 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", 1015 | "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", 1016 | "funding": [ 1017 | { 1018 | "type": "github", 1019 | "url": "https://github.com/sponsors/ai" 1020 | } 1021 | ], 1022 | "bin": { 1023 | "nanoid": "bin/nanoid.cjs" 1024 | }, 1025 | "engines": { 1026 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 1027 | } 1028 | }, 1029 | "node_modules/negotiator": { 1030 | "version": "0.6.3", 1031 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 1032 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", 1033 | "engines": { 1034 | "node": ">= 0.6" 1035 | } 1036 | }, 1037 | "node_modules/next": { 1038 | "version": "14.2.21", 1039 | "resolved": "https://registry.npmjs.org/next/-/next-14.2.21.tgz", 1040 | "integrity": "sha512-rZmLwucLHr3/zfDMYbJXbw0ZeoBpirxkXuvsJbk7UPorvPYZhP7vq7aHbKnU7dQNCYIimRrbB2pp3xmf+wsYUg==", 1041 | "dependencies": { 1042 | "@next/env": "14.2.21", 1043 | "@swc/helpers": "0.5.5", 1044 | "busboy": "1.6.0", 1045 | "caniuse-lite": "^1.0.30001579", 1046 | "graceful-fs": "^4.2.11", 1047 | "postcss": "8.4.31", 1048 | "styled-jsx": "5.1.1" 1049 | }, 1050 | "bin": { 1051 | "next": "dist/bin/next" 1052 | }, 1053 | "engines": { 1054 | "node": ">=18.17.0" 1055 | }, 1056 | "optionalDependencies": { 1057 | "@next/swc-darwin-arm64": "14.2.21", 1058 | "@next/swc-darwin-x64": "14.2.21", 1059 | "@next/swc-linux-arm64-gnu": "14.2.21", 1060 | "@next/swc-linux-arm64-musl": "14.2.21", 1061 | "@next/swc-linux-x64-gnu": "14.2.21", 1062 | "@next/swc-linux-x64-musl": "14.2.21", 1063 | "@next/swc-win32-arm64-msvc": "14.2.21", 1064 | "@next/swc-win32-ia32-msvc": "14.2.21", 1065 | "@next/swc-win32-x64-msvc": "14.2.21" 1066 | }, 1067 | "peerDependencies": { 1068 | "@opentelemetry/api": "^1.1.0", 1069 | "@playwright/test": "^1.41.2", 1070 | "react": "^18.2.0", 1071 | "react-dom": "^18.2.0", 1072 | "sass": "^1.3.0" 1073 | }, 1074 | "peerDependenciesMeta": { 1075 | "@opentelemetry/api": { 1076 | "optional": true 1077 | }, 1078 | "@playwright/test": { 1079 | "optional": true 1080 | }, 1081 | "sass": { 1082 | "optional": true 1083 | } 1084 | } 1085 | }, 1086 | "node_modules/next-redux-wrapper": { 1087 | "version": "1.3.5", 1088 | "resolved": "https://registry.npmjs.org/next-redux-wrapper/-/next-redux-wrapper-1.3.5.tgz", 1089 | "integrity": "sha512-VZFl/CIIujxCGDlBM99W8pDYkSr5o10UMUt5/pZHZVgnaEqpFSsRsKz9yAkx/8C3RYFhGK4MHiNaf9+LtUUemA==", 1090 | "dependencies": { 1091 | "object.assign": "^4.0.4" 1092 | }, 1093 | "engines": { 1094 | "node": ">=0.10.36" 1095 | }, 1096 | "peerDependencies": { 1097 | "react": "*", 1098 | "react-redux": "*" 1099 | } 1100 | }, 1101 | "node_modules/node-fetch": { 1102 | "version": "1.7.3", 1103 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", 1104 | "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", 1105 | "dependencies": { 1106 | "encoding": "^0.1.11", 1107 | "is-stream": "^1.0.1" 1108 | } 1109 | }, 1110 | "node_modules/object-assign": { 1111 | "version": "4.1.1", 1112 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1113 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 1114 | "engines": { 1115 | "node": ">=0.10.0" 1116 | } 1117 | }, 1118 | "node_modules/object-inspect": { 1119 | "version": "1.13.3", 1120 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", 1121 | "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", 1122 | "engines": { 1123 | "node": ">= 0.4" 1124 | }, 1125 | "funding": { 1126 | "url": "https://github.com/sponsors/ljharb" 1127 | } 1128 | }, 1129 | "node_modules/object-keys": { 1130 | "version": "1.0.11", 1131 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", 1132 | "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", 1133 | "engines": { 1134 | "node": ">= 0.4" 1135 | } 1136 | }, 1137 | "node_modules/object.assign": { 1138 | "version": "4.1.0", 1139 | "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", 1140 | "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", 1141 | "dependencies": { 1142 | "define-properties": "^1.1.2", 1143 | "function-bind": "^1.1.1", 1144 | "has-symbols": "^1.0.0", 1145 | "object-keys": "^1.0.11" 1146 | }, 1147 | "engines": { 1148 | "node": ">= 0.4" 1149 | } 1150 | }, 1151 | "node_modules/on-finished": { 1152 | "version": "2.4.1", 1153 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 1154 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 1155 | "dependencies": { 1156 | "ee-first": "1.1.1" 1157 | }, 1158 | "engines": { 1159 | "node": ">= 0.8" 1160 | } 1161 | }, 1162 | "node_modules/parseurl": { 1163 | "version": "1.3.3", 1164 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 1165 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 1166 | "engines": { 1167 | "node": ">= 0.8" 1168 | } 1169 | }, 1170 | "node_modules/path-to-regexp": { 1171 | "version": "0.1.12", 1172 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", 1173 | "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==" 1174 | }, 1175 | "node_modules/picocolors": { 1176 | "version": "1.1.1", 1177 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", 1178 | "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" 1179 | }, 1180 | "node_modules/postcss": { 1181 | "version": "8.4.31", 1182 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", 1183 | "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", 1184 | "funding": [ 1185 | { 1186 | "type": "opencollective", 1187 | "url": "https://opencollective.com/postcss/" 1188 | }, 1189 | { 1190 | "type": "tidelift", 1191 | "url": "https://tidelift.com/funding/github/npm/postcss" 1192 | }, 1193 | { 1194 | "type": "github", 1195 | "url": "https://github.com/sponsors/ai" 1196 | } 1197 | ], 1198 | "dependencies": { 1199 | "nanoid": "^3.3.6", 1200 | "picocolors": "^1.0.0", 1201 | "source-map-js": "^1.0.2" 1202 | }, 1203 | "engines": { 1204 | "node": "^10 || ^12 || >=14" 1205 | } 1206 | }, 1207 | "node_modules/promise": { 1208 | "version": "7.3.1", 1209 | "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", 1210 | "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", 1211 | "dependencies": { 1212 | "asap": "~2.0.3" 1213 | } 1214 | }, 1215 | "node_modules/prop-types": { 1216 | "version": "15.6.0", 1217 | "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz", 1218 | "integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=", 1219 | "dependencies": { 1220 | "fbjs": "^0.8.16", 1221 | "loose-envify": "^1.3.1", 1222 | "object-assign": "^4.1.1" 1223 | } 1224 | }, 1225 | "node_modules/proxy-addr": { 1226 | "version": "2.0.7", 1227 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 1228 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 1229 | "dependencies": { 1230 | "forwarded": "0.2.0", 1231 | "ipaddr.js": "1.9.1" 1232 | }, 1233 | "engines": { 1234 | "node": ">= 0.10" 1235 | } 1236 | }, 1237 | "node_modules/qs": { 1238 | "version": "6.13.0", 1239 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", 1240 | "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", 1241 | "dependencies": { 1242 | "side-channel": "^1.0.6" 1243 | }, 1244 | "engines": { 1245 | "node": ">=0.6" 1246 | }, 1247 | "funding": { 1248 | "url": "https://github.com/sponsors/ljharb" 1249 | } 1250 | }, 1251 | "node_modules/radix-router": { 1252 | "version": "3.0.1", 1253 | "resolved": "https://registry.npmjs.org/radix-router/-/radix-router-3.0.1.tgz", 1254 | "integrity": "sha512-jpHXHgP+ZmVzEfmZ7WVRSvc/EqMoAqYuMtBsHd9s47Hs9Iy8FDJhkweMrDH0wmdxanLzVIWhq0UpomLXNpW8tg==" 1255 | }, 1256 | "node_modules/range-parser": { 1257 | "version": "1.2.1", 1258 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 1259 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 1260 | "engines": { 1261 | "node": ">= 0.6" 1262 | } 1263 | }, 1264 | "node_modules/raw-body": { 1265 | "version": "2.5.2", 1266 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", 1267 | "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", 1268 | "dependencies": { 1269 | "bytes": "3.1.2", 1270 | "http-errors": "2.0.0", 1271 | "iconv-lite": "0.4.24", 1272 | "unpipe": "1.0.0" 1273 | }, 1274 | "engines": { 1275 | "node": ">= 0.8" 1276 | } 1277 | }, 1278 | "node_modules/raw-body/node_modules/iconv-lite": { 1279 | "version": "0.4.24", 1280 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 1281 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 1282 | "dependencies": { 1283 | "safer-buffer": ">= 2.1.2 < 3" 1284 | }, 1285 | "engines": { 1286 | "node": ">=0.10.0" 1287 | } 1288 | }, 1289 | "node_modules/react": { 1290 | "version": "16.3.2", 1291 | "resolved": "https://registry.npmjs.org/react/-/react-16.3.2.tgz", 1292 | "integrity": "sha512-o5GPdkhciQ3cEph6qgvYB7LTOHw/GB0qRI6ZFNugj49qJCFfgHwVNjZ5u+b7nif4vOeMIOuYj3CeYe2IBD74lg==", 1293 | "dependencies": { 1294 | "fbjs": "^0.8.16", 1295 | "loose-envify": "^1.1.0", 1296 | "object-assign": "^4.1.1", 1297 | "prop-types": "^15.6.0" 1298 | }, 1299 | "engines": { 1300 | "node": ">=0.10.0" 1301 | } 1302 | }, 1303 | "node_modules/react-dom": { 1304 | "version": "16.3.3", 1305 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.3.3.tgz", 1306 | "integrity": "sha512-ALCp7ZbSGkqRDtQoZozKVNgwXMxbxf/IGOUMC2A0yF6JHeZrS8e2cOotPT87Vf4b7PKCuUVKU4/RDEXxToA/yA==", 1307 | "dependencies": { 1308 | "fbjs": "^0.8.16", 1309 | "loose-envify": "^1.1.0", 1310 | "object-assign": "^4.1.1", 1311 | "prop-types": "^15.6.0" 1312 | }, 1313 | "peerDependencies": { 1314 | "react": "^16.0.0" 1315 | } 1316 | }, 1317 | "node_modules/react-redux": { 1318 | "version": "5.0.7", 1319 | "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.0.7.tgz", 1320 | "integrity": "sha512-5VI8EV5hdgNgyjfmWzBbdrqUkrVRKlyTKk1sGH3jzM2M2Mhj/seQgPXaz6gVAj2lz/nz688AdTqMO18Lr24Zhg==", 1321 | "dependencies": { 1322 | "hoist-non-react-statics": "^2.5.0", 1323 | "invariant": "^2.0.0", 1324 | "lodash": "^4.17.5", 1325 | "lodash-es": "^4.17.5", 1326 | "loose-envify": "^1.1.0", 1327 | "prop-types": "^15.6.0" 1328 | }, 1329 | "peerDependencies": { 1330 | "react": "^0.14.0 || ^15.0.0-0 || ^16.0.0-0", 1331 | "redux": "^2.0.0 || ^3.0.0 || ^4.0.0-0" 1332 | } 1333 | }, 1334 | "node_modules/react-redux/node_modules/hoist-non-react-statics": { 1335 | "version": "2.5.0", 1336 | "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.0.tgz", 1337 | "integrity": "sha512-6Bl6XsDT1ntE0lHbIhr4Kp2PGcleGZ66qu5Jqk8lc0Xc/IeG6gVLmwUGs/K0Us+L8VWoKgj0uWdPMataOsm31w==" 1338 | }, 1339 | "node_modules/redux": { 1340 | "version": "3.7.2", 1341 | "resolved": "https://registry.npmjs.org/redux/-/redux-3.7.2.tgz", 1342 | "integrity": "sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A==", 1343 | "dependencies": { 1344 | "lodash": "^4.2.1", 1345 | "lodash-es": "^4.2.1", 1346 | "loose-envify": "^1.1.0", 1347 | "symbol-observable": "^1.0.3" 1348 | } 1349 | }, 1350 | "node_modules/redux-devtools-extension": { 1351 | "version": "2.13.2", 1352 | "resolved": "https://registry.npmjs.org/redux-devtools-extension/-/redux-devtools-extension-2.13.2.tgz", 1353 | "integrity": "sha1-4Pmo6N/KfBe+kscSSVijuU6ykR0=", 1354 | "deprecated": "Package moved to @redux-devtools/extension.", 1355 | "peerDependencies": { 1356 | "redux": "^3.1.0" 1357 | } 1358 | }, 1359 | "node_modules/redux-thunk": { 1360 | "version": "2.2.0", 1361 | "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.2.0.tgz", 1362 | "integrity": "sha1-5hWhbha0ehmlFXZhM9Hj6Zt4UuU=" 1363 | }, 1364 | "node_modules/safe-buffer": { 1365 | "version": "5.2.1", 1366 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1367 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1368 | "funding": [ 1369 | { 1370 | "type": "github", 1371 | "url": "https://github.com/sponsors/feross" 1372 | }, 1373 | { 1374 | "type": "patreon", 1375 | "url": "https://www.patreon.com/feross" 1376 | }, 1377 | { 1378 | "type": "consulting", 1379 | "url": "https://feross.org/support" 1380 | } 1381 | ] 1382 | }, 1383 | "node_modules/safer-buffer": { 1384 | "version": "2.1.2", 1385 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1386 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1387 | }, 1388 | "node_modules/send": { 1389 | "version": "0.19.0", 1390 | "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", 1391 | "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", 1392 | "dependencies": { 1393 | "debug": "2.6.9", 1394 | "depd": "2.0.0", 1395 | "destroy": "1.2.0", 1396 | "encodeurl": "~1.0.2", 1397 | "escape-html": "~1.0.3", 1398 | "etag": "~1.8.1", 1399 | "fresh": "0.5.2", 1400 | "http-errors": "2.0.0", 1401 | "mime": "1.6.0", 1402 | "ms": "2.1.3", 1403 | "on-finished": "2.4.1", 1404 | "range-parser": "~1.2.1", 1405 | "statuses": "2.0.1" 1406 | }, 1407 | "engines": { 1408 | "node": ">= 0.8.0" 1409 | } 1410 | }, 1411 | "node_modules/send/node_modules/debug": { 1412 | "version": "2.6.9", 1413 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 1414 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 1415 | "dependencies": { 1416 | "ms": "2.0.0" 1417 | } 1418 | }, 1419 | "node_modules/send/node_modules/debug/node_modules/ms": { 1420 | "version": "2.0.0", 1421 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1422 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 1423 | }, 1424 | "node_modules/send/node_modules/encodeurl": { 1425 | "version": "1.0.2", 1426 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 1427 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", 1428 | "engines": { 1429 | "node": ">= 0.8" 1430 | } 1431 | }, 1432 | "node_modules/send/node_modules/ms": { 1433 | "version": "2.1.3", 1434 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1435 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 1436 | }, 1437 | "node_modules/serve-static": { 1438 | "version": "1.16.2", 1439 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", 1440 | "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", 1441 | "dependencies": { 1442 | "encodeurl": "~2.0.0", 1443 | "escape-html": "~1.0.3", 1444 | "parseurl": "~1.3.3", 1445 | "send": "0.19.0" 1446 | }, 1447 | "engines": { 1448 | "node": ">= 0.8.0" 1449 | } 1450 | }, 1451 | "node_modules/set-function-length": { 1452 | "version": "1.2.2", 1453 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", 1454 | "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", 1455 | "dependencies": { 1456 | "define-data-property": "^1.1.4", 1457 | "es-errors": "^1.3.0", 1458 | "function-bind": "^1.1.2", 1459 | "get-intrinsic": "^1.2.4", 1460 | "gopd": "^1.0.1", 1461 | "has-property-descriptors": "^1.0.2" 1462 | }, 1463 | "engines": { 1464 | "node": ">= 0.4" 1465 | } 1466 | }, 1467 | "node_modules/set-function-length/node_modules/function-bind": { 1468 | "version": "1.1.2", 1469 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 1470 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 1471 | "funding": { 1472 | "url": "https://github.com/sponsors/ljharb" 1473 | } 1474 | }, 1475 | "node_modules/setimmediate": { 1476 | "version": "1.0.5", 1477 | "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", 1478 | "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" 1479 | }, 1480 | "node_modules/setprototypeof": { 1481 | "version": "1.2.0", 1482 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 1483 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 1484 | }, 1485 | "node_modules/side-channel": { 1486 | "version": "1.1.0", 1487 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", 1488 | "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", 1489 | "dependencies": { 1490 | "es-errors": "^1.3.0", 1491 | "object-inspect": "^1.13.3", 1492 | "side-channel-list": "^1.0.0", 1493 | "side-channel-map": "^1.0.1", 1494 | "side-channel-weakmap": "^1.0.2" 1495 | }, 1496 | "engines": { 1497 | "node": ">= 0.4" 1498 | }, 1499 | "funding": { 1500 | "url": "https://github.com/sponsors/ljharb" 1501 | } 1502 | }, 1503 | "node_modules/side-channel-list": { 1504 | "version": "1.0.0", 1505 | "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", 1506 | "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", 1507 | "dependencies": { 1508 | "es-errors": "^1.3.0", 1509 | "object-inspect": "^1.13.3" 1510 | }, 1511 | "engines": { 1512 | "node": ">= 0.4" 1513 | }, 1514 | "funding": { 1515 | "url": "https://github.com/sponsors/ljharb" 1516 | } 1517 | }, 1518 | "node_modules/side-channel-map": { 1519 | "version": "1.0.1", 1520 | "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", 1521 | "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", 1522 | "dependencies": { 1523 | "call-bound": "^1.0.2", 1524 | "es-errors": "^1.3.0", 1525 | "get-intrinsic": "^1.2.5", 1526 | "object-inspect": "^1.13.3" 1527 | }, 1528 | "engines": { 1529 | "node": ">= 0.4" 1530 | }, 1531 | "funding": { 1532 | "url": "https://github.com/sponsors/ljharb" 1533 | } 1534 | }, 1535 | "node_modules/side-channel-weakmap": { 1536 | "version": "1.0.2", 1537 | "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", 1538 | "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", 1539 | "dependencies": { 1540 | "call-bound": "^1.0.2", 1541 | "es-errors": "^1.3.0", 1542 | "get-intrinsic": "^1.2.5", 1543 | "object-inspect": "^1.13.3", 1544 | "side-channel-map": "^1.0.1" 1545 | }, 1546 | "engines": { 1547 | "node": ">= 0.4" 1548 | }, 1549 | "funding": { 1550 | "url": "https://github.com/sponsors/ljharb" 1551 | } 1552 | }, 1553 | "node_modules/socket.io-client": { 1554 | "version": "4.7.5", 1555 | "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.5.tgz", 1556 | "integrity": "sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ==", 1557 | "dependencies": { 1558 | "@socket.io/component-emitter": "~3.1.0", 1559 | "debug": "~4.3.2", 1560 | "engine.io-client": "~6.5.2", 1561 | "socket.io-parser": "~4.2.4" 1562 | }, 1563 | "engines": { 1564 | "node": ">=10.0.0" 1565 | } 1566 | }, 1567 | "node_modules/socket.io-client/node_modules/debug": { 1568 | "version": "4.3.5", 1569 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", 1570 | "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", 1571 | "dependencies": { 1572 | "ms": "2.1.2" 1573 | }, 1574 | "engines": { 1575 | "node": ">=6.0" 1576 | }, 1577 | "peerDependenciesMeta": { 1578 | "supports-color": { 1579 | "optional": true 1580 | } 1581 | } 1582 | }, 1583 | "node_modules/socket.io-client/node_modules/ms": { 1584 | "version": "2.1.2", 1585 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1586 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 1587 | }, 1588 | "node_modules/socket.io-parser": { 1589 | "version": "4.2.4", 1590 | "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", 1591 | "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", 1592 | "dependencies": { 1593 | "@socket.io/component-emitter": "~3.1.0", 1594 | "debug": "~4.3.1" 1595 | }, 1596 | "engines": { 1597 | "node": ">=10.0.0" 1598 | } 1599 | }, 1600 | "node_modules/socket.io-parser/node_modules/debug": { 1601 | "version": "4.3.5", 1602 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", 1603 | "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", 1604 | "dependencies": { 1605 | "ms": "2.1.2" 1606 | }, 1607 | "engines": { 1608 | "node": ">=6.0" 1609 | }, 1610 | "peerDependenciesMeta": { 1611 | "supports-color": { 1612 | "optional": true 1613 | } 1614 | } 1615 | }, 1616 | "node_modules/socket.io-parser/node_modules/ms": { 1617 | "version": "2.1.2", 1618 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1619 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 1620 | }, 1621 | "node_modules/source-map-js": { 1622 | "version": "1.2.1", 1623 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", 1624 | "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", 1625 | "engines": { 1626 | "node": ">=0.10.0" 1627 | } 1628 | }, 1629 | "node_modules/statuses": { 1630 | "version": "2.0.1", 1631 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 1632 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 1633 | "engines": { 1634 | "node": ">= 0.8" 1635 | } 1636 | }, 1637 | "node_modules/streamsearch": { 1638 | "version": "1.1.0", 1639 | "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", 1640 | "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", 1641 | "engines": { 1642 | "node": ">=10.0.0" 1643 | } 1644 | }, 1645 | "node_modules/styled-jsx": { 1646 | "version": "5.1.1", 1647 | "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", 1648 | "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", 1649 | "dependencies": { 1650 | "client-only": "0.0.1" 1651 | }, 1652 | "engines": { 1653 | "node": ">= 12.0.0" 1654 | }, 1655 | "peerDependencies": { 1656 | "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" 1657 | }, 1658 | "peerDependenciesMeta": { 1659 | "@babel/core": { 1660 | "optional": true 1661 | }, 1662 | "babel-plugin-macros": { 1663 | "optional": true 1664 | } 1665 | } 1666 | }, 1667 | "node_modules/symbol-observable": { 1668 | "version": "1.2.0", 1669 | "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", 1670 | "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", 1671 | "engines": { 1672 | "node": ">=0.10.0" 1673 | } 1674 | }, 1675 | "node_modules/toidentifier": { 1676 | "version": "1.0.1", 1677 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 1678 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 1679 | "engines": { 1680 | "node": ">=0.6" 1681 | } 1682 | }, 1683 | "node_modules/tslib": { 1684 | "version": "2.8.1", 1685 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", 1686 | "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" 1687 | }, 1688 | "node_modules/type-is": { 1689 | "version": "1.6.18", 1690 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 1691 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 1692 | "dependencies": { 1693 | "media-typer": "0.3.0", 1694 | "mime-types": "~2.1.24" 1695 | }, 1696 | "engines": { 1697 | "node": ">= 0.6" 1698 | } 1699 | }, 1700 | "node_modules/ua-parser-js": { 1701 | "version": "0.7.17", 1702 | "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz", 1703 | "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g==", 1704 | "engines": { 1705 | "node": "*" 1706 | } 1707 | }, 1708 | "node_modules/uberproto": { 1709 | "version": "1.2.0", 1710 | "resolved": "https://registry.npmjs.org/uberproto/-/uberproto-1.2.0.tgz", 1711 | "integrity": "sha1-YdTqsCT5CcTm6lK+hnxIlKS+63Y=", 1712 | "engines": { 1713 | "node": "*" 1714 | } 1715 | }, 1716 | "node_modules/unpipe": { 1717 | "version": "1.0.0", 1718 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1719 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 1720 | "engines": { 1721 | "node": ">= 0.8" 1722 | } 1723 | }, 1724 | "node_modules/utils-merge": { 1725 | "version": "1.0.1", 1726 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1727 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", 1728 | "engines": { 1729 | "node": ">= 0.4.0" 1730 | } 1731 | }, 1732 | "node_modules/vary": { 1733 | "version": "1.1.2", 1734 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1735 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", 1736 | "engines": { 1737 | "node": ">= 0.8" 1738 | } 1739 | }, 1740 | "node_modules/whatwg-fetch": { 1741 | "version": "2.0.4", 1742 | "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", 1743 | "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" 1744 | }, 1745 | "node_modules/ws": { 1746 | "version": "8.17.1", 1747 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", 1748 | "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", 1749 | "engines": { 1750 | "node": ">=10.0.0" 1751 | }, 1752 | "peerDependencies": { 1753 | "bufferutil": "^4.0.1", 1754 | "utf-8-validate": ">=5.0.2" 1755 | }, 1756 | "peerDependenciesMeta": { 1757 | "bufferutil": { 1758 | "optional": true 1759 | }, 1760 | "utf-8-validate": { 1761 | "optional": true 1762 | } 1763 | } 1764 | }, 1765 | "node_modules/xmlhttprequest-ssl": { 1766 | "version": "2.0.0", 1767 | "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", 1768 | "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", 1769 | "engines": { 1770 | "node": ">=0.4.0" 1771 | } 1772 | } 1773 | } 1774 | } 1775 | -------------------------------------------------------------------------------- /client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "feathers-next-client", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "dev": "node src/server.js", 9 | "build": "next build src", 10 | "start": "NODE_ENV=production node src/server.js" 11 | }, 12 | "dependencies": { 13 | "@feathersjs/authentication-client": "^1.0.2", 14 | "@feathersjs/feathers": "^3.1.0", 15 | "@feathersjs/socketio-client": "^1.0.2", 16 | "cookie": "^0.7.0", 17 | "express": "^4.21.2", 18 | "next": "^14.2.21", 19 | "next-redux-wrapper": "^1.0.0", 20 | "react": "^16.2.0", 21 | "react-dom": "^16.3.3", 22 | "react-redux": "^5.0.1", 23 | "redux": "^3.6.0", 24 | "redux-devtools-extension": "^2.13.2", 25 | "redux-thunk": "^2.1.0", 26 | "socket.io-client": "^4.7.5" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /client/src/api/auth.js: -------------------------------------------------------------------------------- 1 | import client from './client' 2 | 3 | const auth = { 4 | 5 | fetchUser (accessToken) { 6 | 7 | return client.passport.verifyJWT(accessToken) 8 | .then(payload => { 9 | return client.service('users').get(payload.userId) 10 | }) 11 | .then(user => { 12 | return Promise.resolve(user) 13 | }) 14 | }, 15 | 16 | authenticate (jwtFromCookie = null, doAuthenticate = false) { 17 | console.log('authenticate, cookie: ' + (jwtFromCookie ? 'yes' : 'no') + ' , doAuthenticate: ' + doAuthenticate) 18 | 19 | client.authenticated = false 20 | 21 | // If there is no JWT then we don't try to authenticate (because strategy 'jwt' normally needs a JWT), *unless* the 22 | // parameter "doAuthenticate" is true - this is the case when we logged in just now and need to obtain a (new) JWT 23 | if (!jwtFromCookie && !doAuthenticate) { 24 | return Promise.resolve({user: null, jwt: null}) 25 | } 26 | 27 | let jwt = null 28 | 29 | return client.authenticate({ 30 | strategy: 'jwt', 31 | accessToken: jwtFromCookie 32 | }) 33 | .then((response) => { 34 | console.log('authenticate successful') 35 | 36 | jwt = response.accessToken 37 | // set client.authenticated flag TRUE 38 | client.authenticated = true 39 | 40 | return this.fetchUser(jwt) 41 | }) 42 | .then(user => { 43 | console.log('authenticate, got user') 44 | 45 | return Promise.resolve({user, jwt}) 46 | }) 47 | .catch((err) => { 48 | console.log('authenticate failed', err) 49 | 50 | return Promise.resolve({user: null, jwt: null}) 51 | }) 52 | }, 53 | 54 | signout () { 55 | console.log('signout') 56 | 57 | return client.logout() 58 | .then(() => { 59 | // set client.authenticated flag FALSE 60 | client.authenticated = false 61 | 62 | console.log('signout successful') 63 | }) 64 | .catch((err) => { 65 | console.log('signout failed', err) 66 | 67 | return Promise.reject(err) 68 | }) 69 | }, 70 | 71 | register (email, password) { 72 | return client.service('users').create({ 73 | email: email, 74 | password: password 75 | }) 76 | }, 77 | 78 | login (email, password) { 79 | return client.authenticate({ 80 | strategy: 'local', 81 | email: email, 82 | password: password 83 | }) 84 | } 85 | 86 | } 87 | 88 | export default auth 89 | -------------------------------------------------------------------------------- /client/src/api/client.js: -------------------------------------------------------------------------------- 1 | import feathers from '@feathersjs/feathers' 2 | import socketio from '@feathersjs/socketio-client' 3 | import auth from '@feathersjs/authentication-client' 4 | import io from 'socket.io-client' 5 | 6 | // 7 | // TODO get rid of this hardcoded API_ENDPOINT, make it configurable ! 8 | // 9 | // Note: the standard Feathers config approach doesn't work because this is next.js, so it has to work both on client and server 10 | // (that's "universal Javascript" biting us again - really complicating a lot of things!) - an approach we could use is this: 11 | // 12 | // https://github.com/zeit/next.js/tree/canary/examples/with-universal-configuration-runtime 13 | // 14 | const API_ENDPOINT = 'http://localhost:3030' 15 | 16 | // "forceNew": https://github.com/feathersjs/authentication/issues/662 17 | const socket = io(API_ENDPOINT, {transports: ['websocket'], forceNew: true}) 18 | 19 | // We don't configure JWT storage, the next.js app (which is separate from the Feathers backend) manages the JWT via a cookie 20 | const options = {} 21 | 22 | const client = feathers() 23 | .configure(socketio(socket)) 24 | .configure(auth(options)) 25 | 26 | client.service('/users') 27 | client.service('/counters') 28 | 29 | export default client -------------------------------------------------------------------------------- /client/src/components/authForm.js: -------------------------------------------------------------------------------- 1 | export default ({username, password, errorMessage, onChange, onSubmit}) => { 2 | 3 | return ( 4 |
18 | ) 19 | } -------------------------------------------------------------------------------- /client/src/components/withAuth.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import Router from 'next/router' 3 | import { authenticate, FEATHERS_COOKIE, getServerCookie, setServerCookie, clearServerCookie } from '../store' 4 | import Error from 'next/error' 5 | import apiClient from '../api/client' 6 | 7 | export const PUBLIC = 'PUBLIC' 8 | 9 | /** 10 | * Higher order component for Next.js `pages` components. 11 | * 12 | * NOTE: depends of redux store. So you must use the `withRedux` HOC before this one. 13 | * 14 | * Example: 15 | * 16 | * ``` 17 | * export default withRedux(initStore, mapStateToProps)( 18 | * withAuth(PUBLIC)(MyPage) 19 | * ) 20 | * ``` 21 | * 22 | * Or using redux compose function: 23 | * 24 | * ``` 25 | * export default compose( 26 | * withRedux(initStore, mapStateToProps), 27 | * withAuth() 28 | * )(Private) 29 | * ``` 30 | * 31 | * It reads the user from the redux store or calls whoami API to verify current logged in user. 32 | * 33 | * To make a page public you have to pass PUBLIC as the `permission` parameter. 34 | * This is required to be able to show current logged in user from the first server render. 35 | * 36 | * @param permission: permission required to render this page. Use PUBLIC to make the page public. 37 | * @returns function(ChildComponent) React component to be wrapped. Must be a `page` component. 38 | */ 39 | export default (permission = null) => ChildComponent => class withAuth extends Component { 40 | 41 | static redirectToLogin (context) { 42 | const { isServer, req, res } = context 43 | 44 | if (isServer) { 45 | res.writeHead(302, { Location: `/login?next=${req.originalUrl}` }) 46 | res.end() 47 | } else { 48 | Router.push(`/login?next=${context.asPath}`) 49 | } 50 | } 51 | 52 | static userHasPermission (user) { 53 | const userGroups = user.groups || [] 54 | let userHasPerm = true 55 | 56 | // go here only if we have specific permission requirements 57 | if (permission) { 58 | // for instance if the permission is "admin" and the user name starts with admin 59 | userHasPerm = user.email.toLowerCase().startsWith(permission.toLowerCase()) 60 | } 61 | return userHasPerm 62 | } 63 | 64 | static async getInitialProps (context) { 65 | // public page passes the permission `PUBLIC` to this function 66 | const isPublicPage = permission == PUBLIC 67 | const { isServer, store, req, res } = context 68 | 69 | if (isServer) { 70 | // Authenticate, happens on page first load 71 | 72 | const jwtFromCookie = getServerCookie(req, FEATHERS_COOKIE) 73 | const result = await store.dispatch(authenticate(jwtFromCookie)) 74 | 75 | const newJwt = result.auth.jwt 76 | 77 | if (newJwt) { 78 | setServerCookie(res, FEATHERS_COOKIE, newJwt) 79 | } else { 80 | clearServerCookie(res, FEATHERS_COOKIE) 81 | } 82 | 83 | // client side - check if the Feathers API client is already authenticated 84 | } else if (!apiClient.authenticated) { 85 | console.log('Need to authenticate client-side') 86 | 87 | // get the JWT (from cookie - set by previous login or server-side authentication) and use it to auth the API client 88 | const jwt = store.getState().auth.jwt 89 | await store.dispatch(authenticate(jwt)) 90 | } 91 | 92 | return this.getInitProps(context, store.getState().auth.user, isPublicPage) 93 | } 94 | 95 | static async getInitProps (context, user, isPublicPage) { 96 | 97 | let proceedToPage = true 98 | let initProps = {} 99 | 100 | if (user) { 101 | // means the user is logged in so we verify permission 102 | if (!isPublicPage) { 103 | 104 | if (!this.userHasPermission(user)) { 105 | proceedToPage = false 106 | 107 | // Show a 404 page (see using next.js' built-in Error page) - TODO does this also work server-side? 108 | const statusCode = 404 109 | initProps = { statusCode } 110 | } 111 | } 112 | } else { 113 | 114 | // anonymous user 115 | if (!isPublicPage) { 116 | proceedToPage = false 117 | 118 | this.redirectToLogin(context) 119 | } 120 | } 121 | 122 | if (proceedToPage && typeof ChildComponent.getInitialProps === 'function') { 123 | initProps = await ChildComponent.getInitialProps(context) 124 | } 125 | 126 | return initProps 127 | } 128 | 129 | render () { 130 | // Use next's built-in error page 131 | if (this.props.statusCode) { 132 | returnThis content is for "admin" users only.
19 |This content is available for logged in users only.
26 |