Merge branch 'fix/1.2.5/user' into test
This commit is contained in:
@@ -1,30 +1,36 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
about: Report an issue to help the project improve.
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
## Describe the bug
|
||||
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
### To Reproduce
|
||||
|
||||
Steps to reproduce the behavior:
|
||||
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
### Expected behavior
|
||||
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
### Screenshots
|
||||
|
||||
**Platform (please complete the following information):**
|
||||
- Device: [e.g. Desktop, Mobile]
|
||||
- OS: [e.g. macOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
If applicable, add screenshots or video to help explain your problem.
|
||||
|
||||
### Platform
|
||||
|
||||
- Device: [e.g. Desktop, Mobile]
|
||||
- OS: [e.g. macOS]
|
||||
- Browser and version: [e.g. Chrome, Safari]
|
||||
- Version: [e.g. v1.2.0]
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: Support
|
||||
url: https://answer.apache.org/community
|
||||
about: Contact us if you have any questions while using.
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Enhancement request
|
||||
about: Suggest an enhancement for this project. Improve an existing feature.
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## Is your enhancement request related to a problem? Please describe
|
||||
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
## Describe the solution you'd like
|
||||
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
## Describe alternatives you've considered
|
||||
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
@@ -1,17 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
about: Suggest an idea or possible new feature for this project.
|
||||
title: ''
|
||||
labels: enhancement
|
||||
labels: feature
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
## Is your feature request related to a problem? Please describe
|
||||
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
## Describe the solution you'd like
|
||||
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
## Describe alternatives you've considered
|
||||
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
name: Build PR Image
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, closed]
|
||||
|
||||
jobs:
|
||||
build-answer:
|
||||
name: Build and push `Answer`
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
if: ${{ github.event.action != 'closed' && github.repository_owner == 'apache' }}
|
||||
steps:
|
||||
- name: Checkout git repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Generate UUID image name
|
||||
id: uuid
|
||||
run: echo "UUID_WORKER=answer-$(uuidgen --time)" >> $GITHUB_ENV
|
||||
|
||||
- name: Docker metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: registry.uffizzi.com/${{ env.UUID_WORKER }}
|
||||
tags: |
|
||||
type=raw,value=30d
|
||||
|
||||
- name: Build and Push Image to registry.uffizzi.com - Uffizzi's ephemeral Registry
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
push: true
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha, mode=max
|
||||
|
||||
render-compose-file:
|
||||
name: Render Docker Compose File
|
||||
# Pass output of this workflow to another triggered by `workflow_run` event.
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- build-answer
|
||||
outputs:
|
||||
compose-file-cache-key: ${{ steps.hash.outputs.hash }}
|
||||
steps:
|
||||
- name: Checkout git repo
|
||||
uses: actions/checkout@v4
|
||||
- name: Render Compose File
|
||||
run: |
|
||||
ANSWER_IMAGE=${{ needs.build-answer.outputs.tags }}
|
||||
export ANSWER_IMAGE
|
||||
export UFFIZZI_URL=\$UFFIZZI_URL
|
||||
# Render simple template from environment variables.
|
||||
envsubst < docker-compose.uffizzi.yml > docker-compose.rendered.yml
|
||||
cat docker-compose.rendered.yml
|
||||
- name: Upload Rendered Compose File as Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: preview-spec
|
||||
path: docker-compose.rendered.yml
|
||||
retention-days: 2
|
||||
- name: Serialize PR Event to File
|
||||
run: |
|
||||
cat << EOF > event.json
|
||||
${{ toJSON(github.event) }}
|
||||
|
||||
EOF
|
||||
- name: Upload PR Event as Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: preview-spec
|
||||
path: event.json
|
||||
retention-days: 2
|
||||
|
||||
delete-preview:
|
||||
name: Call for Preview Deletion
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.action == 'closed' && github.repository_owner == 'apache' }}
|
||||
steps:
|
||||
# If this PR is closing, we will not render a compose file nor pass it to the next workflow.
|
||||
- name: Serialize PR Event to File
|
||||
run: |
|
||||
cat << EOF > event.json
|
||||
${{ toJSON(github.event) }}
|
||||
|
||||
EOF
|
||||
- name: Upload PR Event as Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: preview-spec
|
||||
path: event.json
|
||||
retention-days: 2
|
||||
@@ -1,113 +0,0 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
name: Deploy Uffizzi Preview
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- "Build PR Image"
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
cache-compose-file:
|
||||
name: Cache Compose File
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
outputs:
|
||||
compose-file-cache-key: ${{ steps.hash.outputs.COMPOSE_FILE_HASH }}
|
||||
git-ref: ${{ steps.event.outputs.GIT_REF }}
|
||||
pr-number: ${{ steps.event.outputs.PR_NUMBER }}
|
||||
action: ${{ steps.event.outputs.ACTION }}
|
||||
steps:
|
||||
- name: Download artifacts
|
||||
# Fetch output (zip archive) from the workflow run that triggered this workflow.
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
run_id: context.payload.workflow_run.id,
|
||||
});
|
||||
let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => {
|
||||
return artifact.name == "preview-spec"
|
||||
})[0];
|
||||
if (matchArtifact === undefined) {
|
||||
throw TypeError('Build Artifact not found!');
|
||||
}
|
||||
let download = await github.rest.actions.downloadArtifact({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
artifact_id: matchArtifact.id,
|
||||
archive_format: 'zip',
|
||||
});
|
||||
let fs = require('fs');
|
||||
fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/preview-spec.zip`, Buffer.from(download.data));
|
||||
|
||||
- name: 'Accept event from first stage'
|
||||
run: unzip preview-spec.zip event.json
|
||||
|
||||
- name: Read Event into ENV
|
||||
id: event
|
||||
run: |
|
||||
echo PR_NUMBER=$(jq '.number | tonumber' < event.json) >> $GITHUB_OUTPUT
|
||||
echo ACTION=$(jq --raw-output '.action | tostring | [scan("\\w+")][0]' < event.json) >> $GITHUB_OUTPUT
|
||||
echo GIT_REF=$(jq --raw-output '.pull_request.head.sha | tostring | [scan("\\w+")][0]' < event.json) >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Hash Rendered Compose File
|
||||
id: hash
|
||||
# If the previous workflow was triggered by a PR close event, we will not have a compose file artifact.
|
||||
if: ${{ steps.event.outputs.ACTION != 'closed' }}
|
||||
run: |
|
||||
unzip preview-spec.zip docker-compose.rendered.yml
|
||||
echo "COMPOSE_FILE_HASH=$(md5sum docker-compose.rendered.yml | awk '{ print $1 }')" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Cache Rendered Compose File
|
||||
if: ${{ steps.event.outputs.ACTION != 'closed' }}
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: docker-compose.rendered.yml
|
||||
key: ${{ steps.hash.outputs.COMPOSE_FILE_HASH }}
|
||||
|
||||
- name: DEBUG - Print Job Outputs
|
||||
if: ${{ runner.debug }}
|
||||
run: |
|
||||
echo "PR number: ${{ steps.event.outputs.PR_NUMBER }}"
|
||||
echo "Git Ref: ${{ steps.event.outputs.GIT_REF }}"
|
||||
echo "Action: ${{ steps.event.outputs.ACTION }}"
|
||||
echo "Compose file hash: ${{ steps.hash.outputs.COMPOSE_FILE_HASH }}"
|
||||
cat event.json
|
||||
|
||||
deploy-uffizzi-preview:
|
||||
name: Use Remote Workflow to Preview on Uffizzi
|
||||
needs:
|
||||
- cache-compose-file
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
uses: UffizziCloud/preview-action/.github/workflows/reusable.yaml@v2
|
||||
with:
|
||||
# If this workflow was triggered by a PR close event, cache-key will be an empty string
|
||||
# and this reusable workflow will delete the preview deployment.
|
||||
compose-file-cache-key: ${{ needs.cache-compose-file.outputs.compose-file-cache-key }}
|
||||
compose-file-cache-path: docker-compose.rendered.yml
|
||||
server: https://app.uffizzi.com
|
||||
pr-number: ${{ needs.cache-compose-file.outputs.pr-number }}
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
id-token: write
|
||||
+8
-4
@@ -32,7 +32,7 @@ builds:
|
||||
- id: build
|
||||
main: ./cmd/answer/.
|
||||
binary: answer
|
||||
ldflags: -s -w -X github.com/apache/incubator-answer/cmd.Version={{.Version}} -X github.com/apache/incubator-answer/cmd.Revision={{.ShortCommit}} -X github.com/apache/incubator-answer/cmd.Time={{.Date}} -X github.com/apache/incubator-answer/cmd.BuildUser=goreleaser
|
||||
ldflags: -s -w -X github.com/apache/incubator-answer/cmd.Version={{.RawVersion}} -X github.com/apache/incubator-answer/cmd.Revision={{.ShortCommit}} -X github.com/apache/incubator-answer/cmd.Time={{.Date}} -X github.com/apache/incubator-answer/cmd.BuildUser=goreleaser
|
||||
flags: -v
|
||||
goos:
|
||||
- linux
|
||||
@@ -43,7 +43,7 @@ builds:
|
||||
- id: build-windows
|
||||
main: ./cmd/answer/.
|
||||
binary: answer
|
||||
ldflags: -s -w -X github.com/apache/incubator-answer/cmd.Version={{.Version}} -X github.com/apache/incubator-answer/cmd.Revision={{.ShortCommit}} -X github.com/apache/incubator-answer/cmd.Time={{.Date}} -X github.com/apache/incubator-answer/cmd.BuildUser=goreleaser
|
||||
ldflags: -s -w -X github.com/apache/incubator-answer/cmd.Version={{.RawVersion}} -X github.com/apache/incubator-answer/cmd.Revision={{.ShortCommit}} -X github.com/apache/incubator-answer/cmd.Time={{.Date}} -X github.com/apache/incubator-answer/cmd.BuildUser=goreleaser
|
||||
flags: -v
|
||||
goos:
|
||||
- windows
|
||||
@@ -55,7 +55,7 @@ builds:
|
||||
|
||||
archives:
|
||||
- name_template: >-
|
||||
apache-answer-{{ .Version }}-incubating-{{ .Os }}-{{ .Arch }}
|
||||
apache-answer-{{ .RawVersion }}-incubating-bin-{{ .Os }}-{{ .Arch }}
|
||||
files:
|
||||
- src: "docs/release/LICENSE"
|
||||
dst: LICENSE
|
||||
@@ -76,5 +76,9 @@ changelog:
|
||||
- '^docs:'
|
||||
- '^test:'
|
||||
|
||||
# goreleaser release --snapshot --rm-dist
|
||||
source:
|
||||
enabled: true
|
||||
name_template: apache-answer-{{ .RawVersion }}-incubating-src
|
||||
|
||||
# goreleaser release --skip-validate --skip-publish --clean
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ DIR_SRC=./cmd/answer
|
||||
DOCKER_CMD=docker
|
||||
|
||||
GO_ENV=CGO_ENABLED=0 GO111MODULE=on
|
||||
Revision=$(shell git rev-parse --short HEAD)
|
||||
Revision=$(shell git rev-parse --short HEAD 2>/dev/null || echo "")
|
||||
GO_FLAGS=-ldflags="-X github.com/apache/incubator-answer/cmd.Version=$(VERSION) -X 'github.com/apache/incubator-answer/cmd.Revision=$(Revision)' -X 'github.com/apache/incubator-answer/cmd.Time=`date +%s`' -extldflags -static"
|
||||
GO=$(GO_ENV) $(shell which go)
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ To learn more about the project, visit [answer.apache.org](https://answer.apache
|
||||
docker run -d -p 9080:80 -v answer-data:/data --name answer apache/answer:1.2.1
|
||||
```
|
||||
|
||||
For more information, see [Installation](https://answer.apache.org/docs/installation)
|
||||
For more information, see [Installation](https://answer.apache.org/docs/installation).
|
||||
|
||||
### Plugins
|
||||
|
||||
@@ -43,11 +43,17 @@ You can also check out the [plugins here](https://answer.apache.org/plugins).
|
||||
- Golang >= 1.18
|
||||
- Node.js >= 16.17
|
||||
- pnpm >= 8
|
||||
- mockgen >= 1.6.0
|
||||
- wire >= 0.5.0
|
||||
|
||||
### Build
|
||||
|
||||
```bash
|
||||
# install wire and mockgen for building
|
||||
$ make generate
|
||||
# install frontend dependencies and build
|
||||
$ make ui
|
||||
# install backend dependencies and build
|
||||
$ make build
|
||||
```
|
||||
|
||||
|
||||
+3
-2
@@ -44,9 +44,10 @@ var (
|
||||
// Version is the version of the project
|
||||
Version = "0.0.0"
|
||||
// Revision is the git short commit revision number
|
||||
Revision = "-"
|
||||
// If built without a Git repository, this field will be empty.
|
||||
Revision = ""
|
||||
// Time is the build time of the project
|
||||
Time = "-"
|
||||
Time = ""
|
||||
// GoVersion is the go version of the project
|
||||
GoVersion = "1.19"
|
||||
// log level
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
version: "3.9"
|
||||
|
||||
# uffizzi integration
|
||||
x-uffizzi:
|
||||
ingress:
|
||||
service: answer
|
||||
port: 80
|
||||
|
||||
services:
|
||||
|
||||
answer:
|
||||
image: "${ANSWER_IMAGE}"
|
||||
environment:
|
||||
- AUTO_INSTALL=true
|
||||
- DB_TYPE=mysql
|
||||
- DB_USERNAME=root
|
||||
- DB_PASSWORD=password
|
||||
- DB_HOST=127.0.0.1:3306
|
||||
- DB_NAME=answer
|
||||
- LANGUAGE=en_US
|
||||
- SITE_NAME=answer-test
|
||||
- SITE_URL=http://localhost
|
||||
- CONTACT_EMAIL=test@answer.com
|
||||
- ADMIN_NAME=admin123
|
||||
- ADMIN_PASSWORD=admin123
|
||||
- ADMIN_EMAIL=admin123@admin.com
|
||||
volumes:
|
||||
- answer-data:/data
|
||||
depends_on:
|
||||
mysql:
|
||||
condition: service_healthy
|
||||
links:
|
||||
- db
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 4000M
|
||||
|
||||
mysql:
|
||||
image: mysql:latest
|
||||
environment:
|
||||
- MYSQL_DATABASE=answer
|
||||
- MYSQL_ROOT_PASSWORD=password
|
||||
- MYSQL_USER=mysql
|
||||
- MYSQL_PASSWORD=mysql
|
||||
healthcheck:
|
||||
test: [ "CMD", "mysqladmin" ,"ping", "-uroot", "-ppassword" ]
|
||||
timeout: 20s
|
||||
retries: 10
|
||||
command: ['mysqld', '--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci', '--skip-character-set-client-handshake']
|
||||
volumes:
|
||||
- sql_data:/var/lib/mysql
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 500M
|
||||
|
||||
volumes:
|
||||
answer-data:
|
||||
sql_data:
|
||||
@@ -1,3 +1,21 @@
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
-->
|
||||
<svg width="126" height="44" viewBox="0 0 126 44" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="125.49" height="44" rx="6" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 14.4C8 12.1598 8 11.0397 8.43597 10.184C8.81947 9.43139 9.43139 8.81947 10.184 8.43597C11.0397 8 12.1598 8 14.4 8H29.6C31.8402 8 32.9603 8 33.816 8.43597C34.5686 8.81947 35.1805 9.43139 35.564 10.184C36 11.0397 36 12.1598 36 14.4V24.0892C36 26.9608 36 28.3967 35.5628 29.6643C35.1761 30.7853 34.5451 31.8063 33.7153 32.6535C32.7771 33.6115 31.4928 34.2536 28.9244 35.5378L28 36V32H14.4C12.1598 32 11.0397 32 10.184 31.564C9.43139 31.1805 8.81947 30.5686 8.43597 29.816C8 28.9603 8 27.8402 8 25.6V14.4ZM28 20C28 23.3137 25.3137 26 22 26C18.6954 26 16.0148 23.3285 16.0001 20.0274V20H28Z" fill="#0033FF"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 6.4 KiB |
@@ -1,3 +1,20 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
module github.com/apache/incubator-answer
|
||||
|
||||
go 1.18
|
||||
|
||||
+1
-1
@@ -360,7 +360,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description (optional)
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -360,7 +360,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description (optional)
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -355,7 +355,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description (optional)
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -355,7 +355,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description (optional)
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -355,7 +355,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description (optional)
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -355,7 +355,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description (optional)
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -355,7 +355,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description (optional)
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -360,7 +360,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description (optional)
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -601,7 +601,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -601,7 +601,7 @@ ui:
|
||||
msg:
|
||||
empty: Ni all ffeil fod yn wag.
|
||||
only_image: Dim ond ffeiliau delwedd a ganiateir.
|
||||
max_size: Ni all maint y ffeil fod yn fwy na 4MB.
|
||||
max_size: Ni all maint y ffeil fod yn fwy na 4 MB.
|
||||
desc:
|
||||
label: Disgrifiad
|
||||
tab_url: URL delwedd
|
||||
|
||||
+1
-1
@@ -601,7 +601,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -360,7 +360,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description (optional)
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -615,7 +615,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -601,7 +601,7 @@ ui:
|
||||
msg:
|
||||
empty: El título no puede estar vacío.
|
||||
only_image: Solo se permiten archivos de imagen.
|
||||
max_size: El tamaño del archivo no puede superar 4MB.
|
||||
max_size: El tamaño del archivo no puede superar 4 MB.
|
||||
desc:
|
||||
label: Descripción
|
||||
tab_url: URL de la imagen
|
||||
|
||||
+1
-1
@@ -360,7 +360,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description (optional)
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -360,7 +360,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description (optional)
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -360,7 +360,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description (optional)
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -355,7 +355,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description (optional)
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -601,7 +601,7 @@ ui:
|
||||
msg:
|
||||
empty: File tidak boleh kosong.
|
||||
only_image: Hanya file Gambar yang diperbolehkan.
|
||||
max_size: Ukuran file tidak boleh melebihi 4MB.
|
||||
max_size: Ukuran file tidak boleh melebihi 4 MB.
|
||||
desc:
|
||||
label: Description
|
||||
tab_url: URL gambar
|
||||
|
||||
+1
-1
@@ -601,7 +601,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -601,7 +601,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -360,7 +360,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description (optional)
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -360,7 +360,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description (optional)
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -360,7 +360,7 @@ ui:
|
||||
msg:
|
||||
empty: Arquivo não pode ser vazio.
|
||||
only_image: Somente um arquivo de imagem é permitido.
|
||||
max_size: O tamanho do arquivo não pode exceder 4MB.
|
||||
max_size: O tamanho do arquivo não pode exceder 4 MB.
|
||||
desc:
|
||||
label: Descrição (opcional)
|
||||
tab_url: URL da imagem
|
||||
|
||||
+1
-1
@@ -601,7 +601,7 @@ ui:
|
||||
msg:
|
||||
empty: Arquivo não pode ser vazio.
|
||||
only_image: Somente um arquivo de imagem é permitido.
|
||||
max_size: O tamanho do arquivo não pode exceder 4MB.
|
||||
max_size: O tamanho do arquivo não pode exceder 4 MB.
|
||||
desc:
|
||||
label: Descrição (opcional)
|
||||
tab_url: URL da imagem
|
||||
|
||||
+1
-1
@@ -360,7 +360,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description (optional)
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -601,7 +601,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Описание
|
||||
tab_url: URL изображения
|
||||
|
||||
+1
-1
@@ -601,7 +601,7 @@ ui:
|
||||
msg:
|
||||
empty: Názov súboru nemôže byť prázdny.
|
||||
only_image: Povolené sú iba obrázkové súbory.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Popis
|
||||
tab_url: URL obrázka
|
||||
|
||||
+1
-1
@@ -355,7 +355,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description (optional)
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -360,7 +360,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description (optional)
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -360,7 +360,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description (optional)
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -601,7 +601,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -601,7 +601,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description
|
||||
tab_url: Image URL
|
||||
|
||||
+1
-1
@@ -601,7 +601,7 @@ ui:
|
||||
msg:
|
||||
empty: File cannot be empty.
|
||||
only_image: Only image files are allowed.
|
||||
max_size: File size cannot exceed 4MB.
|
||||
max_size: File size cannot exceed 4 MB.
|
||||
desc:
|
||||
label: Description
|
||||
tab_url: Image URL
|
||||
|
||||
@@ -89,18 +89,51 @@ func (am *AuthUserMiddleware) EjectUserBySiteInfo() gin.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
_, isLogin := ctx.Get(ctxUUIDKey)
|
||||
if !isLogin {
|
||||
// If site in private mode, user must login.
|
||||
userInfo := GetUserInfoFromContext(ctx)
|
||||
if userInfo == nil {
|
||||
handler.HandleResponse(ctx, errors.Unauthorized(reason.UnauthorizedError), nil)
|
||||
ctx.Abort()
|
||||
return
|
||||
}
|
||||
// If user is not active, eject user.
|
||||
if userInfo.EmailStatus != entity.EmailStatusAvailable {
|
||||
handler.HandleResponse(ctx, errors.Forbidden(reason.EmailNeedToBeVerified),
|
||||
&schema.ForbiddenResp{Type: schema.ForbiddenReasonTypeInactive})
|
||||
ctx.Abort()
|
||||
return
|
||||
}
|
||||
ctx.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// MustAuth auth user info. If the user does not log in, an unauthenticated error is displayed
|
||||
func (am *AuthUserMiddleware) MustAuth() gin.HandlerFunc {
|
||||
// MustAuthWithoutAccountAvailable auth user info, any login user can access though user is not active.
|
||||
func (am *AuthUserMiddleware) MustAuthWithoutAccountAvailable() gin.HandlerFunc {
|
||||
return func(ctx *gin.Context) {
|
||||
token := ExtractToken(ctx)
|
||||
if len(token) == 0 {
|
||||
handler.HandleResponse(ctx, errors.Unauthorized(reason.UnauthorizedError), nil)
|
||||
ctx.Abort()
|
||||
return
|
||||
}
|
||||
userInfo, err := am.authService.GetUserCacheInfo(ctx, token)
|
||||
if err != nil || userInfo == nil {
|
||||
handler.HandleResponse(ctx, errors.Unauthorized(reason.UnauthorizedError), nil)
|
||||
ctx.Abort()
|
||||
return
|
||||
}
|
||||
if userInfo.UserStatus == entity.UserStatusDeleted {
|
||||
handler.HandleResponse(ctx, errors.Unauthorized(reason.UnauthorizedError), nil)
|
||||
ctx.Abort()
|
||||
return
|
||||
}
|
||||
ctx.Set(ctxUUIDKey, userInfo)
|
||||
ctx.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// MustAuthAndAccountAvailable auth user info and check user status, only allow active user access.
|
||||
func (am *AuthUserMiddleware) MustAuthAndAccountAvailable() gin.HandlerFunc {
|
||||
return func(ctx *gin.Context) {
|
||||
token := ExtractToken(ctx)
|
||||
if len(token) == 0 {
|
||||
|
||||
@@ -74,9 +74,14 @@ func NewHTTPServer(debug bool,
|
||||
unAuthV1.Use(authUserMiddleware.Auth(), authUserMiddleware.EjectUserBySiteInfo())
|
||||
answerRouter.RegisterUnAuthAnswerAPIRouter(unAuthV1)
|
||||
|
||||
// register api that must be authenticated but no need to check account status
|
||||
authWithoutStatusV1 := r.Group("/answer/api/v1")
|
||||
authWithoutStatusV1.Use(authUserMiddleware.MustAuthWithoutAccountAvailable())
|
||||
answerRouter.RegisterAuthUserWithAnyStatusAnswerAPIRouter(authWithoutStatusV1)
|
||||
|
||||
// register api that must be authenticated
|
||||
authV1 := r.Group("/answer/api/v1")
|
||||
authV1.Use(authUserMiddleware.MustAuth())
|
||||
authV1.Use(authUserMiddleware.MustAuthAndAccountAvailable())
|
||||
answerRouter.RegisterAnswerAPIRouter(authV1)
|
||||
|
||||
adminauthV1 := r.Group("/answer/admin/api")
|
||||
|
||||
@@ -144,9 +144,6 @@ func (a *AnswerAPIRouter) RegisterMustUnAuthAnswerAPIRouter(authUserMiddleware *
|
||||
|
||||
func (a *AnswerAPIRouter) RegisterUnAuthAnswerAPIRouter(r *gin.RouterGroup) {
|
||||
// user
|
||||
r.GET("/user/logout", a.userController.UserLogout)
|
||||
r.POST("/user/email/change/code", middleware.BanAPIForUserCenter, a.userController.UserChangeEmailSendCode)
|
||||
r.POST("/user/email/verification/send", middleware.BanAPIForUserCenter, a.userController.UserVerifyEmailSend)
|
||||
r.GET("/personal/user/info", a.userController.GetOtherUserInfoByUsername)
|
||||
r.GET("/user/ranking", a.userController.UserRanking)
|
||||
|
||||
@@ -186,6 +183,12 @@ func (a *AnswerAPIRouter) RegisterUnAuthAnswerAPIRouter(r *gin.RouterGroup) {
|
||||
r.GET("/personal/rank/page", a.rankController.GetRankPersonalWithPage)
|
||||
}
|
||||
|
||||
func (a *AnswerAPIRouter) RegisterAuthUserWithAnyStatusAnswerAPIRouter(r *gin.RouterGroup) {
|
||||
r.GET("/user/logout", a.userController.UserLogout)
|
||||
r.POST("/user/email/change/code", middleware.BanAPIForUserCenter, a.userController.UserChangeEmailSendCode)
|
||||
r.POST("/user/email/verification/send", middleware.BanAPIForUserCenter, a.userController.UserVerifyEmailSend)
|
||||
}
|
||||
|
||||
func (a *AnswerAPIRouter) RegisterAnswerAPIRouter(r *gin.RouterGroup) {
|
||||
// revisions
|
||||
r.GET("/revisions/unreviewed", a.revisionController.GetUnreviewedRevisionList)
|
||||
|
||||
@@ -235,6 +235,7 @@ func (ds *dashboardService) remoteVersion(ctx context.Context) string {
|
||||
}
|
||||
|
||||
func (ds *dashboardService) smtpStatus(ctx context.Context) (smtpStatus string) {
|
||||
smtpStatus = "not_configured"
|
||||
emailConf, err := ds.configService.GetStringValue(ctx, "email.config")
|
||||
if err != nil {
|
||||
log.Errorf("get email config failed: %s", err)
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
-->
|
||||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="32" height="32" fill="#DEE2E6"/>
|
||||
<path d="M8.5 25C8.5 25 7 25 7 23.5C7 22 8.5 17.5 16 17.5C23.5 17.5 25 22 25 23.5C25 25 23.5 25 23.5 25H8.5ZM16 16C17.1935 16 18.3381 15.5259 19.182 14.682C20.0259 13.8381 20.5 12.6935 20.5 11.5C20.5 10.3065 20.0259 9.16193 19.182 8.31802C18.3381 7.47411 17.1935 7 16 7C14.8065 7 13.6619 7.47411 12.818 8.31802C11.9741 9.16193 11.5 10.3065 11.5 11.5C11.5 12.6935 11.9741 13.8381 12.818 14.682C13.6619 15.5259 14.8065 16 16 16Z" fill="#6C757D"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 594 B After Width: | Height: | Size: 1.3 KiB |
Reference in New Issue
Block a user