mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-27 16:30:46 +08:00
Compare commits
13 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b0f572c51a | ||
![]() |
19d351d157 | ||
![]() |
d0751bf2fa | ||
![]() |
290cc60f00 | ||
![]() |
6a1ec51978 | ||
![]() |
dffa68cbce | ||
![]() |
fad209a7a3 | ||
![]() |
8b222ce2e3 | ||
![]() |
c5293f428d | ||
![]() |
146aec9ee8 | ||
![]() |
50a52de856 | ||
![]() |
8f7a8d7d4f | ||
![]() |
23f3fe1e3c |
18
.github/workflows/build.yml
vendored
18
.github/workflows/build.yml
vendored
@@ -125,26 +125,36 @@ jobs:
|
|||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v2
|
||||||
|
|
||||||
|
- name: Set up buildx
|
||||||
|
id: buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
with:
|
||||||
|
version: latest
|
||||||
|
|
||||||
- name: Log in to Docker Hub
|
- name: Log in to Docker Hub
|
||||||
uses: docker/login-action@v1
|
uses: docker/login-action@v1
|
||||||
if: github.repository == 'casdoor/casdoor' && github.event_name == 'push' &&steps.should_push.outputs.push=='true'
|
if: github.repository == 'casdoor/casdoor' && github.event_name == 'push' && steps.should_push.outputs.push=='true'
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||||
|
|
||||||
|
|
||||||
- name: Push to Docker Hub
|
- name: Push to Docker Hub
|
||||||
uses: docker/build-push-action@v2
|
uses: docker/build-push-action@v3
|
||||||
if: github.repository == 'casdoor/casdoor' && github.event_name == 'push' && steps.should_push.outputs.push=='true'
|
if: github.repository == 'casdoor/casdoor' && github.event_name == 'push' && steps.should_push.outputs.push=='true'
|
||||||
with:
|
with:
|
||||||
target: STANDARD
|
target: STANDARD
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
push: true
|
push: true
|
||||||
tags: casbin/casdoor:${{steps.get-current-tag.outputs.tag }},casbin/casdoor:latest
|
tags: casbin/casdoor:${{steps.get-current-tag.outputs.tag }},casbin/casdoor:latest
|
||||||
|
|
||||||
- name: Push All In One Version to Docker Hub
|
- name: Push All In One Version to Docker Hub
|
||||||
uses: docker/build-push-action@v2
|
uses: docker/build-push-action@v3
|
||||||
if: github.repository == 'casdoor/casdoor' && github.event_name == 'push' && steps.should_push.outputs.push=='true'
|
if: github.repository == 'casdoor/casdoor' && github.event_name == 'push' && steps.should_push.outputs.push=='true'
|
||||||
with:
|
with:
|
||||||
target: ALLINONE
|
target: ALLINONE
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
push: true
|
push: true
|
||||||
tags: casbin/casdoor-all-in-one:${{steps.get-current-tag.outputs.tag }},casbin/casdoor-all-in-one:latest
|
tags: casbin/casdoor-all-in-one:${{steps.get-current-tag.outputs.tag }},casbin/casdoor-all-in-one:latest
|
||||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -27,3 +27,6 @@ logs/
|
|||||||
files/
|
files/
|
||||||
lastupdate.tmp
|
lastupdate.tmp
|
||||||
commentsRouter*.go
|
commentsRouter*.go
|
||||||
|
|
||||||
|
# ignore build result
|
||||||
|
casdoor
|
20
Dockerfile
20
Dockerfile
@@ -2,7 +2,7 @@ FROM node:16.13.0 AS FRONT
|
|||||||
WORKDIR /web
|
WORKDIR /web
|
||||||
COPY ./web .
|
COPY ./web .
|
||||||
RUN yarn config set registry https://registry.npmmirror.com
|
RUN yarn config set registry https://registry.npmmirror.com
|
||||||
RUN yarn install && yarn run build
|
RUN yarn install --frozen-lockfile --network-timeout 1000000 && yarn run build
|
||||||
|
|
||||||
|
|
||||||
FROM golang:1.17.5 AS BACK
|
FROM golang:1.17.5 AS BACK
|
||||||
@@ -13,16 +13,26 @@ RUN ./build.sh
|
|||||||
|
|
||||||
FROM alpine:latest AS STANDARD
|
FROM alpine:latest AS STANDARD
|
||||||
LABEL MAINTAINER="https://casdoor.org/"
|
LABEL MAINTAINER="https://casdoor.org/"
|
||||||
|
ARG USER=casdoor
|
||||||
|
|
||||||
RUN sed -i 's/https/http/' /etc/apk/repositories
|
RUN sed -i 's/https/http/' /etc/apk/repositories
|
||||||
|
RUN apk add --update sudo
|
||||||
RUN apk add curl
|
RUN apk add curl
|
||||||
RUN apk add ca-certificates && update-ca-certificates
|
RUN apk add ca-certificates && update-ca-certificates
|
||||||
|
|
||||||
|
RUN adduser -D $USER -u 1000 \
|
||||||
|
&& echo "$USER ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/$USER \
|
||||||
|
&& chmod 0440 /etc/sudoers.d/$USER \
|
||||||
|
&& mkdir logs \
|
||||||
|
&& chown -R $USER:$USER logs
|
||||||
|
|
||||||
|
USER 1000
|
||||||
WORKDIR /
|
WORKDIR /
|
||||||
COPY --from=BACK /go/src/casdoor/server ./server
|
COPY --from=BACK --chown=$USER:$USER /go/src/casdoor/server ./server
|
||||||
COPY --from=BACK /go/src/casdoor/swagger ./swagger
|
COPY --from=BACK --chown=$USER:$USER /go/src/casdoor/swagger ./swagger
|
||||||
COPY --from=BACK /go/src/casdoor/conf/app.conf ./conf/app.conf
|
COPY --from=BACK --chown=$USER:$USER /go/src/casdoor/conf/app.conf ./conf/app.conf
|
||||||
COPY --from=FRONT /web/build ./web/build
|
COPY --from=FRONT --chown=$USER:$USER /web/build ./web/build
|
||||||
|
|
||||||
ENTRYPOINT ["/server"]
|
ENTRYPOINT ["/server"]
|
||||||
|
|
||||||
|
|
||||||
|
@@ -203,12 +203,6 @@ func (c *ApiController) Signup() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = object.CheckUsername(user.Name)
|
|
||||||
if msg != "" {
|
|
||||||
c.ResponseError(msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
affected := object.AddUser(user)
|
affected := object.AddUser(user)
|
||||||
if !affected {
|
if !affected {
|
||||||
c.ResponseError(fmt.Sprintf("Failed to create user, user information is invalid: %s", util.StructToJson(user)))
|
c.ResponseError(fmt.Sprintf("Failed to create user, user information is invalid: %s", util.StructToJson(user)))
|
||||||
|
@@ -411,12 +411,6 @@ func (c *ApiController) Login() {
|
|||||||
// sync info from 3rd-party if possible
|
// sync info from 3rd-party if possible
|
||||||
object.SetUserOAuthProperties(organization, user, provider.Type, userInfo)
|
object.SetUserOAuthProperties(organization, user, provider.Type, userInfo)
|
||||||
|
|
||||||
msg := object.CheckUsername(user.Name)
|
|
||||||
if msg != "" {
|
|
||||||
c.ResponseError(msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
affected := object.AddUser(user)
|
affected := object.AddUser(user)
|
||||||
if !affected {
|
if !affected {
|
||||||
c.ResponseError(fmt.Sprintf("Failed to create user, user information is invalid: %s", util.StructToJson(user)))
|
c.ResponseError(fmt.Sprintf("Failed to create user, user information is invalid: %s", util.StructToJson(user)))
|
||||||
|
@@ -158,12 +158,6 @@ func (c *ApiController) UpdateUser() {
|
|||||||
columns = strings.Split(columnsStr, ",")
|
columns = strings.Split(columnsStr, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
msg := object.CheckUsername(user.Name)
|
|
||||||
if msg != "" {
|
|
||||||
c.ResponseError(msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
isGlobalAdmin := c.IsGlobalAdmin()
|
isGlobalAdmin := c.IsGlobalAdmin()
|
||||||
affected := object.UpdateUser(id, &user, columns, isGlobalAdmin)
|
affected := object.UpdateUser(id, &user, columns, isGlobalAdmin)
|
||||||
if affected {
|
if affected {
|
||||||
|
@@ -282,7 +282,7 @@ func getUser(gothUser goth.User, provider string) *UserInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if provider == "steam" {
|
if provider == "steam" {
|
||||||
user.Username = user.DisplayName
|
user.Username = user.Id
|
||||||
user.Email = ""
|
user.Email = ""
|
||||||
}
|
}
|
||||||
return &user
|
return &user
|
||||||
|
@@ -19,11 +19,13 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/beego/beego"
|
"github.com/beego/beego"
|
||||||
|
xormadapter "github.com/casbin/xorm-adapter/v3"
|
||||||
"github.com/casdoor/casdoor/conf"
|
"github.com/casdoor/casdoor/conf"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
_ "github.com/denisenkom/go-mssqldb" // db = mssql
|
_ "github.com/denisenkom/go-mssqldb" // db = mssql
|
||||||
_ "github.com/go-sql-driver/mysql" // db = mysql
|
_ "github.com/go-sql-driver/mysql" // db = mysql
|
||||||
_ "github.com/lib/pq" // db = postgres
|
_ "github.com/lib/pq" // db = postgres
|
||||||
|
"xorm.io/xorm/migrate"
|
||||||
//_ "github.com/mattn/go-sqlite3" // db = sqlite3
|
//_ "github.com/mattn/go-sqlite3" // db = sqlite3
|
||||||
"xorm.io/core"
|
"xorm.io/core"
|
||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
@@ -40,6 +42,7 @@ func InitConfig() {
|
|||||||
beego.BConfig.WebConfig.Session.SessionOn = true
|
beego.BConfig.WebConfig.Session.SessionOn = true
|
||||||
|
|
||||||
InitAdapter(true)
|
InitAdapter(true)
|
||||||
|
initMigrations()
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitAdapter(createDatabase bool) {
|
func InitAdapter(createDatabase bool) {
|
||||||
@@ -214,6 +217,11 @@ func (a *Adapter) createTable() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = a.Engine.Sync2(new(xormadapter.CasbinRule))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetSession(owner string, offset, limit int, field, value, sortField, sortOrder string) *xorm.Session {
|
func GetSession(owner string, offset, limit int, field, value, sortField, sortOrder string) *xorm.Session {
|
||||||
@@ -239,3 +247,22 @@ func GetSession(owner string, offset, limit int, field, value, sortField, sortOr
|
|||||||
}
|
}
|
||||||
return session
|
return session
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func initMigrations() {
|
||||||
|
migrations := []*migrate.Migration{
|
||||||
|
{
|
||||||
|
ID: "20221015CasbinRule--fill ptype field with p",
|
||||||
|
Migrate: func(tx *xorm.Engine) error {
|
||||||
|
_, err := tx.Cols("ptype").Update(&xormadapter.CasbinRule{
|
||||||
|
Ptype: "p",
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
},
|
||||||
|
Rollback: func(tx *xorm.Engine) error {
|
||||||
|
return tx.DropTables(&xormadapter.CasbinRule{})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
m := migrate.New(adapter.Engine, migrate.DefaultOptions, migrations)
|
||||||
|
m.Migrate()
|
||||||
|
}
|
||||||
|
@@ -70,6 +70,7 @@ type Application struct {
|
|||||||
SigninHtml string `xorm:"mediumtext" json:"signinHtml"`
|
SigninHtml string `xorm:"mediumtext" json:"signinHtml"`
|
||||||
FormCss string `xorm:"text" json:"formCss"`
|
FormCss string `xorm:"text" json:"formCss"`
|
||||||
FormOffset int `json:"formOffset"`
|
FormOffset int `json:"formOffset"`
|
||||||
|
FormSideHtml string `xorm:"mediumtext" json:"formSideHtml"`
|
||||||
FormBackgroundUrl string `xorm:"varchar(200)" json:"formBackgroundUrl"`
|
FormBackgroundUrl string `xorm:"varchar(200)" json:"formBackgroundUrl"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -50,7 +50,7 @@ func downloadFile(url string) (*bytes.Buffer, error) {
|
|||||||
return fileBuffer, nil
|
return fileBuffer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPermanentAvatarUrl(organization string, username string, url string) string {
|
func getPermanentAvatarUrl(organization string, username string, url string, upload bool) string {
|
||||||
if url == "" {
|
if url == "" {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@@ -62,6 +62,14 @@ func getPermanentAvatarUrl(organization string, username string, url string) str
|
|||||||
fullFilePath := fmt.Sprintf("/avatar/%s/%s.png", organization, username)
|
fullFilePath := fmt.Sprintf("/avatar/%s/%s.png", organization, username)
|
||||||
uploadedFileUrl, _ := getUploadFileUrl(defaultStorageProvider, fullFilePath, false)
|
uploadedFileUrl, _ := getUploadFileUrl(defaultStorageProvider, fullFilePath, false)
|
||||||
|
|
||||||
|
if upload {
|
||||||
|
DownloadAndUpload(url, fullFilePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
return uploadedFileUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
func DownloadAndUpload(url string, fullFilePath string) {
|
||||||
fileBuffer, err := downloadFile(url)
|
fileBuffer, err := downloadFile(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@@ -71,6 +79,4 @@ func getPermanentAvatarUrl(organization string, username string, url string) str
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return uploadedFileUrl
|
|
||||||
}
|
}
|
||||||
|
@@ -32,7 +32,7 @@ func TestSyncPermanentAvatars(t *testing.T) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
user.PermanentAvatar = getPermanentAvatarUrl(user.Owner, user.Name, user.Avatar)
|
user.PermanentAvatar = getPermanentAvatarUrl(user.Owner, user.Name, user.Avatar, true)
|
||||||
updateUserColumn("permanent_avatar", user)
|
updateUserColumn("permanent_avatar", user)
|
||||||
fmt.Printf("[%d/%d]: Update user: [%s]'s permanent avatar: %s\n", i, len(users), user.GetId(), user.PermanentAvatar)
|
fmt.Printf("[%d/%d]: Update user: [%s]'s permanent avatar: %s\n", i, len(users), user.GetId(), user.PermanentAvatar)
|
||||||
}
|
}
|
||||||
|
@@ -59,6 +59,11 @@ func CheckUserSignup(application *Application, organization *Organization, usern
|
|||||||
if reWhiteSpace.MatchString(username) {
|
if reWhiteSpace.MatchString(username) {
|
||||||
return "username cannot contain white spaces"
|
return "username cannot contain white spaces"
|
||||||
}
|
}
|
||||||
|
msg := CheckUsername(username)
|
||||||
|
if msg != "" {
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
if HasUserByField(organization.Name, "name", username) {
|
if HasUserByField(organization.Name, "name", username) {
|
||||||
return "username already exists"
|
return "username already exists"
|
||||||
}
|
}
|
||||||
@@ -314,16 +319,21 @@ func CheckAccessPermission(userId string, application *Application) (bool, error
|
|||||||
return allowed, err
|
return allowed, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckUsername(name string) string {
|
func CheckUsername(username string) string {
|
||||||
if name == "" {
|
if username == "" {
|
||||||
return "Empty username."
|
return "Empty username."
|
||||||
} else if len(name) > 39 {
|
} else if len(username) > 39 {
|
||||||
return "Username is too long (maximum is 39 characters)."
|
return "Username is too long (maximum is 39 characters)."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exclude, _ := regexp.Compile("^[\u0021-\u007E]+$")
|
||||||
|
if !exclude.MatchString(username) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/58726546/github-username-convention-using-regex
|
// https://stackoverflow.com/questions/58726546/github-username-convention-using-regex
|
||||||
re, _ := regexp.Compile("^[a-zA-Z0-9]+((?:-[a-zA-Z0-9]+)|(?:_[a-zA-Z0-9]+))*$")
|
re, _ := regexp.Compile("^[a-zA-Z0-9]+((?:-[a-zA-Z0-9]+)|(?:_[a-zA-Z0-9]+))*$")
|
||||||
if !re.MatchString(name) {
|
if !re.MatchString(username) {
|
||||||
return "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline."
|
return "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -120,7 +120,7 @@ func (syncer *Syncer) updateUserForOriginalFields(user *User) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if user.Avatar != oldUser.Avatar && user.Avatar != "" {
|
if user.Avatar != oldUser.Avatar && user.Avatar != "" {
|
||||||
user.PermanentAvatar = getPermanentAvatarUrl(user.Owner, user.Name, user.Avatar)
|
user.PermanentAvatar = getPermanentAvatarUrl(user.Owner, user.Name, user.Avatar, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
columns := syncer.getCasdoorColumns()
|
columns := syncer.getCasdoorColumns()
|
||||||
|
@@ -386,7 +386,7 @@ func UpdateUser(id string, user *User, columns []string, isGlobalAdmin bool) boo
|
|||||||
user.UpdateUserHash()
|
user.UpdateUserHash()
|
||||||
|
|
||||||
if user.Avatar != oldUser.Avatar && user.Avatar != "" && user.PermanentAvatar != "*" {
|
if user.Avatar != oldUser.Avatar && user.Avatar != "" && user.PermanentAvatar != "*" {
|
||||||
user.PermanentAvatar = getPermanentAvatarUrl(user.Owner, user.Name, user.Avatar)
|
user.PermanentAvatar = getPermanentAvatarUrl(user.Owner, user.Name, user.Avatar, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(columns) == 0 {
|
if len(columns) == 0 {
|
||||||
@@ -419,7 +419,7 @@ func UpdateUserForAllFields(id string, user *User) bool {
|
|||||||
user.UpdateUserHash()
|
user.UpdateUserHash()
|
||||||
|
|
||||||
if user.Avatar != oldUser.Avatar && user.Avatar != "" {
|
if user.Avatar != oldUser.Avatar && user.Avatar != "" {
|
||||||
user.PermanentAvatar = getPermanentAvatarUrl(user.Owner, user.Name, user.Avatar)
|
user.PermanentAvatar = getPermanentAvatarUrl(user.Owner, user.Name, user.Avatar, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(user)
|
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(user)
|
||||||
@@ -449,7 +449,7 @@ func AddUser(user *User) bool {
|
|||||||
user.UpdateUserHash()
|
user.UpdateUserHash()
|
||||||
user.PreHash = user.Hash
|
user.PreHash = user.Hash
|
||||||
|
|
||||||
user.PermanentAvatar = getPermanentAvatarUrl(user.Owner, user.Name, user.Avatar)
|
user.PermanentAvatar = getPermanentAvatarUrl(user.Owner, user.Name, user.Avatar, false)
|
||||||
|
|
||||||
user.Ranking = GetUserCount(user.Owner, "", "") + 1
|
user.Ranking = GetUserCount(user.Owner, "", "") + 1
|
||||||
|
|
||||||
@@ -474,7 +474,7 @@ func AddUsers(users []*User) bool {
|
|||||||
user.UpdateUserHash()
|
user.UpdateUserHash()
|
||||||
user.PreHash = user.Hash
|
user.PreHash = user.Hash
|
||||||
|
|
||||||
user.PermanentAvatar = getPermanentAvatarUrl(user.Owner, user.Name, user.Avatar)
|
user.PermanentAvatar = getPermanentAvatarUrl(user.Owner, user.Name, user.Avatar, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
affected, err := adapter.Engine.Insert(users)
|
affected, err := adapter.Engine.Insert(users)
|
||||||
|
@@ -159,7 +159,7 @@ func DisableVerificationCode(dest string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// from Casnode/object/validateCode.go line 116
|
// From Casnode/object/validateCode.go line 116
|
||||||
var stdNums = []byte("0123456789")
|
var stdNums = []byte("0123456789")
|
||||||
|
|
||||||
func getRandomCode(length int) string {
|
func getRandomCode(length int) string {
|
||||||
|
@@ -74,6 +74,7 @@ import ModelEditPage from "./ModelEditPage";
|
|||||||
import SystemInfo from "./SystemInfo";
|
import SystemInfo from "./SystemInfo";
|
||||||
import AdapterListPage from "./AdapterListPage";
|
import AdapterListPage from "./AdapterListPage";
|
||||||
import AdapterEditPage from "./AdapterEditPage";
|
import AdapterEditPage from "./AdapterEditPage";
|
||||||
|
import {withTranslation} from "react-i18next";
|
||||||
|
|
||||||
const {Header, Footer} = Layout;
|
const {Header, Footer} = Layout;
|
||||||
|
|
||||||
@@ -798,4 +799,4 @@ class App extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withRouter(App);
|
export default withRouter(withTranslation()(App));
|
||||||
|
@@ -94,6 +94,37 @@
|
|||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.side-image {
|
||||||
|
display: none;
|
||||||
|
@media screen and (min-width: 1100px){
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
width: 500px;
|
||||||
|
border-right: 0.5px solid rgb(196, 203, 215);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.forget-content{
|
||||||
|
padding: 10px 100px 20px;
|
||||||
|
border: 2px solid #ffffff;
|
||||||
|
border-radius: 7px;
|
||||||
|
background-color: rgb(255, 255, 255);
|
||||||
|
box-shadow: 0 0 20px rgba(0, 0, 0, 0.20);
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-panel{
|
||||||
|
margin-top: 50px;
|
||||||
|
margin-bottom: 50px;
|
||||||
|
display: flex;
|
||||||
|
background-color: rgb(255, 255, 255);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-form{
|
||||||
|
text-align: center;
|
||||||
|
padding: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
.login-content {
|
.login-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@@ -105,7 +136,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.loginBackground {
|
.loginBackground {
|
||||||
height: 100%;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex: 1 1 0;
|
||||||
background: #fff no-repeat;
|
background: #fff no-repeat;
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
background-attachment: fixed;
|
background-attachment: fixed;
|
||||||
|
@@ -32,6 +32,7 @@ import copy from "copy-to-clipboard";
|
|||||||
|
|
||||||
import {Controlled as CodeMirror} from "react-codemirror2";
|
import {Controlled as CodeMirror} from "react-codemirror2";
|
||||||
import "codemirror/lib/codemirror.css";
|
import "codemirror/lib/codemirror.css";
|
||||||
|
|
||||||
require("codemirror/theme/material-darker.css");
|
require("codemirror/theme/material-darker.css");
|
||||||
require("codemirror/mode/htmlmixed/htmlmixed");
|
require("codemirror/mode/htmlmixed/htmlmixed");
|
||||||
require("codemirror/mode/xml/xml");
|
require("codemirror/mode/xml/xml");
|
||||||
@@ -39,13 +40,52 @@ require("codemirror/mode/css/css");
|
|||||||
|
|
||||||
const {Option} = Select;
|
const {Option} = Select;
|
||||||
|
|
||||||
const template = {
|
const template = `<!--template: please copy and paste-->
|
||||||
padding: "30px",
|
<style>
|
||||||
border: "2px solid #ffffff",
|
.login-panel{
|
||||||
borderRadius: "7px",
|
border-radius: 10px;
|
||||||
backgroundColor: "#ffffff",
|
background-color: #ffffff;
|
||||||
boxShadow: " 0px 0px 20px rgba(0, 0, 0, 0.20)",
|
box-shadow: 0 0 20px rgba(0, 0, 0, 0.20);
|
||||||
};
|
}
|
||||||
|
</style>
|
||||||
|
`;
|
||||||
|
const sideTemplate = `<!--template: please copy and paste-->
|
||||||
|
<style>
|
||||||
|
.left-model{
|
||||||
|
text-align: center;
|
||||||
|
padding: 30px;
|
||||||
|
background-color: #8ca0ed;
|
||||||
|
position: absolute;
|
||||||
|
transform: none;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.side-logo{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.side-logo span {
|
||||||
|
font-family: Montserrat, sans-serif;
|
||||||
|
font-weight: 900;
|
||||||
|
font-size: 2.4rem;
|
||||||
|
line-height: 1.3;
|
||||||
|
margin-left: 16px;
|
||||||
|
color: #404040;
|
||||||
|
}
|
||||||
|
.img{
|
||||||
|
max-width: none;
|
||||||
|
margin: 41px 0 13px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="left-model">
|
||||||
|
<span class="side-logo"> <img src="https://cdn.casbin.org/img/casdoor-logo_1185x256.png" alt="Casdoor" style="width: 120px">
|
||||||
|
<span>SSO</span>
|
||||||
|
</span>
|
||||||
|
<div class="img">
|
||||||
|
<img src="https://cdn.casbin.org/img/casbin.svg" alt="Casdoor"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
class ApplicationEditPage extends React.Component {
|
class ApplicationEditPage extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@@ -157,7 +197,6 @@ class ApplicationEditPage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderApplication() {
|
renderApplication() {
|
||||||
const preview = JSON.stringify(template, null, 2);
|
|
||||||
return (
|
return (
|
||||||
<Card size="small" title={
|
<Card size="small" title={
|
||||||
<div>
|
<div>
|
||||||
@@ -562,10 +601,10 @@ class ApplicationEditPage extends React.Component {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col span={22} style={(Setting.isMobile()) ? {maxWidth: "100%"} : {}}>
|
<Col span={22} style={(Setting.isMobile()) ? {maxWidth: "100%"} : {}}>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 1}>
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
{Setting.getLabel(i18next.t("general:URL"), i18next.t("general:URL - Tooltip"))} :
|
{Setting.getLabel(i18next.t("general:URL"), i18next.t("general:URL - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={23} >
|
<Col span={22} >
|
||||||
<Input prefix={<LinkOutlined />} value={this.state.application.formBackgroundUrl} onChange={e => {
|
<Input prefix={<LinkOutlined />} value={this.state.application.formBackgroundUrl} onChange={e => {
|
||||||
this.updateApplicationField("formBackgroundUrl", e.target.value);
|
this.updateApplicationField("formBackgroundUrl", e.target.value);
|
||||||
}} />
|
}} />
|
||||||
@@ -590,8 +629,8 @@ class ApplicationEditPage extends React.Component {
|
|||||||
<Col span={22}>
|
<Col span={22}>
|
||||||
<Popover placement="right" content={
|
<Popover placement="right" content={
|
||||||
<div style={{width: "900px", height: "300px"}} >
|
<div style={{width: "900px", height: "300px"}} >
|
||||||
<CodeMirror value={this.state.application.formCss === "" ? preview : this.state.application.formCss}
|
<CodeMirror value={this.state.application.formCss === "" ? template : this.state.application.formCss}
|
||||||
options={{mode: "css", theme: "material-darker"}}
|
options={{mode: "htmlmixed", theme: "material-darker"}}
|
||||||
onBeforeChange={(editor, data, value) => {
|
onBeforeChange={(editor, data, value) => {
|
||||||
this.updateApplicationField("formCss", value);
|
this.updateApplicationField("formCss", value);
|
||||||
}}
|
}}
|
||||||
@@ -609,11 +648,39 @@ class ApplicationEditPage extends React.Component {
|
|||||||
{Setting.getLabel(i18next.t("application:From position"), i18next.t("application:From position - Tooltip"))} :
|
{Setting.getLabel(i18next.t("application:From position"), i18next.t("application:From position - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Radio.Group onChange={e => {this.updateApplicationField("formOffset", e.target.value);}} value={this.state.application.formOffset !== 0 ? this.state.application.formOffset : 8}>
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Radio.Button value={2}>left</Radio.Button>
|
<Radio.Group onChange={e => {this.updateApplicationField("formOffset", e.target.value);}} value={this.state.application.formOffset}>
|
||||||
<Radio.Button value={8}>center</Radio.Button>
|
<Radio.Button value={1}>{i18next.t("application:Left")}</Radio.Button>
|
||||||
<Radio.Button value={14}>right</Radio.Button>
|
<Radio.Button value={2}>{i18next.t("application:Center")}</Radio.Button>
|
||||||
</Radio.Group>
|
<Radio.Button value={3}>{i18next.t("application:Right")}</Radio.Button>
|
||||||
|
<Radio.Button value={4}>
|
||||||
|
{i18next.t("application:Enable side panel")}
|
||||||
|
</Radio.Button>
|
||||||
|
</Radio.Group>
|
||||||
|
</Row>
|
||||||
|
{this.state.application.formOffset === 4 ?
|
||||||
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 3}>
|
||||||
|
{Setting.getLabel(i18next.t("application:Side panel HTML"), i18next.t("application:Side panel HTML - Tooltip"))} :
|
||||||
|
</Col>
|
||||||
|
<Col span={21} >
|
||||||
|
<Popover placement="right" content={
|
||||||
|
<div style={{width: "900px", height: "300px"}} >
|
||||||
|
<CodeMirror value={this.state.application.formSideHtml === "" ? sideTemplate : this.state.application.formSideHtml}
|
||||||
|
options={{mode: "htmlmixed", theme: "material-darker"}}
|
||||||
|
onBeforeChange={(editor, data, value) => {
|
||||||
|
this.updateApplicationField("formSideHtml", value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
} title={i18next.t("application:Side panel HTML - Edit")} trigger="click">
|
||||||
|
<Input value={this.state.application.formSideHtml} style={{marginBottom: "10px"}} onChange={e => {
|
||||||
|
this.updateApplicationField("formSideHtml", e.target.value);
|
||||||
|
}} />
|
||||||
|
</Popover>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
: null}
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
{
|
{
|
||||||
@@ -707,7 +774,7 @@ class ApplicationEditPage extends React.Component {
|
|||||||
<br />
|
<br />
|
||||||
<div style={{position: "relative", width: "90%", border: "1px solid rgb(217,217,217)", boxShadow: "10px 10px 5px #888888", flexDirection: "column", flex: "auto"}}>
|
<div style={{position: "relative", width: "90%", border: "1px solid rgb(217,217,217)", boxShadow: "10px 10px 5px #888888", flexDirection: "column", flex: "auto"}}>
|
||||||
<PromptPage application={this.state.application} account={this.props.account} />
|
<PromptPage application={this.state.application} account={this.props.account} />
|
||||||
<div style={maskStyle}></div>
|
<div style={maskStyle} />
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
);
|
);
|
||||||
|
@@ -12,19 +12,21 @@
|
|||||||
// 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, {useState} from "react";
|
import React, {useEffect, useState} from "react";
|
||||||
import Cropper from "react-cropper";
|
import Cropper from "react-cropper";
|
||||||
import "cropperjs/dist/cropper.css";
|
import "cropperjs/dist/cropper.css";
|
||||||
import * as Setting from "./Setting";
|
import * as Setting from "./Setting";
|
||||||
import {Button, Col, Modal, Row} from "antd";
|
import {Button, Col, Modal, Row, Select} from "antd";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import * as ResourceBackend from "./backend/ResourceBackend";
|
import * as ResourceBackend from "./backend/ResourceBackend";
|
||||||
|
|
||||||
export const CropperDiv = (props) => {
|
export const CropperDiv = (props) => {
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [options, setOptions] = useState([]);
|
||||||
const [image, setImage] = useState("");
|
const [image, setImage] = useState("");
|
||||||
const [cropper, setCropper] = useState();
|
const [cropper, setCropper] = useState();
|
||||||
const [visible, setVisible] = React.useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
const [confirmLoading, setConfirmLoading] = React.useState(false);
|
const [confirmLoading, setConfirmLoading] = useState(false);
|
||||||
const {title} = props;
|
const {title} = props;
|
||||||
const {user} = props;
|
const {user} = props;
|
||||||
const {buttonText} = props;
|
const {buttonText} = props;
|
||||||
@@ -60,7 +62,7 @@ export const CropperDiv = (props) => {
|
|||||||
ResourceBackend.uploadResource(user.owner, user.name, "avatar", "CropperDiv", fullFilePath, blob)
|
ResourceBackend.uploadResource(user.owner, user.name, "avatar", "CropperDiv", fullFilePath, blob)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
window.location.href = "/account";
|
window.location.href = window.location.pathname;
|
||||||
} else {
|
} else {
|
||||||
Setting.showMessage("error", res.msg);
|
Setting.showMessage("error", res.msg);
|
||||||
}
|
}
|
||||||
@@ -88,6 +90,48 @@ export const CropperDiv = (props) => {
|
|||||||
uploadButton.click();
|
uploadButton.click();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getOptions = (data) => {
|
||||||
|
const options = [];
|
||||||
|
if (props.account.organization.defaultAvatar !== null) {
|
||||||
|
options.push({value: props.account.organization.defaultAvatar});
|
||||||
|
}
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
if (data[i].fileType === "image") {
|
||||||
|
const url = `${data[i].url}`;
|
||||||
|
options.push({
|
||||||
|
value: url,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getBase64Image = (src) => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const image = new Image();
|
||||||
|
image.src = src;
|
||||||
|
image.setAttribute("crossOrigin", "anonymous");
|
||||||
|
image.onload = () => {
|
||||||
|
const canvas = document.createElement("canvas");
|
||||||
|
canvas.width = image.width;
|
||||||
|
canvas.height = image.height;
|
||||||
|
const ctx = canvas.getContext("2d");
|
||||||
|
ctx.drawImage(image, 0, 0, image.width, image.height);
|
||||||
|
const dataURL = canvas.toDataURL("image/png");
|
||||||
|
resolve(dataURL);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setLoading(true);
|
||||||
|
ResourceBackend.getResources(props.account.owner, props.account.name, "", "", "", "", "", "")
|
||||||
|
.then((res) => {
|
||||||
|
setLoading(false);
|
||||||
|
setOptions(getOptions(res));
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Button type="default" onClick={showModal}>
|
<Button type="default" onClick={showModal}>
|
||||||
@@ -105,10 +149,20 @@ export const CropperDiv = (props) => {
|
|||||||
[<Button block key="submit" type="primary" onClick={handleOk}>{i18next.t("user:Set new profile picture")}</Button>]
|
[<Button block key="submit" type="primary" onClick={handleOk}>{i18next.t("user:Set new profile picture")}</Button>]
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Col style={{margin: "0px auto 40px auto", width: 1000, height: 300}}>
|
<Col style={{margin: "0px auto 60px auto", width: 1000, height: 350}}>
|
||||||
<Row style={{width: "100%", marginBottom: "20px"}}>
|
<Row style={{width: "100%", marginBottom: "20px"}}>
|
||||||
<input style={{display: "none"}} ref={input => uploadButton = input} type="file" accept="image/*" onChange={onChange} />
|
<input style={{display: "none"}} ref={input => uploadButton = input} type="file" accept="image/*" onChange={onChange} />
|
||||||
<Button block onClick={selectFile}>{i18next.t("user:Select a photo...")}</Button>
|
<Button block onClick={selectFile}>{i18next.t("user:Select a photo...")}</Button>
|
||||||
|
<Select
|
||||||
|
style={{width: "100%"}}
|
||||||
|
loading={loading}
|
||||||
|
placeholder={i18next.t("user:Please select avatar from resources")}
|
||||||
|
onChange={(async value => {
|
||||||
|
setImage(await getBase64Image(value));
|
||||||
|
})}
|
||||||
|
options={options}
|
||||||
|
allowClear={true}
|
||||||
|
/>
|
||||||
</Row>
|
</Row>
|
||||||
<Cropper
|
<Cropper
|
||||||
style={{height: "100%"}}
|
style={{height: "100%"}}
|
||||||
|
@@ -554,7 +554,7 @@ export function changeLanguage(language) {
|
|||||||
localStorage.setItem("language", language);
|
localStorage.setItem("language", language);
|
||||||
changeMomentLanguage(language);
|
changeMomentLanguage(language);
|
||||||
i18next.changeLanguage(language);
|
i18next.changeLanguage(language);
|
||||||
window.location.reload(true);
|
// window.location.reload(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function changeMomentLanguage(language) {
|
export function changeMomentLanguage(language) {
|
||||||
|
@@ -17,7 +17,6 @@ import {Button, Card, Col, Input, Result, Row, Select, Spin, Switch} from "antd"
|
|||||||
import * as UserBackend from "./backend/UserBackend";
|
import * as UserBackend from "./backend/UserBackend";
|
||||||
import * as OrganizationBackend from "./backend/OrganizationBackend";
|
import * as OrganizationBackend from "./backend/OrganizationBackend";
|
||||||
import * as Setting from "./Setting";
|
import * as Setting from "./Setting";
|
||||||
import {LinkOutlined} from "@ant-design/icons";
|
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import CropperDiv from "./CropperDiv.js";
|
import CropperDiv from "./CropperDiv.js";
|
||||||
import * as ApplicationBackend from "./backend/ApplicationBackend";
|
import * as ApplicationBackend from "./backend/ApplicationBackend";
|
||||||
@@ -232,16 +231,6 @@ class UserEditPage extends React.Component {
|
|||||||
{Setting.getLabel(i18next.t("general:Avatar"), i18next.t("general:Avatar - Tooltip"))} :
|
{Setting.getLabel(i18next.t("general:Avatar"), i18next.t("general:Avatar - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Row style={{marginTop: "20px"}} >
|
|
||||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
|
||||||
{i18next.t("general:URL")}:
|
|
||||||
</Col>
|
|
||||||
<Col span={22} >
|
|
||||||
<Input prefix={<LinkOutlined />} value={this.state.user.avatar} onChange={e => {
|
|
||||||
this.updateUserField("avatar", e.target.value);
|
|
||||||
}} />
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
{i18next.t("general:Preview")}:
|
{i18next.t("general:Preview")}:
|
||||||
|
@@ -487,61 +487,65 @@ class ForgetPage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row>
|
<div className="loginBackground" style={{backgroundImage: Setting.inIframe() || Setting.isMobile() ? null : `url(${application.formBackgroundUrl})`}}>
|
||||||
<Col span={24} style={{justifyContent: "center"}}>
|
<CustomGithubCorner />
|
||||||
|
<div className="login-content forget-content">
|
||||||
<Row>
|
<Row>
|
||||||
<Col span={24}>
|
<Col span={24} style={{justifyContent: "center"}}>
|
||||||
<div style={{marginTop: "80px", marginBottom: "10px", textAlign: "center"}}>
|
<Row>
|
||||||
{
|
<Col span={24}>
|
||||||
Setting.renderHelmet(application)
|
<div style={{marginTop: "80px", marginBottom: "10px", textAlign: "center"}}>
|
||||||
}
|
{
|
||||||
<CustomGithubCorner />
|
Setting.renderHelmet(application)
|
||||||
{
|
}
|
||||||
Setting.renderLogo(application)
|
{
|
||||||
}
|
Setting.renderLogo(application)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col span={24}>
|
||||||
|
<div style={{textAlign: "center", fontSize: "28px"}}>
|
||||||
|
{i18next.t("forget:Retrieve password")}
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col span={24}>
|
||||||
|
<Steps
|
||||||
|
current={this.state.current}
|
||||||
|
style={{
|
||||||
|
width: "90%",
|
||||||
|
maxWidth: "500px",
|
||||||
|
margin: "auto",
|
||||||
|
marginTop: "80px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Step
|
||||||
|
title={i18next.t("forget:Account")}
|
||||||
|
icon={<UserOutlined />}
|
||||||
|
/>
|
||||||
|
<Step
|
||||||
|
title={i18next.t("forget:Verify")}
|
||||||
|
icon={<SolutionOutlined />}
|
||||||
|
/>
|
||||||
|
<Step
|
||||||
|
title={i18next.t("forget:Reset")}
|
||||||
|
icon={<KeyOutlined />}
|
||||||
|
/>
|
||||||
|
</Steps>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Col>
|
||||||
|
<Col span={24} style={{display: "flex", justifyContent: "center"}}>
|
||||||
|
<div style={{marginTop: "10px", textAlign: "center"}}>
|
||||||
|
{this.renderForm(application)}
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
</div>
|
||||||
<Col span={24}>
|
</div>
|
||||||
<div style={{textAlign: "center", fontSize: "28px"}}>
|
|
||||||
{i18next.t("forget:Retrieve password")}
|
|
||||||
</div>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
<Row>
|
|
||||||
<Col span={24}>
|
|
||||||
<Steps
|
|
||||||
current={this.state.current}
|
|
||||||
style={{
|
|
||||||
width: "90%",
|
|
||||||
maxWidth: "500px",
|
|
||||||
margin: "auto",
|
|
||||||
marginTop: "80px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Step
|
|
||||||
title={i18next.t("forget:Account")}
|
|
||||||
icon={<UserOutlined />}
|
|
||||||
/>
|
|
||||||
<Step
|
|
||||||
title={i18next.t("forget:Verify")}
|
|
||||||
icon={<SolutionOutlined />}
|
|
||||||
/>
|
|
||||||
<Step
|
|
||||||
title={i18next.t("forget:Reset")}
|
|
||||||
icon={<KeyOutlined />}
|
|
||||||
/>
|
|
||||||
</Steps>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</Col>
|
|
||||||
<Col span={24} style={{display: "flex", justifyContent: "center"}}>
|
|
||||||
<div style={{marginTop: "10px", textAlign: "center"}}>
|
|
||||||
{this.renderForm(application)}
|
|
||||||
</div>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -29,6 +29,7 @@ import i18next from "i18next";
|
|||||||
import CustomGithubCorner from "../CustomGithubCorner";
|
import CustomGithubCorner from "../CustomGithubCorner";
|
||||||
import {CountDownInput} from "../common/CountDownInput";
|
import {CountDownInput} from "../common/CountDownInput";
|
||||||
import SelectLanguageBox from "../SelectLanguageBox";
|
import SelectLanguageBox from "../SelectLanguageBox";
|
||||||
|
import {withTranslation} from "react-i18next";
|
||||||
|
|
||||||
const {TabPane} = Tabs;
|
const {TabPane} = Tabs;
|
||||||
|
|
||||||
@@ -138,6 +139,18 @@ class LoginPage extends React.Component {
|
|||||||
this.props.onUpdateAccount(account);
|
this.props.onUpdateAccount(account);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parseOffset(offset) {
|
||||||
|
if (offset === 2 || offset === 4 || Setting.inIframe() || Setting.isMobile()) {
|
||||||
|
return "0 auto";
|
||||||
|
}
|
||||||
|
if (offset === 1) {
|
||||||
|
return "0 10%";
|
||||||
|
}
|
||||||
|
if (offset === 3) {
|
||||||
|
return "0 60%";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
populateOauthValues(values) {
|
populateOauthValues(values) {
|
||||||
const oAuthParams = Util.getOAuthGetParameters();
|
const oAuthParams = Util.getOAuthGetParameters();
|
||||||
if (oAuthParams !== null && oAuthParams.responseType !== null && oAuthParams.responseType !== "") {
|
if (oAuthParams !== null && oAuthParams.responseType !== null && oAuthParams.responseType !== "") {
|
||||||
@@ -155,8 +168,8 @@ class LoginPage extends React.Component {
|
|||||||
values["type"] = "saml";
|
values["type"] = "saml";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.state.owner !== null && this.state.owner !== undefined) {
|
if (this.state.application.organization !== null && this.state.application.organization !== undefined) {
|
||||||
values["organization"] = this.state.owner;
|
values["organization"] = this.state.application.organization;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
postCodeLoginAction(res) {
|
postCodeLoginAction(res) {
|
||||||
@@ -694,16 +707,18 @@ class LoginPage extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const formStyle = Setting.inIframe() ? null : Setting.parseObject(application.formCss);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="loginBackground" style={{backgroundImage: Setting.inIframe() || Setting.isMobile() ? null : `url(${application.formBackgroundUrl})`}}>
|
<div className="loginBackground" style={{backgroundImage: Setting.inIframe() || Setting.isMobile() ? null : `url(${application.formBackgroundUrl})`}}>
|
||||||
<CustomGithubCorner />
|
<CustomGithubCorner />
|
||||||
<Row>
|
<div className="login-content" style={{margin: this.parseOffset(application.formOffset)}}>
|
||||||
<Col span={8} offset={application.formOffset === 0 || Setting.inIframe() || Setting.isMobile() ? 8 : application.formOffset} style={{display: "flex", justifyContent: "center"}}>
|
{Setting.inIframe() ? null : <div dangerouslySetInnerHTML={{__html: application.formCss}} />}
|
||||||
<div className="login-content">
|
<div className="login-panel">
|
||||||
<div style={{marginTop: "80px", marginBottom: "50px", textAlign: "center", ...formStyle}}>
|
<SelectLanguageBox id="language-box-corner" style={{top: "50px"}} />
|
||||||
<SelectLanguageBox id="language-box-corner" style={{top: formStyle !== null ? "80px" : "45px", right: formStyle !== null ? "5px" : "-45px"}} />
|
<div className="side-image" style={{display: application.formOffset !== 4 ? "none" : null}}>
|
||||||
|
<div dangerouslySetInnerHTML={{__html: application.formSideHtml}} />
|
||||||
|
</div>
|
||||||
|
<div className="login-form">
|
||||||
|
<div >
|
||||||
<div>
|
<div>
|
||||||
{
|
{
|
||||||
Setting.renderHelmet(application)
|
Setting.renderHelmet(application)
|
||||||
@@ -723,11 +738,11 @@ class LoginPage extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</div>
|
||||||
</Row>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default LoginPage;
|
export default withTranslation()(LoginPage);
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {Link} from "react-router-dom";
|
import {Link} from "react-router-dom";
|
||||||
import {Button, Checkbox, Col, Form, Input, Modal, Result, Row} from "antd";
|
import {Button, Checkbox, Form, Input, Modal, Result} from "antd";
|
||||||
import * as Setting from "../Setting";
|
import * as Setting from "../Setting";
|
||||||
import * as AuthBackend from "./AuthBackend";
|
import * as AuthBackend from "./AuthBackend";
|
||||||
import * as ProviderButton from "./ProviderButton";
|
import * as ProviderButton from "./ProviderButton";
|
||||||
@@ -148,6 +148,18 @@ class SignupPage extends React.Component {
|
|||||||
this.props.onUpdateAccount(account);
|
this.props.onUpdateAccount(account);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parseOffset(offset) {
|
||||||
|
if (offset === 2 || offset === 4 || Setting.inIframe() || Setting.isMobile()) {
|
||||||
|
return "0 auto";
|
||||||
|
}
|
||||||
|
if (offset === 1) {
|
||||||
|
return "0 10%";
|
||||||
|
}
|
||||||
|
if (offset === 3) {
|
||||||
|
return "0 60%";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onFinish(values) {
|
onFinish(values) {
|
||||||
const application = this.getApplicationObj();
|
const application = this.getApplicationObj();
|
||||||
values.phonePrefix = application.organizationObj.phonePrefix;
|
values.phonePrefix = application.organizationObj.phonePrefix;
|
||||||
@@ -615,17 +627,18 @@ class SignupPage extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const formStyle = Setting.inIframe() ? null : Setting.parseObject(application.formCss);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="loginBackground" style={{backgroundImage: Setting.inIframe() || Setting.isMobile() ? null : `url(${application.formBackgroundUrl})`}}>
|
<div className="loginBackground" style={{backgroundImage: Setting.inIframe() || Setting.isMobile() ? null : `url(${application.formBackgroundUrl})`}}>
|
||||||
<CustomGithubCorner />
|
<CustomGithubCorner />
|
||||||
|
<div className="login-content" style={{margin: this.parseOffset(application.formOffset)}}>
|
||||||
<Row>
|
{Setting.inIframe() ? null : <div dangerouslySetInnerHTML={{__html: application.formCss}} />}
|
||||||
<Col span={8} offset={application.formOffset === 0 || Setting.inIframe() || Setting.isMobile() ? 8 : application.formOffset} style={{display: "flex", justifyContent: "center"}} >
|
<div className="login-panel" >
|
||||||
<div className="login-content">
|
<SelectLanguageBox id="language-box-corner" style={{top: "50px"}} />
|
||||||
<div style={{marginBottom: "10px", textAlign: "center", ...formStyle}}>
|
<div className="side-image" style={{display: application.formOffset !== 4 ? "none" : null}}>
|
||||||
<SelectLanguageBox id="language-box-corner" style={{top: formStyle !== null ? "3px" : "-20px", right: formStyle !== null ? "5px" : "-45px"}} />
|
<div dangerouslySetInnerHTML={{__html: application.formSideHtml}} />
|
||||||
|
</div>
|
||||||
|
<div className="login-form">
|
||||||
|
<div >
|
||||||
{
|
{
|
||||||
Setting.renderHelmet(application)
|
Setting.renderHelmet(application)
|
||||||
}
|
}
|
||||||
@@ -637,8 +650,8 @@ class SignupPage extends React.Component {
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</div>
|
||||||
</Row>
|
</div>
|
||||||
{
|
{
|
||||||
this.renderModal()
|
this.renderModal()
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,7 @@ import ja from "./locales/ja/data.json";
|
|||||||
import es from "./locales/es/data.json";
|
import es from "./locales/es/data.json";
|
||||||
import * as Conf from "./Conf";
|
import * as Conf from "./Conf";
|
||||||
import * as Setting from "./Setting";
|
import * as Setting from "./Setting";
|
||||||
|
import {initReactI18next} from "react-i18next";
|
||||||
|
|
||||||
const resources = {
|
const resources = {
|
||||||
en: en,
|
en: en,
|
||||||
@@ -80,7 +81,7 @@ function initLanguage() {
|
|||||||
return language;
|
return language;
|
||||||
}
|
}
|
||||||
|
|
||||||
i18n.init({
|
i18n.use(initReactI18next).init({
|
||||||
lng: initLanguage(),
|
lng: initLanguage(),
|
||||||
|
|
||||||
resources: resources,
|
resources: resources,
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
||||||
"Background URL": "Background URL",
|
"Background URL": "Background URL",
|
||||||
"Background URL - Tooltip": "Background URL - Tooltip",
|
"Background URL - Tooltip": "Background URL - Tooltip",
|
||||||
|
"Center": "Center",
|
||||||
"Copy SAML metadata URL": "Copy SAML metadata URL",
|
"Copy SAML metadata URL": "Copy SAML metadata URL",
|
||||||
"Copy prompt page URL": "Copy prompt page URL",
|
"Copy prompt page URL": "Copy prompt page URL",
|
||||||
"Copy signin page URL": "Copy signin page URL",
|
"Copy signin page URL": "Copy signin page URL",
|
||||||
@@ -28,6 +29,7 @@
|
|||||||
"Enable WebAuthn signin - Tooltip": "Enable WebAuthn signin - Tooltip",
|
"Enable WebAuthn signin - Tooltip": "Enable WebAuthn signin - Tooltip",
|
||||||
"Enable code signin": "Code-Anmeldung aktivieren",
|
"Enable code signin": "Code-Anmeldung aktivieren",
|
||||||
"Enable code signin - Tooltip": "Aktiviere Codeanmeldung - Tooltip",
|
"Enable code signin - Tooltip": "Aktiviere Codeanmeldung - Tooltip",
|
||||||
|
"Enable side panel": "Enable side panel",
|
||||||
"Enable signin session - Tooltip": "Aktiviere Anmeldesession - Tooltip",
|
"Enable signin session - Tooltip": "Aktiviere Anmeldesession - Tooltip",
|
||||||
"Enable signup": "Anmeldung aktivieren",
|
"Enable signup": "Anmeldung aktivieren",
|
||||||
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
||||||
@@ -39,6 +41,7 @@
|
|||||||
"From position - Tooltip": "From position - Tooltip",
|
"From position - Tooltip": "From position - Tooltip",
|
||||||
"Grant types": "Grant types",
|
"Grant types": "Grant types",
|
||||||
"Grant types - Tooltip": "Grant types - Tooltip",
|
"Grant types - Tooltip": "Grant types - Tooltip",
|
||||||
|
"Left": "Left",
|
||||||
"New Application": "New Application",
|
"New Application": "New Application",
|
||||||
"Password ON": "Passwort AN",
|
"Password ON": "Passwort AN",
|
||||||
"Password ON - Tooltip": "Whether to allow password login",
|
"Password ON - Tooltip": "Whether to allow password login",
|
||||||
@@ -49,9 +52,13 @@
|
|||||||
"Redirect URLs - Tooltip": "List of redirect addresses after successful login",
|
"Redirect URLs - Tooltip": "List of redirect addresses after successful login",
|
||||||
"Refresh token expire": "Aktualisierungs-Token läuft ab",
|
"Refresh token expire": "Aktualisierungs-Token läuft ab",
|
||||||
"Refresh token expire - Tooltip": "Aktualisierungs-Token läuft ab - Tooltip",
|
"Refresh token expire - Tooltip": "Aktualisierungs-Token läuft ab - Tooltip",
|
||||||
|
"Right": "Right",
|
||||||
"SAML metadata": "SAML metadata",
|
"SAML metadata": "SAML metadata",
|
||||||
"SAML metadata - Tooltip": "SAML metadata - Tooltip",
|
"SAML metadata - Tooltip": "SAML metadata - Tooltip",
|
||||||
"SAML metadata URL copied to clipboard successfully": "SAML metadata URL copied to clipboard successfully",
|
"SAML metadata URL copied to clipboard successfully": "SAML metadata URL copied to clipboard successfully",
|
||||||
|
"Side panel HTML": "Side panel HTML",
|
||||||
|
"Side panel HTML - Edit": "Side panel HTML - Edit",
|
||||||
|
"Side panel HTML - Tooltip": "Side panel HTML - Tooltip",
|
||||||
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser",
|
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser",
|
||||||
"Signin session": "Anmeldesitzung",
|
"Signin session": "Anmeldesitzung",
|
||||||
"Signup items": "Artikel registrieren",
|
"Signup items": "Artikel registrieren",
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
||||||
"Background URL": "Background URL",
|
"Background URL": "Background URL",
|
||||||
"Background URL - Tooltip": "Background URL - Tooltip",
|
"Background URL - Tooltip": "Background URL - Tooltip",
|
||||||
|
"Center": "Center",
|
||||||
"Copy SAML metadata URL": "Copy SAML metadata URL",
|
"Copy SAML metadata URL": "Copy SAML metadata URL",
|
||||||
"Copy prompt page URL": "Copy prompt page URL",
|
"Copy prompt page URL": "Copy prompt page URL",
|
||||||
"Copy signin page URL": "Copy signin page URL",
|
"Copy signin page URL": "Copy signin page URL",
|
||||||
@@ -28,6 +29,7 @@
|
|||||||
"Enable WebAuthn signin - Tooltip": "Enable WebAuthn signin - Tooltip",
|
"Enable WebAuthn signin - Tooltip": "Enable WebAuthn signin - Tooltip",
|
||||||
"Enable code signin": "Enable code signin",
|
"Enable code signin": "Enable code signin",
|
||||||
"Enable code signin - Tooltip": "Enable code signin - Tooltip",
|
"Enable code signin - Tooltip": "Enable code signin - Tooltip",
|
||||||
|
"Enable side panel": "Enable side panel",
|
||||||
"Enable signin session - Tooltip": "Enable signin session - Tooltip",
|
"Enable signin session - Tooltip": "Enable signin session - Tooltip",
|
||||||
"Enable signup": "Enable signup",
|
"Enable signup": "Enable signup",
|
||||||
"Enable signup - Tooltip": "Enable signup - Tooltip",
|
"Enable signup - Tooltip": "Enable signup - Tooltip",
|
||||||
@@ -39,6 +41,7 @@
|
|||||||
"From position - Tooltip": "From position - Tooltip",
|
"From position - Tooltip": "From position - Tooltip",
|
||||||
"Grant types": "Grant types",
|
"Grant types": "Grant types",
|
||||||
"Grant types - Tooltip": "Grant types - Tooltip",
|
"Grant types - Tooltip": "Grant types - Tooltip",
|
||||||
|
"Left": "Left",
|
||||||
"New Application": "New Application",
|
"New Application": "New Application",
|
||||||
"Password ON": "Password ON",
|
"Password ON": "Password ON",
|
||||||
"Password ON - Tooltip": "Password ON - Tooltip",
|
"Password ON - Tooltip": "Password ON - Tooltip",
|
||||||
@@ -49,9 +52,13 @@
|
|||||||
"Redirect URLs - Tooltip": "Redirect URLs - Tooltip",
|
"Redirect URLs - Tooltip": "Redirect URLs - Tooltip",
|
||||||
"Refresh token expire": "Refresh token expire",
|
"Refresh token expire": "Refresh token expire",
|
||||||
"Refresh token expire - Tooltip": "Refresh token expire - Tooltip",
|
"Refresh token expire - Tooltip": "Refresh token expire - Tooltip",
|
||||||
|
"Right": "Right",
|
||||||
"SAML metadata": "SAML metadata",
|
"SAML metadata": "SAML metadata",
|
||||||
"SAML metadata - Tooltip": "SAML metadata - Tooltip",
|
"SAML metadata - Tooltip": "SAML metadata - Tooltip",
|
||||||
"SAML metadata URL copied to clipboard successfully": "SAML metadata URL copied to clipboard successfully",
|
"SAML metadata URL copied to clipboard successfully": "SAML metadata URL copied to clipboard successfully",
|
||||||
|
"Side panel HTML": "Side panel HTML",
|
||||||
|
"Side panel HTML - Edit": "Side panel HTML - Edit",
|
||||||
|
"Side panel HTML - Tooltip": "Side panel HTML - Tooltip",
|
||||||
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser",
|
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser",
|
||||||
"Signin session": "Signin session",
|
"Signin session": "Signin session",
|
||||||
"Signup items": "Signup items",
|
"Signup items": "Signup items",
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
||||||
"Background URL": "Background URL",
|
"Background URL": "Background URL",
|
||||||
"Background URL - Tooltip": "Background URL - Tooltip",
|
"Background URL - Tooltip": "Background URL - Tooltip",
|
||||||
|
"Center": "Center",
|
||||||
"Copy SAML metadata URL": "Copy SAML metadata URL",
|
"Copy SAML metadata URL": "Copy SAML metadata URL",
|
||||||
"Copy prompt page URL": "Copy prompt page URL",
|
"Copy prompt page URL": "Copy prompt page URL",
|
||||||
"Copy signin page URL": "Copy signin page URL",
|
"Copy signin page URL": "Copy signin page URL",
|
||||||
@@ -28,6 +29,7 @@
|
|||||||
"Enable WebAuthn signin - Tooltip": "Enable WebAuthn signin - Tooltip",
|
"Enable WebAuthn signin - Tooltip": "Enable WebAuthn signin - Tooltip",
|
||||||
"Enable code signin": "Activer la connexion au code",
|
"Enable code signin": "Activer la connexion au code",
|
||||||
"Enable code signin - Tooltip": "Activer la connexion au code - infobulle",
|
"Enable code signin - Tooltip": "Activer la connexion au code - infobulle",
|
||||||
|
"Enable side panel": "Enable side panel",
|
||||||
"Enable signin session - Tooltip": "Activer la session de connexion - infobulle",
|
"Enable signin session - Tooltip": "Activer la session de connexion - infobulle",
|
||||||
"Enable signup": "Activer l'inscription",
|
"Enable signup": "Activer l'inscription",
|
||||||
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
||||||
@@ -39,6 +41,7 @@
|
|||||||
"From position - Tooltip": "From position - Tooltip",
|
"From position - Tooltip": "From position - Tooltip",
|
||||||
"Grant types": "Grant types",
|
"Grant types": "Grant types",
|
||||||
"Grant types - Tooltip": "Grant types - Tooltip",
|
"Grant types - Tooltip": "Grant types - Tooltip",
|
||||||
|
"Left": "Left",
|
||||||
"New Application": "New Application",
|
"New Application": "New Application",
|
||||||
"Password ON": "Mot de passe activé",
|
"Password ON": "Mot de passe activé",
|
||||||
"Password ON - Tooltip": "Whether to allow password login",
|
"Password ON - Tooltip": "Whether to allow password login",
|
||||||
@@ -49,9 +52,13 @@
|
|||||||
"Redirect URLs - Tooltip": "List of redirect addresses after successful login",
|
"Redirect URLs - Tooltip": "List of redirect addresses after successful login",
|
||||||
"Refresh token expire": "Expiration du jeton d'actualisation",
|
"Refresh token expire": "Expiration du jeton d'actualisation",
|
||||||
"Refresh token expire - Tooltip": "Expiration du jeton d'actualisation - infobulle",
|
"Refresh token expire - Tooltip": "Expiration du jeton d'actualisation - infobulle",
|
||||||
|
"Right": "Right",
|
||||||
"SAML metadata": "SAML metadata",
|
"SAML metadata": "SAML metadata",
|
||||||
"SAML metadata - Tooltip": "SAML metadata - Tooltip",
|
"SAML metadata - Tooltip": "SAML metadata - Tooltip",
|
||||||
"SAML metadata URL copied to clipboard successfully": "SAML metadata URL copied to clipboard successfully",
|
"SAML metadata URL copied to clipboard successfully": "SAML metadata URL copied to clipboard successfully",
|
||||||
|
"Side panel HTML": "Side panel HTML",
|
||||||
|
"Side panel HTML - Edit": "Side panel HTML - Edit",
|
||||||
|
"Side panel HTML - Tooltip": "Side panel HTML - Tooltip",
|
||||||
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser",
|
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser",
|
||||||
"Signin session": "Connexion à la session",
|
"Signin session": "Connexion à la session",
|
||||||
"Signup items": "Inscrire des éléments",
|
"Signup items": "Inscrire des éléments",
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
||||||
"Background URL": "Background URL",
|
"Background URL": "Background URL",
|
||||||
"Background URL - Tooltip": "Background URL - Tooltip",
|
"Background URL - Tooltip": "Background URL - Tooltip",
|
||||||
|
"Center": "Center",
|
||||||
"Copy SAML metadata URL": "Copy SAML metadata URL",
|
"Copy SAML metadata URL": "Copy SAML metadata URL",
|
||||||
"Copy prompt page URL": "Copy prompt page URL",
|
"Copy prompt page URL": "Copy prompt page URL",
|
||||||
"Copy signin page URL": "Copy signin page URL",
|
"Copy signin page URL": "Copy signin page URL",
|
||||||
@@ -28,6 +29,7 @@
|
|||||||
"Enable WebAuthn signin - Tooltip": "Enable WebAuthn signin - Tooltip",
|
"Enable WebAuthn signin - Tooltip": "Enable WebAuthn signin - Tooltip",
|
||||||
"Enable code signin": "コードサインインを有効にする",
|
"Enable code signin": "コードサインインを有効にする",
|
||||||
"Enable code signin - Tooltip": "Enable code signin - Tooltip",
|
"Enable code signin - Tooltip": "Enable code signin - Tooltip",
|
||||||
|
"Enable side panel": "Enable side panel",
|
||||||
"Enable signin session - Tooltip": "Enable signin session - Tooltip",
|
"Enable signin session - Tooltip": "Enable signin session - Tooltip",
|
||||||
"Enable signup": "サインアップを有効にする",
|
"Enable signup": "サインアップを有効にする",
|
||||||
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
||||||
@@ -39,6 +41,7 @@
|
|||||||
"From position - Tooltip": "From position - Tooltip",
|
"From position - Tooltip": "From position - Tooltip",
|
||||||
"Grant types": "Grant types",
|
"Grant types": "Grant types",
|
||||||
"Grant types - Tooltip": "Grant types - Tooltip",
|
"Grant types - Tooltip": "Grant types - Tooltip",
|
||||||
|
"Left": "Left",
|
||||||
"New Application": "New Application",
|
"New Application": "New Application",
|
||||||
"Password ON": "パスワードON",
|
"Password ON": "パスワードON",
|
||||||
"Password ON - Tooltip": "Whether to allow password login",
|
"Password ON - Tooltip": "Whether to allow password login",
|
||||||
@@ -49,9 +52,13 @@
|
|||||||
"Redirect URLs - Tooltip": "List of redirect addresses after successful login",
|
"Redirect URLs - Tooltip": "List of redirect addresses after successful login",
|
||||||
"Refresh token expire": "トークンの更新の期限が切れます",
|
"Refresh token expire": "トークンの更新の期限が切れます",
|
||||||
"Refresh token expire - Tooltip": "トークンの有効期限を更新する - ツールチップ",
|
"Refresh token expire - Tooltip": "トークンの有効期限を更新する - ツールチップ",
|
||||||
|
"Right": "Right",
|
||||||
"SAML metadata": "SAML metadata",
|
"SAML metadata": "SAML metadata",
|
||||||
"SAML metadata - Tooltip": "SAML metadata - Tooltip",
|
"SAML metadata - Tooltip": "SAML metadata - Tooltip",
|
||||||
"SAML metadata URL copied to clipboard successfully": "SAML metadata URL copied to clipboard successfully",
|
"SAML metadata URL copied to clipboard successfully": "SAML metadata URL copied to clipboard successfully",
|
||||||
|
"Side panel HTML": "Side panel HTML",
|
||||||
|
"Side panel HTML - Edit": "Side panel HTML - Edit",
|
||||||
|
"Side panel HTML - Tooltip": "Side panel HTML - Tooltip",
|
||||||
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser",
|
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser",
|
||||||
"Signin session": "サインインセッション",
|
"Signin session": "サインインセッション",
|
||||||
"Signup items": "アイテムの登録",
|
"Signup items": "アイテムの登録",
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
||||||
"Background URL": "Background URL",
|
"Background URL": "Background URL",
|
||||||
"Background URL - Tooltip": "Background URL - Tooltip",
|
"Background URL - Tooltip": "Background URL - Tooltip",
|
||||||
|
"Center": "Center",
|
||||||
"Copy SAML metadata URL": "Copy SAML metadata URL",
|
"Copy SAML metadata URL": "Copy SAML metadata URL",
|
||||||
"Copy prompt page URL": "Copy prompt page URL",
|
"Copy prompt page URL": "Copy prompt page URL",
|
||||||
"Copy signin page URL": "Copy signin page URL",
|
"Copy signin page URL": "Copy signin page URL",
|
||||||
@@ -28,6 +29,7 @@
|
|||||||
"Enable WebAuthn signin - Tooltip": "Enable WebAuthn signin - Tooltip",
|
"Enable WebAuthn signin - Tooltip": "Enable WebAuthn signin - Tooltip",
|
||||||
"Enable code signin": "Enable code signin",
|
"Enable code signin": "Enable code signin",
|
||||||
"Enable code signin - Tooltip": "Enable code signin - Tooltip",
|
"Enable code signin - Tooltip": "Enable code signin - Tooltip",
|
||||||
|
"Enable side panel": "Enable side panel",
|
||||||
"Enable signin session - Tooltip": "Enable signin session - Tooltip",
|
"Enable signin session - Tooltip": "Enable signin session - Tooltip",
|
||||||
"Enable signup": "Enable signup",
|
"Enable signup": "Enable signup",
|
||||||
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
||||||
@@ -39,6 +41,7 @@
|
|||||||
"From position - Tooltip": "From position - Tooltip",
|
"From position - Tooltip": "From position - Tooltip",
|
||||||
"Grant types": "Grant types",
|
"Grant types": "Grant types",
|
||||||
"Grant types - Tooltip": "Grant types - Tooltip",
|
"Grant types - Tooltip": "Grant types - Tooltip",
|
||||||
|
"Left": "Left",
|
||||||
"New Application": "New Application",
|
"New Application": "New Application",
|
||||||
"Password ON": "Password ON",
|
"Password ON": "Password ON",
|
||||||
"Password ON - Tooltip": "Whether to allow password login",
|
"Password ON - Tooltip": "Whether to allow password login",
|
||||||
@@ -49,9 +52,13 @@
|
|||||||
"Redirect URLs - Tooltip": "List of redirect addresses after successful login",
|
"Redirect URLs - Tooltip": "List of redirect addresses after successful login",
|
||||||
"Refresh token expire": "Refresh token expire",
|
"Refresh token expire": "Refresh token expire",
|
||||||
"Refresh token expire - Tooltip": "Refresh token expire - Tooltip",
|
"Refresh token expire - Tooltip": "Refresh token expire - Tooltip",
|
||||||
|
"Right": "Right",
|
||||||
"SAML metadata": "SAML metadata",
|
"SAML metadata": "SAML metadata",
|
||||||
"SAML metadata - Tooltip": "SAML metadata - Tooltip",
|
"SAML metadata - Tooltip": "SAML metadata - Tooltip",
|
||||||
"SAML metadata URL copied to clipboard successfully": "SAML metadata URL copied to clipboard successfully",
|
"SAML metadata URL copied to clipboard successfully": "SAML metadata URL copied to clipboard successfully",
|
||||||
|
"Side panel HTML": "Side panel HTML",
|
||||||
|
"Side panel HTML - Edit": "Side panel HTML - Edit",
|
||||||
|
"Side panel HTML - Tooltip": "Side panel HTML - Tooltip",
|
||||||
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser",
|
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser",
|
||||||
"Signin session": "Signin session",
|
"Signin session": "Signin session",
|
||||||
"Signup items": "Signup items",
|
"Signup items": "Signup items",
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
||||||
"Background URL": "Background URL",
|
"Background URL": "Background URL",
|
||||||
"Background URL - Tooltip": "Background URL - Tooltip",
|
"Background URL - Tooltip": "Background URL - Tooltip",
|
||||||
|
"Center": "Center",
|
||||||
"Copy SAML metadata URL": "Копировать адрес метаданных SAML",
|
"Copy SAML metadata URL": "Копировать адрес метаданных SAML",
|
||||||
"Copy prompt page URL": "Скопировать URL-адрес страницы запроса",
|
"Copy prompt page URL": "Скопировать URL-адрес страницы запроса",
|
||||||
"Copy signin page URL": "Скопировать URL-адрес страницы входа",
|
"Copy signin page URL": "Скопировать URL-адрес страницы входа",
|
||||||
@@ -28,6 +29,7 @@
|
|||||||
"Enable WebAuthn signin - Tooltip": "Включить вход с WebAuthn - Подсказка",
|
"Enable WebAuthn signin - Tooltip": "Включить вход с WebAuthn - Подсказка",
|
||||||
"Enable code signin": "Включить кодовый вход",
|
"Enable code signin": "Включить кодовый вход",
|
||||||
"Enable code signin - Tooltip": "Включить вход с кодом - Tooltip",
|
"Enable code signin - Tooltip": "Включить вход с кодом - Tooltip",
|
||||||
|
"Enable side panel": "Enable side panel",
|
||||||
"Enable signin session - Tooltip": "Включить сеанс входа - Подсказка",
|
"Enable signin session - Tooltip": "Включить сеанс входа - Подсказка",
|
||||||
"Enable signup": "Включить регистрацию",
|
"Enable signup": "Включить регистрацию",
|
||||||
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
||||||
@@ -39,6 +41,7 @@
|
|||||||
"From position - Tooltip": "From position - Tooltip",
|
"From position - Tooltip": "From position - Tooltip",
|
||||||
"Grant types": "Виды грантов",
|
"Grant types": "Виды грантов",
|
||||||
"Grant types - Tooltip": "Виды грантов - Подсказка",
|
"Grant types - Tooltip": "Виды грантов - Подсказка",
|
||||||
|
"Left": "Left",
|
||||||
"New Application": "Новое приложение",
|
"New Application": "Новое приложение",
|
||||||
"Password ON": "Пароль ВКЛ",
|
"Password ON": "Пароль ВКЛ",
|
||||||
"Password ON - Tooltip": "Whether to allow password login",
|
"Password ON - Tooltip": "Whether to allow password login",
|
||||||
@@ -49,9 +52,13 @@
|
|||||||
"Redirect URLs - Tooltip": "List of redirect addresses after successful login",
|
"Redirect URLs - Tooltip": "List of redirect addresses after successful login",
|
||||||
"Refresh token expire": "Срок действия обновления токена истекает",
|
"Refresh token expire": "Срок действия обновления токена истекает",
|
||||||
"Refresh token expire - Tooltip": "Срок обновления токена истекает - Подсказка",
|
"Refresh token expire - Tooltip": "Срок обновления токена истекает - Подсказка",
|
||||||
|
"Right": "Right",
|
||||||
"SAML metadata": "Метаданные SAML",
|
"SAML metadata": "Метаданные SAML",
|
||||||
"SAML metadata - Tooltip": "Метаданные SAML - Подсказка",
|
"SAML metadata - Tooltip": "Метаданные SAML - Подсказка",
|
||||||
"SAML metadata URL copied to clipboard successfully": "Адрес метаданных SAML скопирован в буфер обмена",
|
"SAML metadata URL copied to clipboard successfully": "Адрес метаданных SAML скопирован в буфер обмена",
|
||||||
|
"Side panel HTML": "Side panel HTML",
|
||||||
|
"Side panel HTML - Edit": "Side panel HTML - Edit",
|
||||||
|
"Side panel HTML - Tooltip": "Side panel HTML - Tooltip",
|
||||||
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "URL страницы входа успешно скопирован в буфер обмена, пожалуйста, вставьте его в окно инкогнито или другой браузер",
|
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "URL страницы входа успешно скопирован в буфер обмена, пожалуйста, вставьте его в окно инкогнито или другой браузер",
|
||||||
"Signin session": "Сессия входа",
|
"Signin session": "Сессия входа",
|
||||||
"Signup items": "Элементы регистрации",
|
"Signup items": "Элементы регистрации",
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
"Auto signin - Tooltip": "当Casdoor存在已登录会话时,自动采用该会话进行应用端的登录",
|
"Auto signin - Tooltip": "当Casdoor存在已登录会话时,自动采用该会话进行应用端的登录",
|
||||||
"Background URL": "背景图URL",
|
"Background URL": "背景图URL",
|
||||||
"Background URL - Tooltip": "登录页背景图的链接",
|
"Background URL - Tooltip": "登录页背景图的链接",
|
||||||
|
"Center": "居中",
|
||||||
"Copy SAML metadata URL": "复制SAML元数据URL",
|
"Copy SAML metadata URL": "复制SAML元数据URL",
|
||||||
"Copy prompt page URL": "复制提醒页面URL",
|
"Copy prompt page URL": "复制提醒页面URL",
|
||||||
"Copy signin page URL": "复制登录页面URL",
|
"Copy signin page URL": "复制登录页面URL",
|
||||||
@@ -28,6 +29,7 @@
|
|||||||
"Enable WebAuthn signin - Tooltip": "是否支持用户在登录页面通过WebAuthn方式登录",
|
"Enable WebAuthn signin - Tooltip": "是否支持用户在登录页面通过WebAuthn方式登录",
|
||||||
"Enable code signin": "启用验证码登录",
|
"Enable code signin": "启用验证码登录",
|
||||||
"Enable code signin - Tooltip": "是否允许用手机或邮箱验证码登录",
|
"Enable code signin - Tooltip": "是否允许用手机或邮箱验证码登录",
|
||||||
|
"Enable side panel": "启用侧面板",
|
||||||
"Enable signin session - Tooltip": "从应用登录Casdoor后,Casdoor是否保持会话",
|
"Enable signin session - Tooltip": "从应用登录Casdoor后,Casdoor是否保持会话",
|
||||||
"Enable signup": "启用注册",
|
"Enable signup": "启用注册",
|
||||||
"Enable signup - Tooltip": "是否允许用户注册",
|
"Enable signup - Tooltip": "是否允许用户注册",
|
||||||
@@ -39,6 +41,7 @@
|
|||||||
"From position - Tooltip": "登录和注册面板的位置",
|
"From position - Tooltip": "登录和注册面板的位置",
|
||||||
"Grant types": "OAuth授权类型",
|
"Grant types": "OAuth授权类型",
|
||||||
"Grant types - Tooltip": "选择允许哪些OAuth协议中的Grant types",
|
"Grant types - Tooltip": "选择允许哪些OAuth协议中的Grant types",
|
||||||
|
"Left": "居左",
|
||||||
"New Application": "添加应用",
|
"New Application": "添加应用",
|
||||||
"Password ON": "开启密码",
|
"Password ON": "开启密码",
|
||||||
"Password ON - Tooltip": "是否允许密码登录",
|
"Password ON - Tooltip": "是否允许密码登录",
|
||||||
@@ -49,9 +52,13 @@
|
|||||||
"Redirect URLs - Tooltip": "登录成功后重定向地址列表",
|
"Redirect URLs - Tooltip": "登录成功后重定向地址列表",
|
||||||
"Refresh token expire": "Refresh Token过期",
|
"Refresh token expire": "Refresh Token过期",
|
||||||
"Refresh token expire - Tooltip": "Refresh Token过期时间",
|
"Refresh token expire - Tooltip": "Refresh Token过期时间",
|
||||||
|
"Right": "居右",
|
||||||
"SAML metadata": "SAML元数据",
|
"SAML metadata": "SAML元数据",
|
||||||
"SAML metadata - Tooltip": "SAML协议的元数据(Metadata)信息",
|
"SAML metadata - Tooltip": "SAML协议的元数据(Metadata)信息",
|
||||||
"SAML metadata URL copied to clipboard successfully": "SAML元数据URL已成功复制到剪贴板",
|
"SAML metadata URL copied to clipboard successfully": "SAML元数据URL已成功复制到剪贴板",
|
||||||
|
"Side panel HTML": "侧面板 HTML",
|
||||||
|
"Side panel HTML - Edit": "侧面板 HTML - 编辑",
|
||||||
|
"Side panel HTML - Tooltip": "侧面板 HTML - Tooltip",
|
||||||
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "登录页面URL已成功复制到剪贴板,请粘贴到当前浏览器的隐身模式窗口或另一个浏览器访问",
|
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "登录页面URL已成功复制到剪贴板,请粘贴到当前浏览器的隐身模式窗口或另一个浏览器访问",
|
||||||
"Signin session": "保持登录会话",
|
"Signin session": "保持登录会话",
|
||||||
"Signup items": "注册项",
|
"Signup items": "注册项",
|
||||||
|
Reference in New Issue
Block a user