mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-01 18:40:18 +08:00
feat: change CRLF to LF for some files
This commit is contained in:
8
.gitattributes
vendored
8
.gitattributes
vendored
@ -1,5 +1,5 @@
|
|||||||
*.go linguist-detectable=true
|
*.go linguist-detectable=true
|
||||||
*.js linguist-detectable=false
|
*.js linguist-detectable=false
|
||||||
# Declare files that will always have LF line endings on checkout.
|
# Declare files that will always have LF line endings on checkout.
|
||||||
# Git will always convert line endings to LF on checkout. You should use this for files that must keep LF endings, even on Windows.
|
# Git will always convert line endings to LF on checkout. You should use this for files that must keep LF endings, even on Windows.
|
||||||
*.sh text eol=lf
|
*.sh text eol=lf
|
204
README.md
204
README.md
@ -1,102 +1,102 @@
|
|||||||
<h1 align="center" style="border-bottom: none;">📦⚡️ Casdoor</h1>
|
<h1 align="center" style="border-bottom: none;">📦⚡️ Casdoor</h1>
|
||||||
<h3 align="center">An open-source UI-first Identity and Access Management (IAM) / Single-Sign-On (SSO) platform with web UI supporting OAuth 2.0, OIDC, SAML, CAS, LDAP, SCIM, WebAuthn, TOTP, MFA and RADIUS</h3>
|
<h3 align="center">An open-source UI-first Identity and Access Management (IAM) / Single-Sign-On (SSO) platform with web UI supporting OAuth 2.0, OIDC, SAML, CAS, LDAP, SCIM, WebAuthn, TOTP, MFA and RADIUS</h3>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="#badge">
|
<a href="#badge">
|
||||||
<img alt="semantic-release" src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg">
|
<img alt="semantic-release" src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://hub.docker.com/r/casbin/casdoor">
|
<a href="https://hub.docker.com/r/casbin/casdoor">
|
||||||
<img alt="docker pull casbin/casdoor" src="https://img.shields.io/docker/pulls/casbin/casdoor.svg">
|
<img alt="docker pull casbin/casdoor" src="https://img.shields.io/docker/pulls/casbin/casdoor.svg">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/casdoor/casdoor/actions/workflows/build.yml">
|
<a href="https://github.com/casdoor/casdoor/actions/workflows/build.yml">
|
||||||
<img alt="GitHub Workflow Status (branch)" src="https://github.com/casdoor/casdoor/workflows/Build/badge.svg?style=flat-square">
|
<img alt="GitHub Workflow Status (branch)" src="https://github.com/casdoor/casdoor/workflows/Build/badge.svg?style=flat-square">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/casdoor/casdoor/releases/latest">
|
<a href="https://github.com/casdoor/casdoor/releases/latest">
|
||||||
<img alt="GitHub Release" src="https://img.shields.io/github/v/release/casdoor/casdoor.svg">
|
<img alt="GitHub Release" src="https://img.shields.io/github/v/release/casdoor/casdoor.svg">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://hub.docker.com/r/casbin/casdoor">
|
<a href="https://hub.docker.com/r/casbin/casdoor">
|
||||||
<img alt="Docker Image Version (latest semver)" src="https://img.shields.io/badge/Docker%20Hub-latest-brightgreen">
|
<img alt="Docker Image Version (latest semver)" src="https://img.shields.io/badge/Docker%20Hub-latest-brightgreen">
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://goreportcard.com/report/github.com/casdoor/casdoor">
|
<a href="https://goreportcard.com/report/github.com/casdoor/casdoor">
|
||||||
<img alt="Go Report Card" src="https://goreportcard.com/badge/github.com/casdoor/casdoor?style=flat-square">
|
<img alt="Go Report Card" src="https://goreportcard.com/badge/github.com/casdoor/casdoor?style=flat-square">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/casdoor/casdoor/blob/master/LICENSE">
|
<a href="https://github.com/casdoor/casdoor/blob/master/LICENSE">
|
||||||
<img src="https://img.shields.io/github/license/casdoor/casdoor?style=flat-square" alt="license">
|
<img src="https://img.shields.io/github/license/casdoor/casdoor?style=flat-square" alt="license">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/casdoor/casdoor/issues">
|
<a href="https://github.com/casdoor/casdoor/issues">
|
||||||
<img alt="GitHub issues" src="https://img.shields.io/github/issues/casdoor/casdoor?style=flat-square">
|
<img alt="GitHub issues" src="https://img.shields.io/github/issues/casdoor/casdoor?style=flat-square">
|
||||||
</a>
|
</a>
|
||||||
<a href="#">
|
<a href="#">
|
||||||
<img alt="GitHub stars" src="https://img.shields.io/github/stars/casdoor/casdoor?style=flat-square">
|
<img alt="GitHub stars" src="https://img.shields.io/github/stars/casdoor/casdoor?style=flat-square">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/casdoor/casdoor/network">
|
<a href="https://github.com/casdoor/casdoor/network">
|
||||||
<img alt="GitHub forks" src="https://img.shields.io/github/forks/casdoor/casdoor?style=flat-square">
|
<img alt="GitHub forks" src="https://img.shields.io/github/forks/casdoor/casdoor?style=flat-square">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://crowdin.com/project/casdoor-site">
|
<a href="https://crowdin.com/project/casdoor-site">
|
||||||
<img alt="Crowdin" src="https://badges.crowdin.net/casdoor-site/localized.svg">
|
<img alt="Crowdin" src="https://badges.crowdin.net/casdoor-site/localized.svg">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://discord.gg/5rPsrAzK7S">
|
<a href="https://discord.gg/5rPsrAzK7S">
|
||||||
<img alt="Discord" src="https://img.shields.io/discord/1022748306096537660?style=flat-square&logo=discord&label=discord&color=5865F2">
|
<img alt="Discord" src="https://img.shields.io/discord/1022748306096537660?style=flat-square&logo=discord&label=discord&color=5865F2">
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<sup>Sponsored by</sup>
|
<sup>Sponsored by</sup>
|
||||||
<br>
|
<br>
|
||||||
<a href="https://stytch.com/docs?utm_source=oss-sponsorship&utm_medium=paid_sponsorship&utm_campaign=casbin">
|
<a href="https://stytch.com/docs?utm_source=oss-sponsorship&utm_medium=paid_sponsorship&utm_campaign=casbin">
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(prefers-color-scheme: dark)" srcset="https://cdn.casbin.org/img/stytch-white.png">
|
<source media="(prefers-color-scheme: dark)" srcset="https://cdn.casbin.org/img/stytch-white.png">
|
||||||
<source media="(prefers-color-scheme: light)" srcset="https://cdn.casbin.org/img/stytch-charcoal.png">
|
<source media="(prefers-color-scheme: light)" srcset="https://cdn.casbin.org/img/stytch-charcoal.png">
|
||||||
<img src="https://cdn.casbin.org/img/stytch-charcoal.png" width="275">
|
<img src="https://cdn.casbin.org/img/stytch-charcoal.png" width="275">
|
||||||
</picture>
|
</picture>
|
||||||
</a><br/>
|
</a><br/>
|
||||||
<a href="https://stytch.com/docs?utm_source=oss-sponsorship&utm_medium=paid_sponsorship&utm_campaign=casbin"><b>Build auth with fraud prevention, faster.</b><br/> Try Stytch for API-first authentication, user & org management, multi-tenant SSO, MFA, device fingerprinting, and more.</a>
|
<a href="https://stytch.com/docs?utm_source=oss-sponsorship&utm_medium=paid_sponsorship&utm_campaign=casbin"><b>Build auth with fraud prevention, faster.</b><br/> Try Stytch for API-first authentication, user & org management, multi-tenant SSO, MFA, device fingerprinting, and more.</a>
|
||||||
<br>
|
<br>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
## Online demo
|
## Online demo
|
||||||
|
|
||||||
- Read-only site: https://door.casdoor.com (any modification operation will fail)
|
- Read-only site: https://door.casdoor.com (any modification operation will fail)
|
||||||
- Writable site: https://demo.casdoor.com (original data will be restored for every 5 minutes)
|
- Writable site: https://demo.casdoor.com (original data will be restored for every 5 minutes)
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
https://casdoor.org
|
https://casdoor.org
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
- By source code: https://casdoor.org/docs/basic/server-installation
|
- By source code: https://casdoor.org/docs/basic/server-installation
|
||||||
- By Docker: https://casdoor.org/docs/basic/try-with-docker
|
- By Docker: https://casdoor.org/docs/basic/try-with-docker
|
||||||
- By Kubernetes Helm: https://casdoor.org/docs/basic/try-with-helm
|
- By Kubernetes Helm: https://casdoor.org/docs/basic/try-with-helm
|
||||||
|
|
||||||
## How to connect to Casdoor?
|
## How to connect to Casdoor?
|
||||||
|
|
||||||
https://casdoor.org/docs/how-to-connect/overview
|
https://casdoor.org/docs/how-to-connect/overview
|
||||||
|
|
||||||
## Casdoor Public API
|
## Casdoor Public API
|
||||||
|
|
||||||
- Docs: https://casdoor.org/docs/basic/public-api
|
- Docs: https://casdoor.org/docs/basic/public-api
|
||||||
- Swagger: https://door.casdoor.com/swagger
|
- Swagger: https://door.casdoor.com/swagger
|
||||||
|
|
||||||
## Integrations
|
## Integrations
|
||||||
|
|
||||||
https://casdoor.org/docs/category/integrations
|
https://casdoor.org/docs/category/integrations
|
||||||
|
|
||||||
## How to contact?
|
## How to contact?
|
||||||
|
|
||||||
- Discord: https://discord.gg/5rPsrAzK7S
|
- Discord: https://discord.gg/5rPsrAzK7S
|
||||||
- Contact: https://casdoor.org/help
|
- Contact: https://casdoor.org/help
|
||||||
|
|
||||||
## Contribute
|
## Contribute
|
||||||
|
|
||||||
For casdoor, if you have any questions, you can give Issues, or you can also directly start Pull Requests(but we recommend giving issues first to communicate with the community).
|
For casdoor, if you have any questions, you can give Issues, or you can also directly start Pull Requests(but we recommend giving issues first to communicate with the community).
|
||||||
|
|
||||||
### I18n translation
|
### I18n translation
|
||||||
|
|
||||||
If you are contributing to casdoor, please note that we use [Crowdin](https://crowdin.com/project/casdoor-site) as translating platform and i18next as translating tool. When you add some words using i18next in the `web/` directory, please remember to add what you have added to the `web/src/locales/en/data.json` file.
|
If you are contributing to casdoor, please note that we use [Crowdin](https://crowdin.com/project/casdoor-site) as translating platform and i18next as translating tool. When you add some words using i18next in the `web/` directory, please remember to add what you have added to the `web/src/locales/en/data.json` file.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
[Apache-2.0](https://github.com/casdoor/casdoor/blob/master/LICENSE)
|
[Apache-2.0](https://github.com/casdoor/casdoor/blob/master/LICENSE)
|
||||||
|
@ -1,97 +1,97 @@
|
|||||||
const CracoLessPlugin = require("craco-less");
|
const CracoLessPlugin = require("craco-less");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
devServer: {
|
devServer: {
|
||||||
proxy: {
|
proxy: {
|
||||||
"/api": {
|
"/api": {
|
||||||
target: "http://localhost:8000",
|
target: "http://localhost:8000",
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
},
|
},
|
||||||
"/swagger": {
|
"/swagger": {
|
||||||
target: "http://localhost:8000",
|
target: "http://localhost:8000",
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
},
|
},
|
||||||
"/files": {
|
"/files": {
|
||||||
target: "http://localhost:8000",
|
target: "http://localhost:8000",
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
},
|
},
|
||||||
"/.well-known/openid-configuration": {
|
"/.well-known/openid-configuration": {
|
||||||
target: "http://localhost:8000",
|
target: "http://localhost:8000",
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
},
|
},
|
||||||
"/cas/serviceValidate": {
|
"/cas/serviceValidate": {
|
||||||
target: "http://localhost:8000",
|
target: "http://localhost:8000",
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
},
|
},
|
||||||
"/cas/proxyValidate": {
|
"/cas/proxyValidate": {
|
||||||
target: "http://localhost:8000",
|
target: "http://localhost:8000",
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
},
|
},
|
||||||
"/cas/proxy": {
|
"/cas/proxy": {
|
||||||
target: "http://localhost:8000",
|
target: "http://localhost:8000",
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
},
|
},
|
||||||
"/cas/validate": {
|
"/cas/validate": {
|
||||||
target: "http://localhost:8000",
|
target: "http://localhost:8000",
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
},
|
},
|
||||||
"/scim": {
|
"/scim": {
|
||||||
target: "http://localhost:8000",
|
target: "http://localhost:8000",
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
{
|
{
|
||||||
plugin: CracoLessPlugin,
|
plugin: CracoLessPlugin,
|
||||||
options: {
|
options: {
|
||||||
lessLoaderOptions: {
|
lessLoaderOptions: {
|
||||||
lessOptions: {
|
lessOptions: {
|
||||||
modifyVars: {"@primary-color": "rgb(89,54,213)", "@border-radius-base": "5px"},
|
modifyVars: {"@primary-color": "rgb(89,54,213)", "@border-radius-base": "5px"},
|
||||||
javascriptEnabled: true,
|
javascriptEnabled: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
webpack: {
|
webpack: {
|
||||||
configure: (webpackConfig, { env, paths }) => {
|
configure: (webpackConfig, { env, paths }) => {
|
||||||
paths.appBuild = path.resolve(__dirname, "build-temp");
|
paths.appBuild = path.resolve(__dirname, "build-temp");
|
||||||
webpackConfig.output.path = path.resolve(__dirname, "build-temp");
|
webpackConfig.output.path = path.resolve(__dirname, "build-temp");
|
||||||
|
|
||||||
// ignore webpack warnings by source-map-loader
|
// ignore webpack warnings by source-map-loader
|
||||||
// https://github.com/facebook/create-react-app/pull/11752#issuecomment-1345231546
|
// https://github.com/facebook/create-react-app/pull/11752#issuecomment-1345231546
|
||||||
webpackConfig.ignoreWarnings = [
|
webpackConfig.ignoreWarnings = [
|
||||||
function ignoreSourcemapsloaderWarnings(warning) {
|
function ignoreSourcemapsloaderWarnings(warning) {
|
||||||
return (
|
return (
|
||||||
warning.module &&
|
warning.module &&
|
||||||
warning.module.resource.includes("node_modules") &&
|
warning.module.resource.includes("node_modules") &&
|
||||||
warning.details &&
|
warning.details &&
|
||||||
warning.details.includes("source-map-loader")
|
warning.details.includes("source-map-loader")
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
// use polyfill Buffer with Webpack 5
|
// use polyfill Buffer with Webpack 5
|
||||||
// https://viglucci.io/articles/how-to-polyfill-buffer-with-webpack-5
|
// https://viglucci.io/articles/how-to-polyfill-buffer-with-webpack-5
|
||||||
// https://craco.js.org/docs/configuration/webpack/
|
// https://craco.js.org/docs/configuration/webpack/
|
||||||
webpackConfig.resolve.fallback = {
|
webpackConfig.resolve.fallback = {
|
||||||
buffer: require.resolve("buffer/"),
|
buffer: require.resolve("buffer/"),
|
||||||
process: false,
|
process: false,
|
||||||
util: false,
|
util: false,
|
||||||
url: false,
|
url: false,
|
||||||
zlib: false,
|
zlib: false,
|
||||||
stream: false,
|
stream: false,
|
||||||
http: false,
|
http: false,
|
||||||
https: false,
|
https: false,
|
||||||
assert: false,
|
assert: false,
|
||||||
crypto: false,
|
crypto: false,
|
||||||
os: false,
|
os: false,
|
||||||
fs: false,
|
fs: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
return webpackConfig;
|
return webpackConfig;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
42
web/mv.js
42
web/mv.js
@ -1,21 +1,21 @@
|
|||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
|
||||||
const sourceDir = path.join(__dirname, "build-temp");
|
const sourceDir = path.join(__dirname, "build-temp");
|
||||||
const targetDir = path.join(__dirname, "build");
|
const targetDir = path.join(__dirname, "build");
|
||||||
|
|
||||||
if (!fs.existsSync(sourceDir)) {
|
if (!fs.existsSync(sourceDir)) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.error(`Source directory "${sourceDir}" does not exist.`);
|
console.error(`Source directory "${sourceDir}" does not exist.`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fs.existsSync(targetDir)) {
|
if (fs.existsSync(targetDir)) {
|
||||||
fs.rmSync(targetDir, {recursive: true, force: true});
|
fs.rmSync(targetDir, {recursive: true, force: true});
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(`Target directory "${targetDir}" has been deleted successfully.`);
|
console.log(`Target directory "${targetDir}" has been deleted successfully.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.renameSync(sourceDir, targetDir);
|
fs.renameSync(sourceDir, targetDir);
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(`Renamed "${sourceDir}" to "${targetDir}" successfully.`);
|
console.log(`Renamed "${sourceDir}" to "${targetDir}" successfully.`);
|
||||||
|
@ -1,36 +1,36 @@
|
|||||||
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
|
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
export const DefaultApplication = "app-built-in";
|
export const DefaultApplication = "app-built-in";
|
||||||
|
|
||||||
export const CasvisorUrl = "";
|
export const CasvisorUrl = "";
|
||||||
|
|
||||||
export const ShowGithubCorner = false;
|
export const ShowGithubCorner = false;
|
||||||
export const IsDemoMode = false;
|
export const IsDemoMode = false;
|
||||||
|
|
||||||
export const ForceLanguage = "";
|
export const ForceLanguage = "";
|
||||||
export const DefaultLanguage = "en";
|
export const DefaultLanguage = "en";
|
||||||
|
|
||||||
export const InitThemeAlgorithm = true;
|
export const InitThemeAlgorithm = true;
|
||||||
export const ThemeDefault = {
|
export const ThemeDefault = {
|
||||||
themeType: "default",
|
themeType: "default",
|
||||||
colorPrimary: "#5734d3",
|
colorPrimary: "#5734d3",
|
||||||
borderRadius: 6,
|
borderRadius: 6,
|
||||||
isCompact: false,
|
isCompact: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CustomFooter = null;
|
export const CustomFooter = null;
|
||||||
|
|
||||||
// Blank or null to hide Ai Assistant button
|
// Blank or null to hide Ai Assistant button
|
||||||
export const AiAssistantUrl = "https://ai.casbin.com";
|
export const AiAssistantUrl = "https://ai.casbin.com";
|
||||||
|
@ -1,341 +1,341 @@
|
|||||||
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
|
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {Button, Image, Table, Upload} from "antd";
|
import {Button, Image, Table, Upload} from "antd";
|
||||||
import {UploadOutlined} from "@ant-design/icons";
|
import {UploadOutlined} from "@ant-design/icons";
|
||||||
import copy from "copy-to-clipboard";
|
import copy from "copy-to-clipboard";
|
||||||
import * as Setting from "./Setting";
|
import * as Setting from "./Setting";
|
||||||
import * as ResourceBackend from "./backend/ResourceBackend";
|
import * as ResourceBackend from "./backend/ResourceBackend";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import {Link} from "react-router-dom";
|
import {Link} from "react-router-dom";
|
||||||
import BaseListPage from "./BaseListPage";
|
import BaseListPage from "./BaseListPage";
|
||||||
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
||||||
|
|
||||||
class ResourceListPage extends BaseListPage {
|
class ResourceListPage extends BaseListPage {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.setState({
|
this.setState({
|
||||||
fileList: [],
|
fileList: [],
|
||||||
uploading: false,
|
uploading: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteResource(i) {
|
deleteResource(i) {
|
||||||
ResourceBackend.deleteResource(this.state.data[i])
|
ResourceBackend.deleteResource(this.state.data[i])
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||||
this.fetch({
|
this.fetch({
|
||||||
pagination: {
|
pagination: {
|
||||||
...this.state.pagination,
|
...this.state.pagination,
|
||||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
|
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleUpload(info) {
|
handleUpload(info) {
|
||||||
this.setState({uploading: true});
|
this.setState({uploading: true});
|
||||||
const filename = info.fileList[0].name;
|
const filename = info.fileList[0].name;
|
||||||
const fullFilePath = `resource/${this.props.account.owner}/${this.props.account.name}/${filename}`;
|
const fullFilePath = `resource/${this.props.account.owner}/${this.props.account.name}/${filename}`;
|
||||||
ResourceBackend.uploadResource(this.props.account.owner, this.props.account.name, "custom", "ResourceListPage", fullFilePath, info.file)
|
ResourceBackend.uploadResource(this.props.account.owner, this.props.account.name, "custom", "ResourceListPage", fullFilePath, info.file)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
Setting.showMessage("success", i18next.t("application:File uploaded successfully"));
|
Setting.showMessage("success", i18next.t("application:File uploaded successfully"));
|
||||||
|
|
||||||
const {pagination} = this.state;
|
const {pagination} = this.state;
|
||||||
this.fetch({pagination});
|
this.fetch({pagination});
|
||||||
} else {
|
} else {
|
||||||
Setting.showMessage("error", res.msg);
|
Setting.showMessage("error", res.msg);
|
||||||
}
|
}
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
this.setState({uploading: false});
|
this.setState({uploading: false});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
renderUpload() {
|
renderUpload() {
|
||||||
return (
|
return (
|
||||||
<Upload maxCount={1} accept="image/*,video/*,audio/*,.pdf,.doc,.docx,.csv,.xls,.xlsx" showUploadList={false}
|
<Upload maxCount={1} accept="image/*,video/*,audio/*,.pdf,.doc,.docx,.csv,.xls,.xlsx" showUploadList={false}
|
||||||
beforeUpload={file => {return false;}} onChange={info => {this.handleUpload(info);}}>
|
beforeUpload={file => {return false;}} onChange={info => {this.handleUpload(info);}}>
|
||||||
<Button id="upload-button" icon={<UploadOutlined />} loading={this.state.uploading} type="primary" size="small">
|
<Button id="upload-button" icon={<UploadOutlined />} loading={this.state.uploading} type="primary" size="small">
|
||||||
{i18next.t("resource:Upload a file...")}
|
{i18next.t("resource:Upload a file...")}
|
||||||
</Button>
|
</Button>
|
||||||
</Upload>
|
</Upload>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTable(resources) {
|
renderTable(resources) {
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: i18next.t("general:Provider"),
|
title: i18next.t("general:Provider"),
|
||||||
dataIndex: "provider",
|
dataIndex: "provider",
|
||||||
key: "provider",
|
key: "provider",
|
||||||
width: "150px",
|
width: "150px",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
...this.getColumnSearchProps("provider"),
|
...this.getColumnSearchProps("provider"),
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
return (
|
return (
|
||||||
<Link to={`/providers/${record.owner}/${text}`}>
|
<Link to={`/providers/${record.owner}/${text}`}>
|
||||||
{text}
|
{text}
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: i18next.t("general:Organization"),
|
title: i18next.t("general:Organization"),
|
||||||
dataIndex: "owner",
|
dataIndex: "owner",
|
||||||
key: "owner",
|
key: "owner",
|
||||||
width: "120px",
|
width: "120px",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
...this.getColumnSearchProps("owner"),
|
...this.getColumnSearchProps("owner"),
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
return (
|
return (
|
||||||
<Link to={`/organizations/${text}`}>
|
<Link to={`/organizations/${text}`}>
|
||||||
{text}
|
{text}
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: i18next.t("general:Application"),
|
title: i18next.t("general:Application"),
|
||||||
dataIndex: "application",
|
dataIndex: "application",
|
||||||
key: "application",
|
key: "application",
|
||||||
width: "80px",
|
width: "80px",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
...this.getColumnSearchProps("application"),
|
...this.getColumnSearchProps("application"),
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
return (
|
return (
|
||||||
<Link to={`/applications/${record.owner}/${text}`}>
|
<Link to={`/applications/${record.owner}/${text}`}>
|
||||||
{text}
|
{text}
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: i18next.t("general:User"),
|
title: i18next.t("general:User"),
|
||||||
dataIndex: "user",
|
dataIndex: "user",
|
||||||
key: "user",
|
key: "user",
|
||||||
width: "80px",
|
width: "80px",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
...this.getColumnSearchProps("user"),
|
...this.getColumnSearchProps("user"),
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
return (
|
return (
|
||||||
<Link to={`/users/${record.owner}/${record.user}`}>
|
<Link to={`/users/${record.owner}/${record.user}`}>
|
||||||
{text}
|
{text}
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: i18next.t("resource:Parent"),
|
title: i18next.t("resource:Parent"),
|
||||||
dataIndex: "parent",
|
dataIndex: "parent",
|
||||||
key: "parent",
|
key: "parent",
|
||||||
width: "80px",
|
width: "80px",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
...this.getColumnSearchProps("parent"),
|
...this.getColumnSearchProps("parent"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: i18next.t("general:Name"),
|
title: i18next.t("general:Name"),
|
||||||
dataIndex: "name",
|
dataIndex: "name",
|
||||||
key: "name",
|
key: "name",
|
||||||
width: "150px",
|
width: "150px",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
...this.getColumnSearchProps("name"),
|
...this.getColumnSearchProps("name"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: i18next.t("general:Created time"),
|
title: i18next.t("general:Created time"),
|
||||||
dataIndex: "createdTime",
|
dataIndex: "createdTime",
|
||||||
key: "createdTime",
|
key: "createdTime",
|
||||||
width: "150px",
|
width: "150px",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
return Setting.getFormattedDate(text);
|
return Setting.getFormattedDate(text);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: i18next.t("user:Tag"),
|
title: i18next.t("user:Tag"),
|
||||||
dataIndex: "tag",
|
dataIndex: "tag",
|
||||||
key: "tag",
|
key: "tag",
|
||||||
width: "80px",
|
width: "80px",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
...this.getColumnSearchProps("tag"),
|
...this.getColumnSearchProps("tag"),
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
// title: i18next.t("resource:File name"),
|
// title: i18next.t("resource:File name"),
|
||||||
// dataIndex: 'fileName',
|
// dataIndex: 'fileName',
|
||||||
// key: 'fileName',
|
// key: 'fileName',
|
||||||
// width: '120px',
|
// width: '120px',
|
||||||
// sorter: (a, b) => a.fileName.localeCompare(b.fileName),
|
// sorter: (a, b) => a.fileName.localeCompare(b.fileName),
|
||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
title: i18next.t("provider:Type"),
|
title: i18next.t("provider:Type"),
|
||||||
dataIndex: "fileType",
|
dataIndex: "fileType",
|
||||||
key: "fileType",
|
key: "fileType",
|
||||||
width: "80px",
|
width: "80px",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
...this.getColumnSearchProps("fileType"),
|
...this.getColumnSearchProps("fileType"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: i18next.t("resource:Format"),
|
title: i18next.t("resource:Format"),
|
||||||
dataIndex: "fileFormat",
|
dataIndex: "fileFormat",
|
||||||
key: "fileFormat",
|
key: "fileFormat",
|
||||||
width: "80px",
|
width: "80px",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
...this.getColumnSearchProps("fileFormat"),
|
...this.getColumnSearchProps("fileFormat"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: i18next.t("resource:File size"),
|
title: i18next.t("resource:File size"),
|
||||||
dataIndex: "fileSize",
|
dataIndex: "fileSize",
|
||||||
key: "fileSize",
|
key: "fileSize",
|
||||||
width: "100px",
|
width: "100px",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
return Setting.getFriendlyFileSize(text);
|
return Setting.getFriendlyFileSize(text);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: i18next.t("general:Preview"),
|
title: i18next.t("general:Preview"),
|
||||||
dataIndex: "preview",
|
dataIndex: "preview",
|
||||||
key: "preview",
|
key: "preview",
|
||||||
width: "100px",
|
width: "100px",
|
||||||
fixed: (Setting.isMobile()) ? "false" : "right",
|
fixed: (Setting.isMobile()) ? "false" : "right",
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
if (record.fileType === "image") {
|
if (record.fileType === "image") {
|
||||||
const errorImage = "data:image/png;base64,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";
|
const errorImage = "data:image/png;base64,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";
|
||||||
return (
|
return (
|
||||||
<Image
|
<Image
|
||||||
width={200}
|
width={200}
|
||||||
src={record.url}
|
src={record.url}
|
||||||
fallback={errorImage}
|
fallback={errorImage}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
} else if (record.fileType === "video") {
|
} else if (record.fileType === "video") {
|
||||||
return (
|
return (
|
||||||
<video width={200} controls>
|
<video width={200} controls>
|
||||||
<source src={record.url} type="video/mp4" />
|
<source src={record.url} type="video/mp4" />
|
||||||
</video>
|
</video>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: i18next.t("general:URL"),
|
title: i18next.t("general:URL"),
|
||||||
dataIndex: "url",
|
dataIndex: "url",
|
||||||
key: "url",
|
key: "url",
|
||||||
width: "120px",
|
width: "120px",
|
||||||
fixed: (Setting.isMobile()) ? "false" : "right",
|
fixed: (Setting.isMobile()) ? "false" : "right",
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Button onClick={() => {
|
<Button onClick={() => {
|
||||||
copy(record.url);
|
copy(record.url);
|
||||||
Setting.showMessage("success", i18next.t("general:Copied to clipboard successfully"));
|
Setting.showMessage("success", i18next.t("general:Copied to clipboard successfully"));
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{i18next.t("resource:Copy Link")}
|
{i18next.t("resource:Copy Link")}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: i18next.t("general:Action"),
|
title: i18next.t("general:Action"),
|
||||||
dataIndex: "",
|
dataIndex: "",
|
||||||
key: "op",
|
key: "op",
|
||||||
width: "70px",
|
width: "70px",
|
||||||
fixed: (Setting.isMobile()) ? "false" : "right",
|
fixed: (Setting.isMobile()) ? "false" : "right",
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<PopconfirmModal
|
<PopconfirmModal
|
||||||
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
|
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
|
||||||
onConfirm={() => this.deleteResource(index)}
|
onConfirm={() => this.deleteResource(index)}
|
||||||
okText={i18next.t("general:OK")}
|
okText={i18next.t("general:OK")}
|
||||||
cancelText={i18next.t("general:Cancel")}
|
cancelText={i18next.t("general:Cancel")}
|
||||||
>
|
>
|
||||||
</PopconfirmModal>
|
</PopconfirmModal>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const paginationProps = {
|
const paginationProps = {
|
||||||
total: this.state.pagination.total,
|
total: this.state.pagination.total,
|
||||||
showQuickJumper: true,
|
showQuickJumper: true,
|
||||||
showSizeChanger: true,
|
showSizeChanger: true,
|
||||||
showTotal: () => i18next.t("general:{total} in total").replace("{total}", this.state.pagination.total),
|
showTotal: () => i18next.t("general:{total} in total").replace("{total}", this.state.pagination.total),
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Table scroll={{x: "max-content"}} columns={columns} dataSource={resources} rowKey="name" size="middle" bordered pagination={paginationProps}
|
<Table scroll={{x: "max-content"}} columns={columns} dataSource={resources} rowKey="name" size="middle" bordered pagination={paginationProps}
|
||||||
title={() => (
|
title={() => (
|
||||||
<div>
|
<div>
|
||||||
{i18next.t("general:Resources")}
|
{i18next.t("general:Resources")}
|
||||||
{/* <Button type="primary" size="small" onClick={this.addResource.bind(this)}>{i18next.t("general:Add")}</Button>*/}
|
{/* <Button type="primary" size="small" onClick={this.addResource.bind(this)}>{i18next.t("general:Add")}</Button>*/}
|
||||||
{
|
{
|
||||||
this.renderUpload()
|
this.renderUpload()
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
loading={this.state.loading}
|
loading={this.state.loading}
|
||||||
onChange={this.handleTableChange}
|
onChange={this.handleTableChange}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch = (params = {}) => {
|
fetch = (params = {}) => {
|
||||||
const field = params.searchedColumn, value = params.searchText;
|
const field = params.searchedColumn, value = params.searchText;
|
||||||
const sortField = params.sortField, sortOrder = params.sortOrder;
|
const sortField = params.sortField, sortOrder = params.sortOrder;
|
||||||
this.setState({loading: true});
|
this.setState({loading: true});
|
||||||
ResourceBackend.getResources(Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), this.props.account.name, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
|
ResourceBackend.getResources(Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), this.props.account.name, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false,
|
loading: false,
|
||||||
});
|
});
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
this.setState({
|
this.setState({
|
||||||
data: res.data,
|
data: res.data,
|
||||||
pagination: {
|
pagination: {
|
||||||
...params.pagination,
|
...params.pagination,
|
||||||
total: res.data2,
|
total: res.data2,
|
||||||
},
|
},
|
||||||
searchText: params.searchText,
|
searchText: params.searchText,
|
||||||
searchedColumn: params.searchedColumn,
|
searchedColumn: params.searchedColumn,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (res.data.includes("Please login first")) {
|
if (res.data.includes("Please login first")) {
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false,
|
loading: false,
|
||||||
isAuthorized: false,
|
isAuthorized: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ResourceListPage;
|
export default ResourceListPage;
|
||||||
|
@ -1,30 +1,30 @@
|
|||||||
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
|
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import * as Setting from "../Setting";
|
import * as Setting from "../Setting";
|
||||||
|
|
||||||
class OdicDiscoveryPage extends React.Component {
|
class OdicDiscoveryPage extends React.Component {
|
||||||
UNSAFE_componentWillMount() {
|
UNSAFE_componentWillMount() {
|
||||||
if (Setting.isLocalhost()) {
|
if (Setting.isLocalhost()) {
|
||||||
Setting.goToLink(`${Setting.ServerUrl}/.well-known/openid-configuration`);
|
Setting.goToLink(`${Setting.ServerUrl}/.well-known/openid-configuration`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default OdicDiscoveryPage;
|
export default OdicDiscoveryPage;
|
||||||
|
@ -1,31 +1,31 @@
|
|||||||
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
|
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import {createButton} from "react-social-login-buttons";
|
import {createButton} from "react-social-login-buttons";
|
||||||
|
|
||||||
function Icon({width = 24, height = 24, color}) {
|
function Icon({width = 24, height = 24, color}) {
|
||||||
return <svg xmlns="http://www.w3.org/2000/svg" height="48" width="32" viewBox="-18.15 -35.9725 157.3 215.835"><path fill="#faab07" d="M60.503 142.237c-12.533 0-24.038-4.195-31.445-10.46-3.762 1.124-8.574 2.932-11.61 5.175-2.6 1.918-2.275 3.874-1.807 4.663 2.056 3.47 35.273 2.216 44.862 1.136zm0 0c12.535 0 24.039-4.195 31.447-10.46 3.76 1.124 8.573 2.932 11.61 5.175 2.598 1.918 2.274 3.874 1.805 4.663-2.056 3.47-35.272 2.216-44.862 1.136zm0 0" /><path d="M60.576 67.119c20.698-.14 37.286-4.147 42.907-5.683 1.34-.367 2.056-1.024 2.056-1.024.005-.189.085-3.37.085-5.01C105.624 27.768 92.58.001 60.5 0 28.42.001 15.375 27.769 15.375 55.401c0 1.642.08 4.822.086 5.01 0 0 .583.615 1.65.913 5.19 1.444 22.09 5.65 43.312 5.795zm56.245 23.02c-1.283-4.129-3.034-8.944-4.808-13.568 0 0-1.02-.126-1.537.023-15.913 4.623-35.202 7.57-49.9 7.392h-.153c-14.616.175-33.774-2.737-49.634-7.315-.606-.175-1.802-.1-1.802-.1-1.774 4.624-3.525 9.44-4.808 13.568-6.119 19.69-4.136 27.838-2.627 28.02 3.239.392 12.606-14.821 12.606-14.821 0 15.459 13.957 39.195 45.918 39.413h.848c31.96-.218 45.917-23.954 45.917-39.413 0 0 9.368 15.213 12.607 14.822 1.508-.183 3.491-8.332-2.627-28.021" /><path fill="#fff" d="M49.085 40.824c-4.352.197-8.07-4.76-8.304-11.063-.236-6.305 3.098-11.576 7.45-11.773 4.347-.195 8.064 4.76 8.3 11.065.238 6.306-3.097 11.577-7.446 11.771m31.133-11.063c-.233 6.302-3.951 11.26-8.303 11.063-4.35-.195-7.684-5.465-7.446-11.77.236-6.305 3.952-11.26 8.3-11.066 4.352.197 7.686 5.468 7.449 11.773" /><path fill="#faab07" d="M87.952 49.725C86.79 47.15 75.077 44.28 60.578 44.28h-.156c-14.5 0-26.212 2.87-27.375 5.446a.863.863 0 00-.085.367.88.88 0 00.16.496c.98 1.427 13.985 8.487 27.3 8.487h.156c13.314 0 26.319-7.058 27.299-8.487a.873.873 0 00.16-.498.856.856 0 00-.085-.365" /><path d="M54.434 29.854c.199 2.49-1.167 4.702-3.046 4.943-1.883.242-3.568-1.58-3.768-4.07-.197-2.492 1.167-4.704 3.043-4.944 1.886-.244 3.574 1.58 3.771 4.07m11.956.833c.385-.689 3.004-4.312 8.427-2.993 1.425.347 2.084.857 2.223 1.057.205.296.262.718.053 1.286-.412 1.126-1.263 1.095-1.734.875-.305-.142-4.082-2.66-7.562 1.097-.24.257-.668.346-1.073.04-.407-.308-.574-.93-.334-1.362" /><path fill="#fff" d="M60.576 83.08h-.153c-9.996.12-22.116-1.204-33.854-3.518-1.004 5.818-1.61 13.132-1.09 21.853 1.316 22.043 14.407 35.9 34.614 36.1h.82c20.208-.2 33.298-14.057 34.616-36.1.52-8.723-.087-16.035-1.092-21.854-11.739 2.315-23.862 3.64-33.86 3.518" /><path fill="#eb1923" d="M32.102 81.235v21.693s9.937 2.004 19.893.616V83.535c-6.307-.357-13.109-1.152-19.893-2.3" /><path fill="#eb1923" d="M105.539 60.412s-19.33 6.102-44.963 6.275h-.153c-25.591-.172-44.896-6.255-44.962-6.275L8.987 76.57c16.193 4.882 36.261 8.028 51.436 7.845h.153c15.175.183 35.242-2.963 51.437-7.845zm0 0" /></svg>;
|
return <svg xmlns="http://www.w3.org/2000/svg" height="48" width="32" viewBox="-18.15 -35.9725 157.3 215.835"><path fill="#faab07" d="M60.503 142.237c-12.533 0-24.038-4.195-31.445-10.46-3.762 1.124-8.574 2.932-11.61 5.175-2.6 1.918-2.275 3.874-1.807 4.663 2.056 3.47 35.273 2.216 44.862 1.136zm0 0c12.535 0 24.039-4.195 31.447-10.46 3.76 1.124 8.573 2.932 11.61 5.175 2.598 1.918 2.274 3.874 1.805 4.663-2.056 3.47-35.272 2.216-44.862 1.136zm0 0" /><path d="M60.576 67.119c20.698-.14 37.286-4.147 42.907-5.683 1.34-.367 2.056-1.024 2.056-1.024.005-.189.085-3.37.085-5.01C105.624 27.768 92.58.001 60.5 0 28.42.001 15.375 27.769 15.375 55.401c0 1.642.08 4.822.086 5.01 0 0 .583.615 1.65.913 5.19 1.444 22.09 5.65 43.312 5.795zm56.245 23.02c-1.283-4.129-3.034-8.944-4.808-13.568 0 0-1.02-.126-1.537.023-15.913 4.623-35.202 7.57-49.9 7.392h-.153c-14.616.175-33.774-2.737-49.634-7.315-.606-.175-1.802-.1-1.802-.1-1.774 4.624-3.525 9.44-4.808 13.568-6.119 19.69-4.136 27.838-2.627 28.02 3.239.392 12.606-14.821 12.606-14.821 0 15.459 13.957 39.195 45.918 39.413h.848c31.96-.218 45.917-23.954 45.917-39.413 0 0 9.368 15.213 12.607 14.822 1.508-.183 3.491-8.332-2.627-28.021" /><path fill="#fff" d="M49.085 40.824c-4.352.197-8.07-4.76-8.304-11.063-.236-6.305 3.098-11.576 7.45-11.773 4.347-.195 8.064 4.76 8.3 11.065.238 6.306-3.097 11.577-7.446 11.771m31.133-11.063c-.233 6.302-3.951 11.26-8.303 11.063-4.35-.195-7.684-5.465-7.446-11.77.236-6.305 3.952-11.26 8.3-11.066 4.352.197 7.686 5.468 7.449 11.773" /><path fill="#faab07" d="M87.952 49.725C86.79 47.15 75.077 44.28 60.578 44.28h-.156c-14.5 0-26.212 2.87-27.375 5.446a.863.863 0 00-.085.367.88.88 0 00.16.496c.98 1.427 13.985 8.487 27.3 8.487h.156c13.314 0 26.319-7.058 27.299-8.487a.873.873 0 00.16-.498.856.856 0 00-.085-.365" /><path d="M54.434 29.854c.199 2.49-1.167 4.702-3.046 4.943-1.883.242-3.568-1.58-3.768-4.07-.197-2.492 1.167-4.704 3.043-4.944 1.886-.244 3.574 1.58 3.771 4.07m11.956.833c.385-.689 3.004-4.312 8.427-2.993 1.425.347 2.084.857 2.223 1.057.205.296.262.718.053 1.286-.412 1.126-1.263 1.095-1.734.875-.305-.142-4.082-2.66-7.562 1.097-.24.257-.668.346-1.073.04-.407-.308-.574-.93-.334-1.362" /><path fill="#fff" d="M60.576 83.08h-.153c-9.996.12-22.116-1.204-33.854-3.518-1.004 5.818-1.61 13.132-1.09 21.853 1.316 22.043 14.407 35.9 34.614 36.1h.82c20.208-.2 33.298-14.057 34.616-36.1.52-8.723-.087-16.035-1.092-21.854-11.739 2.315-23.862 3.64-33.86 3.518" /><path fill="#eb1923" d="M32.102 81.235v21.693s9.937 2.004 19.893.616V83.535c-6.307-.357-13.109-1.152-19.893-2.3" /><path fill="#eb1923" d="M105.539 60.412s-19.33 6.102-44.963 6.275h-.153c-25.591-.172-44.896-6.255-44.962-6.275L8.987 76.57c16.193 4.882 36.261 8.028 51.436 7.845h.153c15.175.183 35.242-2.963 51.437-7.845zm0 0" /></svg>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
text: "Sign in with QQ",
|
text: "Sign in with QQ",
|
||||||
icon: Icon,
|
icon: Icon,
|
||||||
iconFormat: name => `fa fa-${name}`,
|
iconFormat: name => `fa fa-${name}`,
|
||||||
style: {background: "rgb(94,188,249)"},
|
style: {background: "rgb(94,188,249)"},
|
||||||
activeStyle: {background: "rgb(76,143,208)"},
|
activeStyle: {background: "rgb(76,143,208)"},
|
||||||
};
|
};
|
||||||
|
|
||||||
const QqLoginButton = createButton(config);
|
const QqLoginButton = createButton(config);
|
||||||
|
|
||||||
export default QqLoginButton;
|
export default QqLoginButton;
|
||||||
|
@ -1,85 +1,85 @@
|
|||||||
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
|
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import * as Setting from "../Setting";
|
import * as Setting from "../Setting";
|
||||||
|
|
||||||
export function getResources(owner, user, page = "", pageSize = "", field = "", value = "", sortField = "", sortOrder = "") {
|
export function getResources(owner, user, page = "", pageSize = "", field = "", value = "", sortField = "", sortOrder = "") {
|
||||||
return fetch(`${Setting.ServerUrl}/api/get-resources?owner=${owner}&user=${user}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-resources?owner=${owner}&user=${user}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
headers: {
|
headers: {
|
||||||
"Accept-Language": Setting.getAcceptLanguage(),
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
},
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getResource(owner, name) {
|
export function getResource(owner, name) {
|
||||||
return fetch(`${Setting.ServerUrl}/api/get-resource?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-resource?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
headers: {
|
headers: {
|
||||||
"Accept-Language": Setting.getAcceptLanguage(),
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
},
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateResource(owner, name, resource) {
|
export function updateResource(owner, name, resource) {
|
||||||
const newResource = Setting.deepCopy(resource);
|
const newResource = Setting.deepCopy(resource);
|
||||||
return fetch(`${Setting.ServerUrl}/api/update-resource?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/update-resource?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newResource),
|
body: JSON.stringify(newResource),
|
||||||
headers: {
|
headers: {
|
||||||
"Accept-Language": Setting.getAcceptLanguage(),
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
},
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addResource(resource) {
|
export function addResource(resource) {
|
||||||
const newResource = Setting.deepCopy(resource);
|
const newResource = Setting.deepCopy(resource);
|
||||||
return fetch(`${Setting.ServerUrl}/api/add-resource`, {
|
return fetch(`${Setting.ServerUrl}/api/add-resource`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newResource),
|
body: JSON.stringify(newResource),
|
||||||
headers: {
|
headers: {
|
||||||
"Accept-Language": Setting.getAcceptLanguage(),
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
},
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deleteResource(resource, provider = "") {
|
export function deleteResource(resource, provider = "") {
|
||||||
const newResource = Setting.deepCopy(resource);
|
const newResource = Setting.deepCopy(resource);
|
||||||
return fetch(`${Setting.ServerUrl}/api/delete-resource?provider=${provider}`, {
|
return fetch(`${Setting.ServerUrl}/api/delete-resource?provider=${provider}`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newResource),
|
body: JSON.stringify(newResource),
|
||||||
headers: {
|
headers: {
|
||||||
"Accept-Language": Setting.getAcceptLanguage(),
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
},
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function uploadResource(owner, user, tag, parent, fullFilePath, file, provider = "") {
|
export function uploadResource(owner, user, tag, parent, fullFilePath, file, provider = "") {
|
||||||
const application = "app-built-in";
|
const application = "app-built-in";
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("file", file);
|
formData.append("file", file);
|
||||||
return fetch(`${Setting.ServerUrl}/api/upload-resource?owner=${owner}&user=${user}&application=${application}&tag=${tag}&parent=${parent}&fullFilePath=${encodeURIComponent(fullFilePath)}&provider=${provider}`, {
|
return fetch(`${Setting.ServerUrl}/api/upload-resource?owner=${owner}&user=${user}&application=${application}&tag=${tag}&parent=${parent}&fullFilePath=${encodeURIComponent(fullFilePath)}&provider=${provider}`, {
|
||||||
body: formData,
|
body: formData,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
headers: {
|
headers: {
|
||||||
"Accept-Language": Setting.getAcceptLanguage(),
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
},
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
@ -1,229 +1,229 @@
|
|||||||
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
|
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {Button, Col, Row} from "antd";
|
import {Button, Col, Row} from "antd";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import * as UserBackend from "../backend/UserBackend";
|
import * as UserBackend from "../backend/UserBackend";
|
||||||
import * as Setting from "../Setting";
|
import * as Setting from "../Setting";
|
||||||
import * as Provider from "../auth/Provider";
|
import * as Provider from "../auth/Provider";
|
||||||
import * as AuthBackend from "../auth/AuthBackend";
|
import * as AuthBackend from "../auth/AuthBackend";
|
||||||
import {goToWeb3Url} from "../auth/ProviderButton";
|
import {goToWeb3Url} from "../auth/ProviderButton";
|
||||||
import AccountAvatar from "../account/AccountAvatar";
|
import AccountAvatar from "../account/AccountAvatar";
|
||||||
import {WechatOfficialAccountModal} from "../auth/Util";
|
import {WechatOfficialAccountModal} from "../auth/Util";
|
||||||
|
|
||||||
class OAuthWidget extends React.Component {
|
class OAuthWidget extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
classes: props,
|
classes: props,
|
||||||
addressOptions: [],
|
addressOptions: [],
|
||||||
affiliationOptions: [],
|
affiliationOptions: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
UNSAFE_componentWillMount() {
|
UNSAFE_componentWillMount() {
|
||||||
this.getAddressOptions(this.props.application);
|
this.getAddressOptions(this.props.application);
|
||||||
this.getAffiliationOptions(this.props.application, this.props.user);
|
this.getAffiliationOptions(this.props.application, this.props.user);
|
||||||
}
|
}
|
||||||
|
|
||||||
getAddressOptions(application) {
|
getAddressOptions(application) {
|
||||||
if (application.affiliationUrl === "") {
|
if (application.affiliationUrl === "") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const addressUrl = application.affiliationUrl.split("|")[0];
|
const addressUrl = application.affiliationUrl.split("|")[0];
|
||||||
UserBackend.getAddressOptions(addressUrl)
|
UserBackend.getAddressOptions(addressUrl)
|
||||||
.then((addressOptions) => {
|
.then((addressOptions) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
addressOptions: addressOptions,
|
addressOptions: addressOptions,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getAffiliationOptions(application, user) {
|
getAffiliationOptions(application, user) {
|
||||||
if (application.affiliationUrl === "") {
|
if (application.affiliationUrl === "") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const affiliationUrl = application.affiliationUrl.split("|")[1];
|
const affiliationUrl = application.affiliationUrl.split("|")[1];
|
||||||
const code = user.address[user.address.length - 1];
|
const code = user.address[user.address.length - 1];
|
||||||
UserBackend.getAffiliationOptions(affiliationUrl, code)
|
UserBackend.getAffiliationOptions(affiliationUrl, code)
|
||||||
.then((affiliationOptions) => {
|
.then((affiliationOptions) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
affiliationOptions: affiliationOptions,
|
affiliationOptions: affiliationOptions,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateUserField(key, value) {
|
updateUserField(key, value) {
|
||||||
this.props.onUpdateUserField(key, value);
|
this.props.onUpdateUserField(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
unlinked() {
|
unlinked() {
|
||||||
this.props.onUnlinked();
|
this.props.onUnlinked();
|
||||||
}
|
}
|
||||||
|
|
||||||
getProviderLink(user, provider) {
|
getProviderLink(user, provider) {
|
||||||
if (provider.type === "GitHub") {
|
if (provider.type === "GitHub") {
|
||||||
return `https://github.com/${this.getUserProperty(user, provider.type, "username")}`;
|
return `https://github.com/${this.getUserProperty(user, provider.type, "username")}`;
|
||||||
} else if (provider.type === "Google") {
|
} else if (provider.type === "Google") {
|
||||||
return "https://mail.google.com";
|
return "https://mail.google.com";
|
||||||
} else {
|
} else {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getUserProperty(user, providerType, propertyName) {
|
getUserProperty(user, providerType, propertyName) {
|
||||||
const key = `oauth_${providerType}_${propertyName}`;
|
const key = `oauth_${providerType}_${propertyName}`;
|
||||||
if (user.properties === null) {return "";}
|
if (user.properties === null) {return "";}
|
||||||
return user.properties[key];
|
return user.properties[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
unlinkUser(providerType, linkedValue) {
|
unlinkUser(providerType, linkedValue) {
|
||||||
const body = {
|
const body = {
|
||||||
providerType: providerType,
|
providerType: providerType,
|
||||||
// should add the unlink user's info, cause the user may not be logged in, but a admin want to unlink the user.
|
// should add the unlink user's info, cause the user may not be logged in, but a admin want to unlink the user.
|
||||||
user: this.props.user,
|
user: this.props.user,
|
||||||
};
|
};
|
||||||
if (providerType === "MetaMask" || providerType === "Web3Onboard") {
|
if (providerType === "MetaMask" || providerType === "Web3Onboard") {
|
||||||
import("../auth/Web3Auth")
|
import("../auth/Web3Auth")
|
||||||
.then(module => {
|
.then(module => {
|
||||||
const delWeb3AuthToken = module.delWeb3AuthToken;
|
const delWeb3AuthToken = module.delWeb3AuthToken;
|
||||||
delWeb3AuthToken(linkedValue);
|
delWeb3AuthToken(linkedValue);
|
||||||
AuthBackend.unlink(body)
|
AuthBackend.unlink(body)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
Setting.showMessage("success", "Unlinked successfully");
|
Setting.showMessage("success", "Unlinked successfully");
|
||||||
|
|
||||||
this.unlinked();
|
this.unlinked();
|
||||||
} else {
|
} else {
|
||||||
Setting.showMessage("error", `Failed to unlink: ${res.msg}`);
|
Setting.showMessage("error", `Failed to unlink: ${res.msg}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AuthBackend.unlink(body)
|
AuthBackend.unlink(body)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
Setting.showMessage("success", "Unlinked successfully");
|
Setting.showMessage("success", "Unlinked successfully");
|
||||||
|
|
||||||
this.unlinked();
|
this.unlinked();
|
||||||
} else {
|
} else {
|
||||||
Setting.showMessage("error", `Failed to unlink: ${res.msg}`);
|
Setting.showMessage("error", `Failed to unlink: ${res.msg}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
renderIdp(user, application, providerItem) {
|
renderIdp(user, application, providerItem) {
|
||||||
const provider = providerItem.provider;
|
const provider = providerItem.provider;
|
||||||
const linkedValue = user[provider.type.toLowerCase()];
|
const linkedValue = user[provider.type.toLowerCase()];
|
||||||
const profileUrl = this.getProviderLink(user, provider);
|
const profileUrl = this.getProviderLink(user, provider);
|
||||||
const id = this.getUserProperty(user, provider.type, "id");
|
const id = this.getUserProperty(user, provider.type, "id");
|
||||||
const username = this.getUserProperty(user, provider.type, "username");
|
const username = this.getUserProperty(user, provider.type, "username");
|
||||||
const displayName = this.getUserProperty(user, provider.type, "displayName");
|
const displayName = this.getUserProperty(user, provider.type, "displayName");
|
||||||
const email = this.getUserProperty(user, provider.type, "email");
|
const email = this.getUserProperty(user, provider.type, "email");
|
||||||
let avatarUrl = this.getUserProperty(user, provider.type, "avatarUrl");
|
let avatarUrl = this.getUserProperty(user, provider.type, "avatarUrl");
|
||||||
// the account user
|
// the account user
|
||||||
const account = this.props.account;
|
const account = this.props.account;
|
||||||
|
|
||||||
if (avatarUrl === "" || avatarUrl === undefined) {
|
if (avatarUrl === "" || avatarUrl === undefined) {
|
||||||
avatarUrl = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAQAAACROWYpAAAAHElEQVR42mNkoAAwjmoe1TyqeVTzqOZRzcNZMwB18wAfEFQkPQAAAABJRU5ErkJggg==";
|
avatarUrl = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAQAAACROWYpAAAAHElEQVR42mNkoAAwjmoe1TyqeVTzqOZRzcNZMwB18wAfEFQkPQAAAABJRU5ErkJggg==";
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = (username === undefined) ? displayName : `${displayName} (${username})`;
|
let name = (username === undefined) ? displayName : `${displayName} (${username})`;
|
||||||
if (name === undefined) {
|
if (name === undefined) {
|
||||||
if (id !== undefined) {
|
if (id !== undefined) {
|
||||||
name = id;
|
name = id;
|
||||||
} else if (email !== undefined) {
|
} else if (email !== undefined) {
|
||||||
name = email;
|
name = email;
|
||||||
} else {
|
} else {
|
||||||
name = linkedValue;
|
name = linkedValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let linkButtonWidth = "110px";
|
let linkButtonWidth = "110px";
|
||||||
if (Setting.getLanguage() === "id") {
|
if (Setting.getLanguage() === "id") {
|
||||||
linkButtonWidth = "160px";
|
linkButtonWidth = "160px";
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row key={provider.name} style={{marginTop: "20px"}} >
|
<Row key={provider.name} style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={this.props.labelSpan}>
|
<Col style={{marginTop: "5px"}} span={this.props.labelSpan}>
|
||||||
{
|
{
|
||||||
Setting.getProviderLogo(provider)
|
Setting.getProviderLogo(provider)
|
||||||
}
|
}
|
||||||
<span style={{marginLeft: "5px"}}>
|
<span style={{marginLeft: "5px"}}>
|
||||||
{
|
{
|
||||||
`${provider.type}:`
|
`${provider.type}:`
|
||||||
}
|
}
|
||||||
</span>
|
</span>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={24 - this.props.labelSpan} >
|
<Col span={24 - this.props.labelSpan} >
|
||||||
<AccountAvatar style={{marginRight: "10px"}} size={30} src={avatarUrl} alt={name} referrerPolicy="no-referrer" />
|
<AccountAvatar style={{marginRight: "10px"}} size={30} src={avatarUrl} alt={name} referrerPolicy="no-referrer" />
|
||||||
<span style={{
|
<span style={{
|
||||||
width: this.props.labelSpan === 3 ? "300px" : "200px",
|
width: this.props.labelSpan === 3 ? "300px" : "200px",
|
||||||
display: (Setting.isMobile()) ? "inline" : "inline-block",
|
display: (Setting.isMobile()) ? "inline" : "inline-block",
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
textOverflow: "ellipsis",
|
textOverflow: "ellipsis",
|
||||||
}} title={name}>
|
}} title={name}>
|
||||||
{
|
{
|
||||||
linkedValue === "" ? (
|
linkedValue === "" ? (
|
||||||
`(${i18next.t("general:empty")})`
|
`(${i18next.t("general:empty")})`
|
||||||
) : (
|
) : (
|
||||||
profileUrl === "" ? name : (
|
profileUrl === "" ? name : (
|
||||||
<a target="_blank" rel="noreferrer" href={profileUrl}>
|
<a target="_blank" rel="noreferrer" href={profileUrl}>
|
||||||
{
|
{
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
</a>
|
</a>
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</span>
|
</span>
|
||||||
{
|
{
|
||||||
linkedValue === "" ? (
|
linkedValue === "" ? (
|
||||||
provider.category === "Web3" ? (
|
provider.category === "Web3" ? (
|
||||||
<Button style={{marginLeft: "20px", width: linkButtonWidth}} type="primary" disabled={user.id !== account.id} onClick={() => goToWeb3Url(application, provider, "link")}>{i18next.t("user:Link")}</Button>
|
<Button style={{marginLeft: "20px", width: linkButtonWidth}} type="primary" disabled={user.id !== account.id} onClick={() => goToWeb3Url(application, provider, "link")}>{i18next.t("user:Link")}</Button>
|
||||||
) : (
|
) : (
|
||||||
provider.type === "WeChat" && provider.clientId2 !== "" && provider.clientSecret2 !== "" && provider.disableSsl === true && !navigator.userAgent.includes("MicroMessenger") ? (
|
provider.type === "WeChat" && provider.clientId2 !== "" && provider.clientSecret2 !== "" && provider.disableSsl === true && !navigator.userAgent.includes("MicroMessenger") ? (
|
||||||
<a key={provider.displayName}>
|
<a key={provider.displayName}>
|
||||||
<Button style={{marginLeft: "20px", width: linkButtonWidth}} type="primary" disabled={user.id !== account.id} onClick={
|
<Button style={{marginLeft: "20px", width: linkButtonWidth}} type="primary" disabled={user.id !== account.id} onClick={
|
||||||
() => {
|
() => {
|
||||||
WechatOfficialAccountModal(application, provider, "link");
|
WechatOfficialAccountModal(application, provider, "link");
|
||||||
}
|
}
|
||||||
}>{i18next.t("user:Link")}</Button>
|
}>{i18next.t("user:Link")}</Button>
|
||||||
</a>
|
</a>
|
||||||
) : (
|
) : (
|
||||||
<a key={provider.displayName} href={user.id !== account.id ? null : Provider.getAuthUrl(application, provider, "link")}>
|
<a key={provider.displayName} href={user.id !== account.id ? null : Provider.getAuthUrl(application, provider, "link")}>
|
||||||
<Button style={{marginLeft: "20px", width: linkButtonWidth}} type="primary" disabled={user.id !== account.id}>{i18next.t("user:Link")}</Button>
|
<Button style={{marginLeft: "20px", width: linkButtonWidth}} type="primary" disabled={user.id !== account.id}>{i18next.t("user:Link")}</Button>
|
||||||
</a>
|
</a>
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
) : (
|
) : (
|
||||||
<Button disabled={!providerItem.canUnlink && !Setting.isAdminUser(account)} style={{marginLeft: "20px", width: linkButtonWidth}} onClick={() => this.unlinkUser(provider.type, linkedValue)}>{i18next.t("user:Unlink")}</Button>
|
<Button disabled={!providerItem.canUnlink && !Setting.isAdminUser(account)} style={{marginLeft: "20px", width: linkButtonWidth}} onClick={() => this.unlinkUser(provider.type, linkedValue)}>{i18next.t("user:Unlink")}</Button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return this.renderIdp(this.props.user, this.props.application, this.props.providerItem);
|
return this.renderIdp(this.props.user, this.props.application, this.props.providerItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default OAuthWidget;
|
export default OAuthWidget;
|
||||||
|
Reference in New Issue
Block a user