mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2024-11-10 06:54:16 +00:00
[chore] Convert some settings / admin panel JS to TypeScript (#2247)
* initial conversion of STUFF to typescript * more stuff * update babel deps, include commonjs transform * update bundler & eslint configuration * eslint --fix * upgrade deps * update docs, build stuff, peripheral stuff --------- Co-authored-by: f0x <f0x@cthu.lu>
This commit is contained in:
parent
6e508830e1
commit
d173fcdfa3
84 changed files with 2365 additions and 1621 deletions
11
.drone.yml
11
.drone.yml
|
@ -53,8 +53,7 @@ steps:
|
||||||
- name: yarn_cache
|
- name: yarn_cache
|
||||||
path: /tmp/cache
|
path: /tmp/cache
|
||||||
commands:
|
commands:
|
||||||
- cd web/source
|
- yarn --cwd ./web/source install --frozen-lockfile --cache-folder /tmp/cache
|
||||||
- yarn --frozen-lockfile --cache-folder /tmp/cache
|
|
||||||
|
|
||||||
- name: web-lint
|
- name: web-lint
|
||||||
image: node:18-alpine
|
image: node:18-alpine
|
||||||
|
@ -65,8 +64,7 @@ steps:
|
||||||
depends_on:
|
depends_on:
|
||||||
- web-setup
|
- web-setup
|
||||||
commands:
|
commands:
|
||||||
- cd web/source
|
- yarn --cwd ./web/source lint
|
||||||
- yarn run lint
|
|
||||||
|
|
||||||
- name: web-build
|
- name: web-build
|
||||||
image: node:18-alpine
|
image: node:18-alpine
|
||||||
|
@ -77,8 +75,7 @@ steps:
|
||||||
depends_on:
|
depends_on:
|
||||||
- web-setup
|
- web-setup
|
||||||
commands:
|
commands:
|
||||||
- cd web/source
|
- yarn --cwd ./web/source build
|
||||||
- yarn run build
|
|
||||||
|
|
||||||
- name: snapshot
|
- name: snapshot
|
||||||
image: superseriousbusiness/gotosocial-drone-build:0.3.0 # https://github.com/superseriousbusiness/gotosocial-drone-build
|
image: superseriousbusiness/gotosocial-drone-build:0.3.0 # https://github.com/superseriousbusiness/gotosocial-drone-build
|
||||||
|
@ -194,6 +191,6 @@ steps:
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: signature
|
kind: signature
|
||||||
hmac: 74653d67ed44ceefb7e19d6125d4a457e6308b5ef627df6325d72a0cc7d7cc0a
|
hmac: c3efbd528a76016562f88ae435141cfb5fd6d4d07b6ad2a24ecc23cb529cc1c6
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
|
@ -6,9 +6,9 @@ before:
|
||||||
# generate the swagger.yaml file using go-swagger and bundle it into the assets directory
|
# generate the swagger.yaml file using go-swagger and bundle it into the assets directory
|
||||||
- swagger generate spec --scan-models --exclude-deps -o web/assets/swagger.yaml
|
- swagger generate spec --scan-models --exclude-deps -o web/assets/swagger.yaml
|
||||||
- sed -i "s/REPLACE_ME/{{ incpatch .Version }}/" web/assets/swagger.yaml
|
- sed -i "s/REPLACE_ME/{{ incpatch .Version }}/" web/assets/swagger.yaml
|
||||||
# bundle web assets
|
# Install web deps + bundle web assets
|
||||||
- yarn install --cwd web/source
|
- yarn --cwd ./web/source install
|
||||||
- scripts/bundle.sh
|
- yarn --cwd ./web/source build
|
||||||
builds:
|
builds:
|
||||||
# https://goreleaser.com/customization/build/
|
# https://goreleaser.com/customization/build/
|
||||||
-
|
-
|
||||||
|
|
|
@ -226,31 +226,44 @@ To bundle changes, you need [Node.js](https://nodejs.org/en/download/) and [Yarn
|
||||||
|
|
||||||
Using [NVM](https://github.com/nvm-sh/nvm) is one convenient way to install them which also supports managing different Node versions.
|
Using [NVM](https://github.com/nvm-sh/nvm) is one convenient way to install them which also supports managing different Node versions.
|
||||||
|
|
||||||
To install Yarn dependencies:
|
To install frontend dependencies:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yarn install --cwd web/source
|
yarn --cwd web/source
|
||||||
```
|
```
|
||||||
|
|
||||||
To recompile bundles:
|
To recompile frontend bundles into `web/assets/dist`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
node web/source
|
yarn --cwd web/source build
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Live Reloading
|
#### Live Reloading
|
||||||
|
|
||||||
For a more convenient development environment, you can run a livereloading version of the bundler alongside the [testrig](#testing).
|
For a more convenient development environment, you can run a livereloading version of the bundler alongside the [testrig](#testing).
|
||||||
|
|
||||||
Open two terminals, first start the testrig on port 8081:
|
First build the GtS binary with DEBUG=1 to enable the testrig:
|
||||||
|
|
||||||
``` bash
|
``` bash
|
||||||
GTS_PORT=8081 go run ./cmd/gotosocial testrig start
|
DEBUG=1 ./scripts/build.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Now open two terminals.
|
||||||
|
|
||||||
|
In the first terminal, run the testrig on port 8081, using the binary you just built:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
DEBUG=1 GTS_PORT=8081 ./gotosocial testrig start
|
||||||
|
```
|
||||||
|
|
||||||
Then start the bundler, which will run on port 8080, and proxy requests to the testrig instance where needed.
|
Then start the bundler, which will run on port 8080, and proxy requests to the testrig instance where needed.
|
||||||
|
|
||||||
``` bash
|
``` bash
|
||||||
NODE_ENV=development node web/source
|
NODE_ENV=development yarn --cwd ./web/source dev
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can then log in to the GoToSocial settings panel at `http://localhost:8080/settings` and see your changes reflected in real time as the dev bundler reloads.
|
||||||
|
|
||||||
The livereloading bundler *will not* change the bundled assets in `dist/`, so once you are finished with changes and want to deploy it somewhere, you have to run `node web/source` to generate production-ready bundles.
|
The livereloading bundler *will not* change the bundled assets in `dist/`, so once you are finished with changes and want to deploy it somewhere, you have to run `node web/source` to generate production-ready bundles.
|
||||||
|
|
||||||
### Project Structure
|
### Project Structure
|
||||||
|
|
|
@ -12,12 +12,12 @@ WORKDIR /go/src/github.com/superseriousbusiness/gotosocial
|
||||||
RUN swagger generate spec -o /go/src/github.com/superseriousbusiness/gotosocial/swagger.yaml --scan-models
|
RUN swagger generate spec -o /go/src/github.com/superseriousbusiness/gotosocial/swagger.yaml --scan-models
|
||||||
|
|
||||||
# stage 2: generate the web/assets/dist bundles
|
# stage 2: generate the web/assets/dist bundles
|
||||||
FROM --platform=${BUILDPLATFORM} node:16.19.1-alpine3.17 AS bundler
|
FROM --platform=${BUILDPLATFORM} node:18-alpine AS bundler
|
||||||
|
|
||||||
COPY web web
|
COPY web web
|
||||||
RUN yarn install --cwd web/source && \
|
RUN yarn --cwd ./web/source install && \
|
||||||
BUDO_BUILD=1 node web/source && \
|
yarn --cwd ./web/source build && \
|
||||||
rm -r web/source
|
rm -rf ./web/source
|
||||||
|
|
||||||
# stage 3: build the executor container
|
# stage 3: build the executor container
|
||||||
FROM --platform=${TARGETPLATFORM} alpine:3.17.2 as executor
|
FROM --platform=${TARGETPLATFORM} alpine:3.17.2 as executor
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# this script is really just here because GoReleaser doesn't let
|
|
||||||
# you set env vars in your 'before' commands in the free version
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
BUDO_BUILD=1 node web/source
|
|
|
@ -17,13 +17,15 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
"extends": ["@joepie91/eslint-config/react"],
|
"extends": ["@joepie91/eslint-config/react"],
|
||||||
"plugins": ["license-header"],
|
"parser": "@typescript-eslint/parser",
|
||||||
|
"plugins": ["@typescript-eslint", "license-header"],
|
||||||
"rules": {
|
"rules": {
|
||||||
"license-header/header": ["error", __dirname + "/.license-header.js"],
|
"license-header/header": ["error", __dirname + "/.license-header.js"],
|
||||||
"no-console": 'error'
|
"no-console": 'error'
|
||||||
|
},
|
||||||
|
"parserOptions": {
|
||||||
|
"sourceType": "module"
|
||||||
}
|
}
|
||||||
};
|
};
|
3
web/source/.gitignore
vendored
3
web/source/.gitignore
vendored
|
@ -1,2 +1,5 @@
|
||||||
node_modules
|
node_modules
|
||||||
public/bundle.*
|
public/bundle.*
|
||||||
|
|
||||||
|
# Built/Typescript-compiled settings files.
|
||||||
|
settings-js
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const Photoswipe = require("photoswipe/dist/umd/photoswipe.umd.min.js");
|
const Photoswipe = require("photoswipe/dist/umd/photoswipe.umd.min.js");
|
||||||
const PhotoswipeLightbox = require("photoswipe/dist/umd/photoswipe-lightbox.umd.min.js");
|
const PhotoswipeLightbox = require("photoswipe/dist/umd/photoswipe-lightbox.umd.min.js");
|
||||||
const PhotoswipeCaptionPlugin = require("photoswipe-dynamic-caption-plugin").default;
|
const PhotoswipeCaptionPlugin = require("photoswipe-dynamic-caption-plugin").default;
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const skulk = require("skulk");
|
const skulk = require("skulk");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
@ -70,10 +68,17 @@ skulk({
|
||||||
entryFile: "settings",
|
entryFile: "settings",
|
||||||
outputFile: "settings.js",
|
outputFile: "settings.js",
|
||||||
prodCfg: prodCfg,
|
prodCfg: prodCfg,
|
||||||
|
plugin: [
|
||||||
|
// Additional settings for TS are passed from tsconfig.json.
|
||||||
|
// See: https://github.com/TypeStrong/tsify#tsconfigjson
|
||||||
|
["tsify"]
|
||||||
|
],
|
||||||
transform: [
|
transform: [
|
||||||
|
// tsify is called before babelify, so we're just babelifying
|
||||||
|
// commonjs here, no need for the typescript preset.
|
||||||
["babelify", {
|
["babelify", {
|
||||||
global: true,
|
global: true,
|
||||||
ignore: [/node_modules\/(?!nanoid)/]
|
ignore: [/node_modules\/(?!nanoid)/],
|
||||||
}]
|
}]
|
||||||
],
|
],
|
||||||
presets: [
|
presets: [
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
"author": "f0x",
|
"author": "f0x",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint . --ext .js,.jsx",
|
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
|
||||||
"build": "node index.js",
|
"build": "node index.js",
|
||||||
"dev": "NODE_ENV=development node index.js"
|
"dev": "NODE_ENV=development node index.js"
|
||||||
},
|
},
|
||||||
|
@ -29,21 +29,25 @@
|
||||||
"psl": "^1.9.0",
|
"psl": "^1.9.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-redux": "^8.0.4",
|
"react-redux": "^8.1.3",
|
||||||
"redux": "^4.2.0",
|
"redux": "^4.2.0",
|
||||||
"redux-persist": "^6.0.0",
|
"redux-persist": "^6.0.0",
|
||||||
"skulk": "^0.0.6",
|
"skulk": "^0.0.8-fix",
|
||||||
"split-filter-n": "^1.1.3",
|
"split-filter-n": "^1.1.3",
|
||||||
"syncpipe": "^1.0.0",
|
"syncpipe": "^1.0.0",
|
||||||
"wouter": "^2.8.0-alpha.2"
|
"wouter": "^2.8.0-alpha.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.19.6",
|
"@babel/core": "^7.23.0",
|
||||||
"@babel/preset-env": "^7.19.4",
|
"@babel/preset-env": "^7.22.20",
|
||||||
"@babel/preset-react": "^7.18.6",
|
"@babel/preset-react": "^7.22.15",
|
||||||
|
"@babel/preset-typescript": "^7.23.0",
|
||||||
"@browserify/envify": "^6.0.0",
|
"@browserify/envify": "^6.0.0",
|
||||||
"@browserify/uglifyify": "^6.0.0",
|
"@browserify/uglifyify": "^6.0.0",
|
||||||
"@joepie91/eslint-config": "^1.1.1",
|
"@joepie91/eslint-config": "^1.1.1",
|
||||||
|
"@types/react-dom": "^18.2.8",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^6.7.4",
|
||||||
|
"@typescript-eslint/parser": "^6.7.4",
|
||||||
"autoprefixer": "^10.4.13",
|
"autoprefixer": "^10.4.13",
|
||||||
"babelify": "^10.0.0",
|
"babelify": "^10.0.0",
|
||||||
"css-extract": "^2.0.0",
|
"css-extract": "^2.0.0",
|
||||||
|
@ -56,6 +60,10 @@
|
||||||
"postcss": "^8.4.18",
|
"postcss": "^8.4.18",
|
||||||
"postcss-custom-prop-vars": "^0.0.5",
|
"postcss-custom-prop-vars": "^0.0.5",
|
||||||
"postcss-import": "^15.0.0",
|
"postcss-import": "^15.0.0",
|
||||||
"postcss-nested": "^6.0.0"
|
"postcss-nested": "^6.0.0",
|
||||||
|
"source-map-loader": "^4.0.1",
|
||||||
|
"ts-loader": "^9.4.4",
|
||||||
|
"tsify": "^5.0.4",
|
||||||
|
"typescript": "^5.2.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const { useRoute, Redirect } = require("wouter");
|
const { useRoute, Redirect } = require("wouter");
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const { Switch, Route, Link } = require("wouter");
|
const { Switch, Route, Link } = require("wouter");
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
const query = require("../../../lib/query");
|
const query = require("../../../lib/query");
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const ExpireRemote = require("./expireremote");
|
const ExpireRemote = require("./expireremote");
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
const query = require("../../../lib/query");
|
const query = require("../../../lib/query");
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const Cleanup = require("./cleanup");
|
const Cleanup = require("./cleanup");
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const splitFilterN = require("split-filter-n");
|
const splitFilterN = require("split-filter-n");
|
||||||
const syncpipe = require('syncpipe');
|
const syncpipe = require('syncpipe');
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const { useRoute, Link, Redirect } = require("wouter");
|
const { useRoute, Link, Redirect } = require("wouter");
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const { Switch, Route } = require("wouter");
|
const { Switch, Route } = require("wouter");
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
const query = require("../../../lib/query");
|
const query = require("../../../lib/query");
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const { Link } = require("wouter");
|
const { Link } = require("wouter");
|
||||||
const syncpipe = require("syncpipe");
|
const syncpipe = require("syncpipe");
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
const query = require("../../../lib/query");
|
const query = require("../../../lib/query");
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
const ParseFromToot = require("./parse-from-toot");
|
const ParseFromToot = require("./parse-from-toot");
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
const query = require("../../../lib/query");
|
const query = require("../../../lib/query");
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const { useRoute, Redirect, useLocation } = require("wouter");
|
const { useRoute, Redirect, useLocation } = require("wouter");
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
module.exports = function ExportFormatTable() {
|
module.exports = function ExportFormatTable() {
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
const query = require("../../../lib/query");
|
const query = require("../../../lib/query");
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const { Switch, Route, Redirect, useLocation } = require("wouter");
|
const { Switch, Route, Redirect, useLocation } = require("wouter");
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
const query = require("../../../lib/query");
|
const query = require("../../../lib/query");
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const { Switch, Route } = require("wouter");
|
const { Switch, Route } = require("wouter");
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const { Link, useLocation } = require("wouter");
|
const { Link, useLocation } = require("wouter");
|
||||||
const { matchSorter } = require("match-sorter");
|
const { matchSorter } = require("match-sorter");
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const { useRoute, Redirect } = require("wouter");
|
const { useRoute, Redirect } = require("wouter");
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const { Link, Switch, Route } = require("wouter");
|
const { Link, Switch, Route } = require("wouter");
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const { Link } = require("wouter");
|
const { Link } = require("wouter");
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
const query = require("../../lib/query");
|
const query = require("../../lib/query");
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const { Switch, Route, Link, Redirect, useRoute } = require("wouter");
|
const { Switch, Route, Link, Redirect, useRoute } = require("wouter");
|
||||||
|
|
||||||
|
|
|
@ -17,23 +17,25 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
import { useVerifyCredentialsQuery } from "../../lib/query/oauth";
|
||||||
|
import { store } from "../../redux/store";
|
||||||
|
|
||||||
const React = require("react");
|
import React from "react";
|
||||||
const Redux = require("react-redux");
|
|
||||||
|
|
||||||
const query = require("../../lib/query");
|
import Login from "./login";
|
||||||
|
import Loading from "../loading";
|
||||||
|
import { Error } from "../error";
|
||||||
|
|
||||||
const Login = require("./login");
|
export function Authorization({ App }) {
|
||||||
const Loading = require("../loading");
|
const { loginState, expectingRedirect } = store.getState().oauth;
|
||||||
const { Error } = require("../error");
|
const skip = (loginState == "none" || loginState == "logout" || expectingRedirect);
|
||||||
|
|
||||||
module.exports = function Authorization({ App }) {
|
const {
|
||||||
const { loginState, expectingRedirect } = Redux.useSelector((state) => state.oauth);
|
isLoading,
|
||||||
|
isSuccess,
|
||||||
const { isLoading, isSuccess, data: account, error } = query.useVerifyCredentialsQuery(undefined, {
|
data: account,
|
||||||
skip: loginState == "none" || loginState == "logout" || expectingRedirect
|
error,
|
||||||
});
|
} = useVerifyCredentialsQuery(null, { skip: skip });
|
||||||
|
|
||||||
let showLogin = true;
|
let showLogin = true;
|
||||||
let content = null;
|
let content = null;
|
||||||
|
@ -73,4 +75,4 @@ module.exports = function Authorization({ App }) {
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
}
|
|
@ -17,18 +17,16 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
import React from "react";
|
||||||
|
|
||||||
const React = require("react");
|
import { useAuthorizeFlowMutation } from "../../lib/query/oauth";
|
||||||
|
import { useTextInput, useValue } from "../../lib/form";
|
||||||
|
import useFormSubmit from "../../lib/form/submit";
|
||||||
|
import { TextInput } from "../form/inputs";
|
||||||
|
import MutationButton from "../form/mutation-button";
|
||||||
|
import Loading from "../loading";
|
||||||
|
|
||||||
const query = require("../../lib/query");
|
export default function Login({ }) {
|
||||||
const { useTextInput, useValue } = require("../../lib/form");
|
|
||||||
const useFormSubmit = require("../../lib/form/submit");
|
|
||||||
const { TextInput } = require("../form/inputs");
|
|
||||||
const MutationButton = require("../form/mutation-button");
|
|
||||||
const Loading = require("../loading");
|
|
||||||
|
|
||||||
module.exports = function Login({ }) {
|
|
||||||
const form = {
|
const form = {
|
||||||
instance: useTextInput("instance", {
|
instance: useTextInput("instance", {
|
||||||
defaultValue: window.location.origin
|
defaultValue: window.location.origin
|
||||||
|
@ -38,8 +36,11 @@ module.exports = function Login({ }) {
|
||||||
|
|
||||||
const [formSubmit, result] = useFormSubmit(
|
const [formSubmit, result] = useFormSubmit(
|
||||||
form,
|
form,
|
||||||
query.useAuthorizeFlowMutation(),
|
useAuthorizeFlowMutation(),
|
||||||
{ changedOnly: false }
|
{
|
||||||
|
changedOnly: false,
|
||||||
|
onFinish: undefined,
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result.isLoading) {
|
if (result.isLoading) {
|
||||||
|
@ -63,7 +64,11 @@ module.exports = function Login({ }) {
|
||||||
label="Instance"
|
label="Instance"
|
||||||
name="instance"
|
name="instance"
|
||||||
/>
|
/>
|
||||||
<MutationButton label="Login" result={result} />
|
<MutationButton
|
||||||
|
label="Login"
|
||||||
|
result={result}
|
||||||
|
disabled={false}
|
||||||
|
/>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
}
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const { Link } = require("wouter");
|
const { Link } = require("wouter");
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
module.exports = function CheckList({ field, header = "All", EntryComponent, getExtraProps }) {
|
module.exports = function CheckList({ field, header = "All", EntryComponent, getExtraProps }) {
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
function ErrorFallback({ error, resetErrorBoundary }) {
|
function ErrorFallback({ error, resetErrorBoundary }) {
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
module.exports = function FakeProfile({ avatar, header, display_name, username, role }) {
|
module.exports = function FakeProfile({ avatar, header, display_name, username, role }) {
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
const query = require("../lib/query");
|
const query = require("../lib/query");
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
function TextInput({ label, field, ...inputProps }) {
|
function TextInput({ label, field, ...inputProps }) {
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const { Error } = require("../error");
|
const { Error } = require("../error");
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const langs = require("langs");
|
const langs = require("langs");
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
module.exports = function Loading() {
|
module.exports = function Loading() {
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
const query = require("../lib/query");
|
const query = require("../lib/query");
|
||||||
|
|
|
@ -17,17 +17,15 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const ReactDom = require("react-dom/client");
|
const ReactDom = require("react-dom/client");
|
||||||
const { Provider } = require("react-redux");
|
const { Provider } = require("react-redux");
|
||||||
const { PersistGate } = require("redux-persist/integration/react");
|
const { PersistGate } = require("redux-persist/integration/react");
|
||||||
|
|
||||||
const { store, persistor } = require("./redux");
|
const { store, persistor } = require("./redux/store");
|
||||||
const { createNavigation, Menu, Item } = require("./lib/navigation");
|
const { createNavigation, Menu, Item } = require("./lib/navigation");
|
||||||
|
|
||||||
const AuthorizationGate = require("./components/authorization");
|
const { Authorization } = require("./components/authorization");
|
||||||
const Loading = require("./components/loading");
|
const Loading = require("./components/loading");
|
||||||
const UserLogoutCard = require("./components/user-logout-card");
|
const UserLogoutCard = require("./components/user-logout-card");
|
||||||
const { RoleContext } = require("./lib/navigation/util");
|
const { RoleContext } = require("./lib/navigation/util");
|
||||||
|
@ -90,7 +88,7 @@ function Main() {
|
||||||
return (
|
return (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<PersistGate loading={<section><Loading /></section>} persistor={persistor}>
|
<PersistGate loading={<section><Loading /></section>} persistor={persistor}>
|
||||||
<AuthorizationGate App={App} />
|
<Authorization App={App} />
|
||||||
</PersistGate>
|
</PersistGate>
|
||||||
</Provider>
|
</Provider>
|
||||||
);
|
);
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const isValidDomain = require("is-valid-domain");
|
const isValidDomain = require("is-valid-domain");
|
||||||
const psl = require("psl");
|
const psl = require("psl");
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
const _default = false;
|
const _default = false;
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const syncpipe = require("syncpipe");
|
const syncpipe = require("syncpipe");
|
||||||
const { createSlice } = require("@reduxjs/toolkit");
|
const { createSlice } = require("@reduxjs/toolkit");
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
const { useComboboxState } = require("ariakit/combobox");
|
const { useComboboxState } = require("ariakit/combobox");
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
const FormContext = React.createContext({});
|
const FormContext = React.createContext({});
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
const getFormMutations = require("./get-form-mutations");
|
const getFormMutations = require("./get-form-mutations");
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const prettierBytes = require("prettier-bytes");
|
const prettierBytes = require("prettier-bytes");
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const { Error } = require("../../components/error");
|
const { Error } = require("../../components/error");
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const syncpipe = require("syncpipe");
|
const syncpipe = require("syncpipe");
|
||||||
|
|
||||||
module.exports = function getFormMutations(form, { changedOnly }) {
|
module.exports = function getFormMutations(form, { changedOnly }) {
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const getByDot = require("get-by-dot").default;
|
const getByDot = require("get-by-dot").default;
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
const _default = "";
|
const _default = "";
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const Promise = require("bluebird");
|
const Promise = require("bluebird");
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const getFormMutations = require("./get-form-mutations");
|
const getFormMutations = require("./get-form-mutations");
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
const _default = "";
|
const _default = "";
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const { Link, Route, Redirect, Switch, useLocation, useRouter } = require("wouter");
|
const { Link, Route, Redirect, Switch, useLocation, useRouter } = require("wouter");
|
||||||
const syncpipe = require("syncpipe");
|
const syncpipe = require("syncpipe");
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const { nanoid } = require("nanoid");
|
const { nanoid } = require("nanoid");
|
||||||
const { Redirect } = require("wouter");
|
const { Redirect } = require("wouter");
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
const RoleContext = React.createContext([]);
|
const RoleContext = React.createContext([]);
|
||||||
const BaseUrlContext = React.createContext(null);
|
const BaseUrlContext = React.createContext(null);
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const Promise = require("bluebird");
|
const Promise = require("bluebird");
|
||||||
|
|
||||||
const { unwrapRes } = require("../lib");
|
const { unwrapRes } = require("../lib");
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const Promise = require("bluebird");
|
const Promise = require("bluebird");
|
||||||
const fileDownload = require("js-file-download");
|
const fileDownload = require("js-file-download");
|
||||||
const csv = require("papaparse");
|
const csv = require("papaparse");
|
||||||
|
|
|
@ -17,15 +17,13 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
replaceCacheOnMutation,
|
replaceCacheOnMutation,
|
||||||
removeFromCacheOnMutation,
|
removeFromCacheOnMutation,
|
||||||
domainListToObject,
|
domainListToObject,
|
||||||
idListToObject
|
idListToObject
|
||||||
} = require("../lib");
|
} = require("../lib");
|
||||||
const base = require("../base");
|
const { gtsApi } = require("../gts-api");
|
||||||
|
|
||||||
const endpoints = (build) => ({
|
const endpoints = (build) => ({
|
||||||
updateInstance: build.mutation({
|
updateInstance: build.mutation({
|
||||||
|
@ -164,4 +162,4 @@ const endpoints = (build) => ({
|
||||||
...require("./reports")(build)
|
...require("./reports")(build)
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = base.injectEndpoints({ endpoints });
|
module.exports = gtsApi.injectEndpoints({ endpoints });
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
module.exports = (build) => ({
|
module.exports = (build) => ({
|
||||||
listReports: build.query({
|
listReports: build.query({
|
||||||
query: (params = {}) => ({
|
query: (params = {}) => ({
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
/*
|
|
||||||
GoToSocial
|
|
||||||
Copyright (C) GoToSocial Authors admin@gotosocial.org
|
|
||||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Affero General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const { createApi, fetchBaseQuery } = require("@reduxjs/toolkit/query/react");
|
|
||||||
const { serialize: serializeForm } = require("object-to-formdata");
|
|
||||||
|
|
||||||
function instanceBasedQuery(args, api, extraOptions) {
|
|
||||||
const state = api.getState();
|
|
||||||
const { instance, token } = state.oauth;
|
|
||||||
|
|
||||||
if (args.baseUrl == undefined) {
|
|
||||||
args.baseUrl = instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.discardEmpty) {
|
|
||||||
if (args.body == undefined || Object.keys(args.body).length == 0) {
|
|
||||||
return { data: null };
|
|
||||||
}
|
|
||||||
delete args.discardEmpty;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.asForm) {
|
|
||||||
delete args.asForm;
|
|
||||||
args.body = serializeForm(args.body, {
|
|
||||||
indices: true, // Array indices, for profile fields
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return fetchBaseQuery({
|
|
||||||
baseUrl: args.baseUrl,
|
|
||||||
prepareHeaders: (headers) => {
|
|
||||||
if (token != undefined) {
|
|
||||||
headers.set('Authorization', token);
|
|
||||||
}
|
|
||||||
headers.set("Accept", "application/json");
|
|
||||||
return headers;
|
|
||||||
},
|
|
||||||
})(args, api, extraOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = createApi({
|
|
||||||
reducerPath: "api",
|
|
||||||
baseQuery: instanceBasedQuery,
|
|
||||||
tagTypes: ["Auth", "Emoji", "Reports", "Account", "InstanceRules"],
|
|
||||||
endpoints: (build) => ({
|
|
||||||
instance: build.query({
|
|
||||||
query: () => ({
|
|
||||||
url: `/api/v1/instance`
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
});
|
|
149
web/source/settings/lib/query/gts-api.ts
Normal file
149
web/source/settings/lib/query/gts-api.ts
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
/*
|
||||||
|
GoToSocial
|
||||||
|
Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
|
||||||
|
import type {
|
||||||
|
BaseQueryFn,
|
||||||
|
FetchArgs,
|
||||||
|
FetchBaseQueryError,
|
||||||
|
} from '@reduxjs/toolkit/query/react';
|
||||||
|
import { serialize as serializeForm } from "object-to-formdata";
|
||||||
|
|
||||||
|
import type { RootState } from '../../redux/store';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GTSFetchArgs extends standard FetchArgs used by
|
||||||
|
* RTK Query with a couple helpers of our own.
|
||||||
|
*/
|
||||||
|
export interface GTSFetchArgs extends FetchArgs {
|
||||||
|
/**
|
||||||
|
* If provided, will be used as base URL. Else,
|
||||||
|
* will fall back to authorized instance as baseUrl.
|
||||||
|
*/
|
||||||
|
baseUrl?: string;
|
||||||
|
/**
|
||||||
|
* If true, and no args.body is set, or args.body is empty,
|
||||||
|
* then a null response will be returned from the API call.
|
||||||
|
*/
|
||||||
|
discardEmpty?: boolean;
|
||||||
|
/**
|
||||||
|
* If true, then args.body will be serialized
|
||||||
|
* as FormData before submission.
|
||||||
|
*/
|
||||||
|
asForm?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtsBaseQuery wraps the redux toolkit fetchBaseQuery with some helper functionality.
|
||||||
|
*
|
||||||
|
* For an explainer of what's happening in this function, see:
|
||||||
|
* - https://redux-toolkit.js.org/rtk-query/usage/customizing-queries#customizing-queries-with-basequery
|
||||||
|
* - https://redux-toolkit.js.org/rtk-query/usage/customizing-queries#constructing-a-dynamic-base-url-using-redux-state
|
||||||
|
*
|
||||||
|
* @param args
|
||||||
|
* @param api
|
||||||
|
* @param extraOptions
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const gtsBaseQuery: BaseQueryFn<
|
||||||
|
string | GTSFetchArgs,
|
||||||
|
any,
|
||||||
|
FetchBaseQueryError
|
||||||
|
> = async (args, api, extraOptions) => {
|
||||||
|
// Retrieve state at the moment
|
||||||
|
// this function was called.
|
||||||
|
const state = api.getState() as RootState;
|
||||||
|
const { instanceUrl, token } = state.oauth;
|
||||||
|
|
||||||
|
// Derive baseUrl dynamically.
|
||||||
|
let baseUrl: string;
|
||||||
|
|
||||||
|
// Check if simple string baseUrl provided
|
||||||
|
// as args, or if more complex args provided.
|
||||||
|
if (typeof args === "string") {
|
||||||
|
baseUrl = args;
|
||||||
|
} else {
|
||||||
|
if (args.baseUrl != undefined) {
|
||||||
|
baseUrl = args.baseUrl;
|
||||||
|
} else {
|
||||||
|
baseUrl = instanceUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.discardEmpty) {
|
||||||
|
if (args.body == undefined || Object.keys(args.body).length == 0) {
|
||||||
|
return { data: null };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.asForm) {
|
||||||
|
args.body = serializeForm(args.body, {
|
||||||
|
// Array indices, for profile fields.
|
||||||
|
indices: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete any of our extended arguments
|
||||||
|
// to avoid confusing fetchBaseQuery.
|
||||||
|
delete args.baseUrl;
|
||||||
|
delete args.discardEmpty;
|
||||||
|
delete args.asForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!baseUrl) {
|
||||||
|
return {
|
||||||
|
error: {
|
||||||
|
status: 400,
|
||||||
|
statusText: 'Bad Request',
|
||||||
|
data: {"error":"No baseUrl set for request"},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return fetchBaseQuery({
|
||||||
|
baseUrl: baseUrl,
|
||||||
|
prepareHeaders: (headers) => {
|
||||||
|
if (token != undefined) {
|
||||||
|
headers.set('Authorization', token);
|
||||||
|
}
|
||||||
|
headers.set("Accept", "application/json");
|
||||||
|
return headers;
|
||||||
|
},
|
||||||
|
})(args, api, extraOptions);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const gtsApi = createApi({
|
||||||
|
reducerPath: "api",
|
||||||
|
baseQuery: gtsBaseQuery,
|
||||||
|
tagTypes: [
|
||||||
|
"Auth",
|
||||||
|
"Emoji",
|
||||||
|
"Reports",
|
||||||
|
"Account",
|
||||||
|
"InstanceRules",
|
||||||
|
],
|
||||||
|
endpoints: (builder) => ({
|
||||||
|
instance: builder.query<any, void>({
|
||||||
|
query: () => ({
|
||||||
|
url: `/api/v1/instance`
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
export const { useInstanceQuery } = gtsApi;
|
|
@ -17,11 +17,9 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
...require("./base"),
|
...require("./gts-api"),
|
||||||
...require("./oauth"),
|
...require("./oauth"),
|
||||||
...require("./user"),
|
...require("./user"),
|
||||||
...require("./admin")
|
...require("./admin")
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,10 +17,8 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const syncpipe = require("syncpipe");
|
const syncpipe = require("syncpipe");
|
||||||
const base = require("./base");
|
const { gtsApi } = require("./gts-api");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
unwrapRes(res) {
|
unwrapRes(res) {
|
||||||
|
@ -70,7 +68,7 @@ function makeCacheMutation(action) {
|
||||||
return {
|
return {
|
||||||
onQueryStarted: (_, { dispatch, queryFulfilled }) => {
|
onQueryStarted: (_, { dispatch, queryFulfilled }) => {
|
||||||
queryFulfilled.then(({ data: newData }) => {
|
queryFulfilled.then(({ data: newData }) => {
|
||||||
dispatch(base.util.updateQueryData(queryName, arg, (draft) => {
|
dispatch(gtsApi.util.updateQueryData(queryName, arg, (draft) => {
|
||||||
if (findKey != undefined) {
|
if (findKey != undefined) {
|
||||||
key = findKey(draft, newData);
|
key = findKey(draft, newData);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,160 +0,0 @@
|
||||||
/*
|
|
||||||
GoToSocial
|
|
||||||
Copyright (C) GoToSocial Authors admin@gotosocial.org
|
|
||||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Affero General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const Promise = require("bluebird");
|
|
||||||
|
|
||||||
const base = require("./base");
|
|
||||||
const { unwrapRes } = require("./lib");
|
|
||||||
const oauth = require("../../redux/oauth").actions;
|
|
||||||
|
|
||||||
function getSettingsURL() {
|
|
||||||
/* needed in case the settings interface isn't hosted at /settings but
|
|
||||||
some subpath like /gotosocial/settings. Other parts of the code don't
|
|
||||||
take this into account yet so mostly future-proofing.
|
|
||||||
|
|
||||||
Also drops anything past /settings/, because authorization urls that are too long
|
|
||||||
get rejected by GTS.
|
|
||||||
*/
|
|
||||||
let [pre, _past] = window.location.pathname.split("/settings");
|
|
||||||
return `${window.location.origin}${pre}/settings`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const SETTINGS_URL = getSettingsURL();
|
|
||||||
|
|
||||||
const endpoints = (build) => ({
|
|
||||||
verifyCredentials: build.query({
|
|
||||||
providesTags: (_res, error) =>
|
|
||||||
error == undefined
|
|
||||||
? ["Auth"]
|
|
||||||
: [],
|
|
||||||
queryFn: (_arg, api, _extraOpts, baseQuery) => {
|
|
||||||
const state = api.getState();
|
|
||||||
|
|
||||||
return Promise.try(() => {
|
|
||||||
// Process callback code first, if available
|
|
||||||
if (state.oauth.loginState == "callback") {
|
|
||||||
let urlParams = new URLSearchParams(window.location.search);
|
|
||||||
let code = urlParams.get("code");
|
|
||||||
|
|
||||||
if (code == undefined) {
|
|
||||||
throw {
|
|
||||||
message: "Waiting for callback, but no ?code= provided in url."
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
let app = state.oauth.registration;
|
|
||||||
|
|
||||||
if (app == undefined || app.client_id == undefined) {
|
|
||||||
throw {
|
|
||||||
message: "No stored registration data, can't finish login flow."
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return baseQuery({
|
|
||||||
method: "POST",
|
|
||||||
url: "/oauth/token",
|
|
||||||
body: {
|
|
||||||
client_id: app.client_id,
|
|
||||||
client_secret: app.client_secret,
|
|
||||||
redirect_uri: SETTINGS_URL,
|
|
||||||
grant_type: "authorization_code",
|
|
||||||
code: code
|
|
||||||
}
|
|
||||||
}).then(unwrapRes).then((token) => {
|
|
||||||
// remove ?code= from url
|
|
||||||
window.history.replaceState({}, document.title, window.location.pathname);
|
|
||||||
api.dispatch(oauth.setToken(token));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).then(() => {
|
|
||||||
return baseQuery({
|
|
||||||
url: `/api/v1/accounts/verify_credentials`
|
|
||||||
});
|
|
||||||
}).catch((e) => {
|
|
||||||
return { error: e };
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
authorizeFlow: build.mutation({
|
|
||||||
queryFn: (formData, api, _extraOpts, baseQuery) => {
|
|
||||||
let instance;
|
|
||||||
const state = api.getState();
|
|
||||||
|
|
||||||
return Promise.try(() => {
|
|
||||||
if (!formData.instance.startsWith("http")) {
|
|
||||||
formData.instance = `https://${formData.instance}`;
|
|
||||||
}
|
|
||||||
instance = new URL(formData.instance).origin;
|
|
||||||
|
|
||||||
const stored = state.oauth.instance;
|
|
||||||
if (stored?.instance == instance && stored.registration) {
|
|
||||||
return stored.registration;
|
|
||||||
}
|
|
||||||
|
|
||||||
return baseQuery({
|
|
||||||
method: "POST",
|
|
||||||
baseUrl: instance,
|
|
||||||
url: "/api/v1/apps",
|
|
||||||
body: {
|
|
||||||
client_name: "GoToSocial Settings",
|
|
||||||
scopes: formData.scopes,
|
|
||||||
redirect_uris: SETTINGS_URL,
|
|
||||||
website: SETTINGS_URL
|
|
||||||
}
|
|
||||||
}).then(unwrapRes).then((app) => {
|
|
||||||
app.scopes = formData.scopes;
|
|
||||||
|
|
||||||
api.dispatch(oauth.authorize({
|
|
||||||
instance: instance,
|
|
||||||
registration: app,
|
|
||||||
loginState: "callback",
|
|
||||||
expectingRedirect: true
|
|
||||||
}));
|
|
||||||
|
|
||||||
return app;
|
|
||||||
});
|
|
||||||
}).then((app) => {
|
|
||||||
let url = new URL(instance);
|
|
||||||
url.pathname = "/oauth/authorize";
|
|
||||||
url.searchParams.set("client_id", app.client_id);
|
|
||||||
url.searchParams.set("redirect_uri", SETTINGS_URL);
|
|
||||||
url.searchParams.set("response_type", "code");
|
|
||||||
url.searchParams.set("scope", app.scopes);
|
|
||||||
|
|
||||||
let redirectURL = url.toString();
|
|
||||||
window.location.assign(redirectURL);
|
|
||||||
|
|
||||||
return { data: null };
|
|
||||||
}).catch((e) => {
|
|
||||||
return { error: e };
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
logout: build.mutation({
|
|
||||||
queryFn: (_arg, api) => {
|
|
||||||
api.dispatch(oauth.remove());
|
|
||||||
return { data: null };
|
|
||||||
},
|
|
||||||
invalidatesTags: ["Auth"]
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = base.injectEndpoints({ endpoints });
|
|
204
web/source/settings/lib/query/oauth/index.ts
Normal file
204
web/source/settings/lib/query/oauth/index.ts
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
/*
|
||||||
|
GoToSocial
|
||||||
|
Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { FetchBaseQueryError } from '@reduxjs/toolkit/query';
|
||||||
|
|
||||||
|
import { gtsApi } from "../gts-api";
|
||||||
|
import {
|
||||||
|
setToken as oauthSetToken,
|
||||||
|
remove as oauthRemove,
|
||||||
|
authorize as oauthAuthorize,
|
||||||
|
} from "../../../redux/oauth";
|
||||||
|
import { RootState } from '../../../redux/store';
|
||||||
|
|
||||||
|
export interface OauthTokenRequestBody {
|
||||||
|
client_id: string;
|
||||||
|
client_secret: string;
|
||||||
|
redirect_uri: string;
|
||||||
|
grant_type: string;
|
||||||
|
code: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSettingsURL() {
|
||||||
|
/*
|
||||||
|
needed in case the settings interface isn't hosted at /settings but
|
||||||
|
some subpath like /gotosocial/settings. Other parts of the code don't
|
||||||
|
take this into account yet so mostly future-proofing.
|
||||||
|
|
||||||
|
Also drops anything past /settings/, because authorization urls that are too long
|
||||||
|
get rejected by GTS.
|
||||||
|
*/
|
||||||
|
let [pre, _past] = window.location.pathname.split("/settings");
|
||||||
|
return `${window.location.origin}${pre}/settings`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SETTINGS_URL = (getSettingsURL());
|
||||||
|
|
||||||
|
// Couple auth functions here require multiple requests as
|
||||||
|
// part of an OAuth token 'flow'. To keep things simple for
|
||||||
|
// callers of these query functions, the multiple requests
|
||||||
|
// are chained within one query.
|
||||||
|
//
|
||||||
|
// https://redux-toolkit.js.org/rtk-query/usage/customizing-queries#performing-multiple-requests-with-a-single-query
|
||||||
|
const extended = gtsApi.injectEndpoints({
|
||||||
|
endpoints: (builder) => ({
|
||||||
|
verifyCredentials: builder.query<any, void>({
|
||||||
|
providesTags: (_res, error) =>
|
||||||
|
error == undefined ? ["Auth"] : [],
|
||||||
|
async queryFn(_arg, api, _extraOpts, fetchWithBQ) {
|
||||||
|
const state = api.getState() as RootState;
|
||||||
|
const oauthState = state.oauth;
|
||||||
|
|
||||||
|
// If we're not in the middle of an auth/callback,
|
||||||
|
// we may already have an auth token, so just
|
||||||
|
// return a standard verify_credentials query.
|
||||||
|
if (oauthState.loginState != 'callback') {
|
||||||
|
return fetchWithBQ({
|
||||||
|
url: `/api/v1/accounts/verify_credentials`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// We're in the middle of an auth/callback flow.
|
||||||
|
// Try to retrieve callback code from URL query.
|
||||||
|
let urlParams = new URLSearchParams(window.location.search);
|
||||||
|
let code = urlParams.get("code");
|
||||||
|
if (code == undefined) {
|
||||||
|
return {
|
||||||
|
error: {
|
||||||
|
status: 400,
|
||||||
|
statusText: 'Bad Request',
|
||||||
|
data: {"error":"Waiting for callback, but no ?code= provided in url."},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve app with which the
|
||||||
|
// callback code was generated.
|
||||||
|
let app = oauthState.app;
|
||||||
|
if (app == undefined || app.client_id == undefined) {
|
||||||
|
return {
|
||||||
|
error: {
|
||||||
|
status: 400,
|
||||||
|
statusText: 'Bad Request',
|
||||||
|
data: {"error":"No stored app registration data, can't finish login flow."},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the provided code and app
|
||||||
|
// secret to request an auth token.
|
||||||
|
const tokenReqBody: OauthTokenRequestBody = {
|
||||||
|
client_id: app.client_id,
|
||||||
|
client_secret: app.client_secret,
|
||||||
|
redirect_uri: SETTINGS_URL,
|
||||||
|
grant_type: "authorization_code",
|
||||||
|
code: code
|
||||||
|
};
|
||||||
|
|
||||||
|
const tokenResult = await fetchWithBQ({
|
||||||
|
method: "POST",
|
||||||
|
url: "/oauth/token",
|
||||||
|
body: tokenReqBody,
|
||||||
|
});
|
||||||
|
if (tokenResult.error) {
|
||||||
|
return { error: tokenResult.error as FetchBaseQueryError };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove ?code= query param from
|
||||||
|
// url, we don't want it anymore.
|
||||||
|
window.history.replaceState({}, document.title, window.location.pathname);
|
||||||
|
|
||||||
|
// Store returned token in redux.
|
||||||
|
api.dispatch(oauthSetToken(tokenResult.data));
|
||||||
|
|
||||||
|
// We're now authed! So return
|
||||||
|
// standard verify_credentials query.
|
||||||
|
return fetchWithBQ({
|
||||||
|
url: `/api/v1/accounts/verify_credentials`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
authorizeFlow: builder.mutation({
|
||||||
|
async queryFn(formData, api, _extraOpts, fetchWithBQ) {
|
||||||
|
const state = api.getState() as RootState;
|
||||||
|
const oauthState = state.oauth;
|
||||||
|
|
||||||
|
let instanceUrl: string;
|
||||||
|
if (!formData.instance.startsWith("http")) {
|
||||||
|
formData.instance = `https://${formData.instance}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
instanceUrl = new URL(formData.instance).origin;
|
||||||
|
if (oauthState?.instanceUrl == instanceUrl && oauthState.app) {
|
||||||
|
return { data: oauthState.app };
|
||||||
|
}
|
||||||
|
|
||||||
|
const appResult = await fetchWithBQ({
|
||||||
|
method: "POST",
|
||||||
|
baseUrl: instanceUrl,
|
||||||
|
url: "/api/v1/apps",
|
||||||
|
body: {
|
||||||
|
client_name: "GoToSocial Settings",
|
||||||
|
scopes: formData.scopes,
|
||||||
|
redirect_uris: SETTINGS_URL,
|
||||||
|
website: SETTINGS_URL
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (appResult.error) {
|
||||||
|
return { error: appResult.error as FetchBaseQueryError };
|
||||||
|
}
|
||||||
|
|
||||||
|
let app = appResult.data as any;
|
||||||
|
|
||||||
|
app.scopes = formData.scopes;
|
||||||
|
api.dispatch(oauthAuthorize({
|
||||||
|
instanceUrl: instanceUrl,
|
||||||
|
app: app,
|
||||||
|
loginState: "callback",
|
||||||
|
expectingRedirect: true
|
||||||
|
}));
|
||||||
|
|
||||||
|
let url = new URL(instanceUrl);
|
||||||
|
url.pathname = "/oauth/authorize";
|
||||||
|
url.searchParams.set("client_id", app.client_id);
|
||||||
|
url.searchParams.set("redirect_uri", SETTINGS_URL);
|
||||||
|
url.searchParams.set("response_type", "code");
|
||||||
|
url.searchParams.set("scope", app.scopes);
|
||||||
|
|
||||||
|
let redirectURL = url.toString();
|
||||||
|
window.location.assign(redirectURL);
|
||||||
|
return { data: null };
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
logout: builder.mutation({
|
||||||
|
queryFn: (_arg, api) => {
|
||||||
|
api.dispatch(oauthRemove());
|
||||||
|
return { data: null };
|
||||||
|
},
|
||||||
|
invalidatesTags: ["Auth"]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
export const {
|
||||||
|
useVerifyCredentialsQuery,
|
||||||
|
useAuthorizeFlowMutation,
|
||||||
|
useLogoutMutation,
|
||||||
|
} = extended;
|
|
@ -17,29 +17,32 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
import { replaceCacheOnMutation } from "../lib";
|
||||||
|
import { gtsApi } from "../gts-api";
|
||||||
|
|
||||||
const { replaceCacheOnMutation } = require("./lib");
|
const extended = gtsApi.injectEndpoints({
|
||||||
const base = require("./base");
|
endpoints: (builder) => ({
|
||||||
|
updateCredentials: builder.mutation({
|
||||||
const endpoints = (build) => ({
|
query: (formData) => ({
|
||||||
updateCredentials: build.mutation({
|
method: "PATCH",
|
||||||
query: (formData) => ({
|
url: `/api/v1/accounts/update_credentials`,
|
||||||
method: "PATCH",
|
asForm: true,
|
||||||
url: `/api/v1/accounts/update_credentials`,
|
body: formData,
|
||||||
asForm: true,
|
discardEmpty: true
|
||||||
body: formData,
|
}),
|
||||||
discardEmpty: true
|
...replaceCacheOnMutation("verifyCredentials")
|
||||||
}),
|
}),
|
||||||
...replaceCacheOnMutation("verifyCredentials")
|
passwordChange: builder.mutation({
|
||||||
}),
|
query: (data) => ({
|
||||||
passwordChange: build.mutation({
|
method: "POST",
|
||||||
query: (data) => ({
|
url: `/api/v1/user/password_change`,
|
||||||
method: "POST",
|
body: data
|
||||||
url: `/api/v1/user/password_change`,
|
})
|
||||||
body: data
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = base.injectEndpoints({ endpoints });
|
export const {
|
||||||
|
useUpdateCredentialsMutation,
|
||||||
|
usePasswordChangeMutation,
|
||||||
|
} = extended;
|
|
@ -1,44 +0,0 @@
|
||||||
/*
|
|
||||||
GoToSocial
|
|
||||||
Copyright (C) GoToSocial Authors admin@gotosocial.org
|
|
||||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Affero General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const { createSlice } = require("@reduxjs/toolkit");
|
|
||||||
|
|
||||||
module.exports = createSlice({
|
|
||||||
name: "oauth",
|
|
||||||
initialState: {
|
|
||||||
loginState: 'none',
|
|
||||||
expectingRedirect: false
|
|
||||||
},
|
|
||||||
reducers: {
|
|
||||||
authorize: (state, { payload }) => {
|
|
||||||
return payload; // overrides state
|
|
||||||
},
|
|
||||||
setToken: (state, { payload }) => {
|
|
||||||
state.token = `${payload.token_type} ${payload.access_token}`;
|
|
||||||
state.loginState = "login";
|
|
||||||
},
|
|
||||||
remove: (state, { _payload }) => {
|
|
||||||
delete state.token;
|
|
||||||
delete state.registration;
|
|
||||||
state.loginState = "logout";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
89
web/source/settings/redux/oauth.ts
Normal file
89
web/source/settings/redux/oauth.ts
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
GoToSocial
|
||||||
|
Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { PayloadAction, createSlice } from "@reduxjs/toolkit";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OAuthToken represents a response
|
||||||
|
* to an OAuth token request.
|
||||||
|
*/
|
||||||
|
export interface OAuthToken {
|
||||||
|
/**
|
||||||
|
* Most likely to be 'Bearer'
|
||||||
|
* but may be something else.
|
||||||
|
*/
|
||||||
|
token_type: string;
|
||||||
|
/**
|
||||||
|
* The actual token. Can be passed in to
|
||||||
|
* authenticate further requests using the
|
||||||
|
* Authorization header and the token type.
|
||||||
|
*/
|
||||||
|
access_token: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OAuthApp {
|
||||||
|
client_id: string;
|
||||||
|
client_secret: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OAuthState {
|
||||||
|
instanceUrl?: string;
|
||||||
|
loginState: "none" | "callback" | "login" | "logout";
|
||||||
|
expectingRedirect: boolean;
|
||||||
|
/**
|
||||||
|
* Token stored in easy-to-use format.
|
||||||
|
* Will look something like:
|
||||||
|
* "Authorization: Bearer BLAHBLAHBLAH"
|
||||||
|
*/
|
||||||
|
token?: string;
|
||||||
|
app?: OAuthApp;
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialState: OAuthState = {
|
||||||
|
loginState: 'none',
|
||||||
|
expectingRedirect: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const oauthSlice = createSlice({
|
||||||
|
name: "oauth",
|
||||||
|
initialState: initialState,
|
||||||
|
reducers: {
|
||||||
|
authorize: (_state, action: PayloadAction<OAuthState>) => {
|
||||||
|
// Overrides state with payload.
|
||||||
|
return action.payload;
|
||||||
|
},
|
||||||
|
setToken: (state, action: PayloadAction<OAuthToken>) => {
|
||||||
|
// Mark us as logged in by storing token.
|
||||||
|
state.token = `${action.payload.token_type} ${action.payload.access_token}`;
|
||||||
|
state.loginState = "login";
|
||||||
|
},
|
||||||
|
remove: (state) => {
|
||||||
|
// Mark us as logged out by clearing auth.
|
||||||
|
delete state.token;
|
||||||
|
delete state.app;
|
||||||
|
state.loginState = "logout";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const {
|
||||||
|
authorize,
|
||||||
|
setToken,
|
||||||
|
remove,
|
||||||
|
} = oauthSlice.actions;
|
|
@ -17,11 +17,9 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
import { combineReducers } from "redux";
|
||||||
|
import { configureStore } from "@reduxjs/toolkit";
|
||||||
const { combineReducers } = require("redux");
|
import {
|
||||||
const { configureStore } = require("@reduxjs/toolkit");
|
|
||||||
const {
|
|
||||||
persistStore,
|
persistStore,
|
||||||
persistReducer,
|
persistReducer,
|
||||||
FLUSH,
|
FLUSH,
|
||||||
|
@ -30,14 +28,14 @@ const {
|
||||||
PERSIST,
|
PERSIST,
|
||||||
PURGE,
|
PURGE,
|
||||||
REGISTER,
|
REGISTER,
|
||||||
} = require("redux-persist");
|
} from "redux-persist";
|
||||||
|
|
||||||
const query = require("../lib/query/base");
|
import { oauthSlice } from "./oauth";
|
||||||
const { Promise } = require("bluebird");
|
import { gtsApi } from "../lib/query/gts-api";
|
||||||
|
|
||||||
const combinedReducers = combineReducers({
|
const combinedReducers = combineReducers({
|
||||||
oauth: require("./oauth").reducer,
|
[gtsApi.reducerPath]: gtsApi.reducer,
|
||||||
[query.reducerPath]: query.reducer
|
oauth: oauthSlice.reducer,
|
||||||
});
|
});
|
||||||
|
|
||||||
const persistedReducer = persistReducer({
|
const persistedReducer = persistReducer({
|
||||||
|
@ -45,27 +43,41 @@ const persistedReducer = persistReducer({
|
||||||
storage: require("redux-persist/lib/storage").default,
|
storage: require("redux-persist/lib/storage").default,
|
||||||
stateReconciler: require("redux-persist/lib/stateReconciler/autoMergeLevel1").default,
|
stateReconciler: require("redux-persist/lib/stateReconciler/autoMergeLevel1").default,
|
||||||
whitelist: ["oauth"],
|
whitelist: ["oauth"],
|
||||||
migrate: (state) => {
|
migrate: async (state) => {
|
||||||
return Promise.try(() => {
|
if (state == undefined) {
|
||||||
if (state?.oauth != undefined) {
|
|
||||||
state.oauth.expectingRedirect = false;
|
|
||||||
}
|
|
||||||
return state;
|
return state;
|
||||||
});
|
}
|
||||||
|
|
||||||
|
// This is a cheeky workaround for
|
||||||
|
// redux-persist being a stickler.
|
||||||
|
let anyState = state as any;
|
||||||
|
if (anyState?.oauth != undefined) {
|
||||||
|
anyState.oauth.expectingRedirect = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return anyState;
|
||||||
}
|
}
|
||||||
}, combinedReducers);
|
}, combinedReducers);
|
||||||
|
|
||||||
const store = configureStore({
|
export const store = configureStore({
|
||||||
reducer: persistedReducer,
|
reducer: persistedReducer,
|
||||||
middleware: (getDefaultMiddleware) => {
|
middleware: (getDefaultMiddleware) => {
|
||||||
return getDefaultMiddleware({
|
return getDefaultMiddleware({
|
||||||
serializableCheck: {
|
serializableCheck: {
|
||||||
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER]
|
ignoredActions: [
|
||||||
|
FLUSH,
|
||||||
|
REHYDRATE,
|
||||||
|
PAUSE,
|
||||||
|
PERSIST,
|
||||||
|
PURGE,
|
||||||
|
REGISTER,
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}).concat(query.middleware);
|
}).concat(gtsApi.middleware);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const persistor = persistStore(store);
|
export const persistor = persistStore(store);
|
||||||
|
|
||||||
module.exports = { store, persistor };
|
export type AppDispatch = typeof store.dispatch;
|
||||||
|
export type RootState = ReturnType<typeof store.getState>;
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
const query = require("../lib/query");
|
const query = require("../lib/query");
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const React = require("react");
|
const React = require("react");
|
||||||
|
|
||||||
const query = require("../lib/query");
|
const query = require("../lib/query");
|
||||||
|
|
109
web/source/tsconfig.json
Normal file
109
web/source/tsconfig.json
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
/* Visit https://aka.ms/tsconfig to read more about this file */
|
||||||
|
|
||||||
|
/* Projects */
|
||||||
|
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
|
||||||
|
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
||||||
|
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
|
||||||
|
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
|
||||||
|
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
||||||
|
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
||||||
|
|
||||||
|
/* Language and Environment */
|
||||||
|
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
||||||
|
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||||
|
"jsx": "react" , /* Specify what JSX code is generated. */
|
||||||
|
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
|
||||||
|
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||||
|
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
|
||||||
|
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
||||||
|
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
|
||||||
|
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
|
||||||
|
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
||||||
|
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
||||||
|
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
|
||||||
|
|
||||||
|
/* Modules */
|
||||||
|
"module": "commonjs", /* Specify what module code is generated. */
|
||||||
|
// "rootDir": "./", /* Specify the root folder within your source files. */
|
||||||
|
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
|
||||||
|
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
||||||
|
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||||
|
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||||
|
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
|
||||||
|
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
||||||
|
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||||
|
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
|
||||||
|
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
|
||||||
|
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
|
||||||
|
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
|
||||||
|
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
|
||||||
|
// "resolveJsonModule": true, /* Enable importing .json files. */
|
||||||
|
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
|
||||||
|
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
|
||||||
|
|
||||||
|
/* JavaScript Support */
|
||||||
|
"allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
|
||||||
|
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
||||||
|
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
||||||
|
|
||||||
|
/* Emit */
|
||||||
|
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
||||||
|
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||||
|
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||||
|
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
||||||
|
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
||||||
|
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
||||||
|
// "outDir": "./", /* Specify an output folder for all emitted files. */
|
||||||
|
// "removeComments": true, /* Disable emitting comments. */
|
||||||
|
"noEmit": true, /* Disable emitting files from a compilation. */
|
||||||
|
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
||||||
|
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
|
||||||
|
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
||||||
|
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
||||||
|
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||||
|
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
||||||
|
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
||||||
|
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
||||||
|
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
|
||||||
|
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
|
||||||
|
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
||||||
|
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
|
||||||
|
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
||||||
|
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
||||||
|
|
||||||
|
/* Interop Constraints */
|
||||||
|
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
||||||
|
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
|
||||||
|
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
||||||
|
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
|
||||||
|
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
||||||
|
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
|
||||||
|
|
||||||
|
/* Type Checking */
|
||||||
|
"strict": false, /* Enable all strict type-checking options. */
|
||||||
|
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
|
||||||
|
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
|
||||||
|
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
||||||
|
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
|
||||||
|
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
||||||
|
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
|
||||||
|
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
|
||||||
|
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
||||||
|
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
|
||||||
|
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
|
||||||
|
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
||||||
|
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
||||||
|
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
||||||
|
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
|
||||||
|
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
||||||
|
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
|
||||||
|
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
||||||
|
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
||||||
|
|
||||||
|
/* Completeness */
|
||||||
|
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
||||||
|
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||||
|
}
|
||||||
|
}
|
2753
web/source/yarn.lock
2753
web/source/yarn.lock
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue