Compare commits

..

No commits in common. "80765aab8c71219ffd32689b3d15558157c25b85" and "97b70a0cd40e8f73cdf6ba4397087b45061de3d8" have entirely different histories.

16 changed files with 42 additions and 100 deletions

View File

@ -139,7 +139,7 @@ GO_DIRS := build cmd models modules routers services tests
WEB_DIRS := web_src/js web_src/css
GO_SOURCES := $(wildcard *.go)
GO_SOURCES += $(shell find $(GO_DIRS) -type f -name "*.go" ! -path modules/options/bindata.go ! -path modules/public/bindata.go ! -path modules/templates/bindata.go)
GO_SOURCES += $(shell find $(GO_DIRS) -type f -name "*.go" -not -path modules/options/bindata.go -not -path modules/public/bindata.go -not -path modules/templates/bindata.go)
GO_SOURCES += $(GENERATED_GO_DEST)
GO_SOURCES_NO_BINDATA := $(GO_SOURCES)

View File

@ -10,7 +10,6 @@ import (
"encoding/base64"
"encoding/hex"
"errors"
"fmt"
"io"
"github.com/minio/sha256-simd"
@ -20,13 +19,13 @@ import (
func AesEncrypt(key, text []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, fmt.Errorf("AesEncrypt invalid key: %v", err)
return nil, err
}
b := base64.StdEncoding.EncodeToString(text)
ciphertext := make([]byte, aes.BlockSize+len(b))
iv := ciphertext[:aes.BlockSize]
if _, err = io.ReadFull(rand.Reader, iv); err != nil {
return nil, fmt.Errorf("AesEncrypt unable to read IV: %w", err)
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return nil, err
}
cfb := cipher.NewCFBEncrypter(block, iv)
cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b))
@ -40,7 +39,7 @@ func AesDecrypt(key, text []byte) ([]byte, error) {
return nil, err
}
if len(text) < aes.BlockSize {
return nil, errors.New("AesDecrypt ciphertext too short")
return nil, errors.New("ciphertext too short")
}
iv := text[:aes.BlockSize]
text = text[aes.BlockSize:]
@ -48,7 +47,7 @@ func AesDecrypt(key, text []byte) ([]byte, error) {
cfb.XORKeyStream(text, text)
data, err := base64.StdEncoding.DecodeString(string(text))
if err != nil {
return nil, fmt.Errorf("AesDecrypt invalid decrypted base64 string: %w", err)
return nil, err
}
return data, nil
}
@ -59,21 +58,21 @@ func EncryptSecret(key, str string) (string, error) {
plaintext := []byte(str)
ciphertext, err := AesEncrypt(keyHash[:], plaintext)
if err != nil {
return "", fmt.Errorf("failed to encrypt by secret: %w", err)
return "", err
}
return hex.EncodeToString(ciphertext), nil
}
// DecryptSecret decrypts a previously encrypted hex string
func DecryptSecret(key, cipherHex string) (string, error) {
func DecryptSecret(key, cipherhex string) (string, error) {
keyHash := sha256.Sum256([]byte(key))
ciphertext, err := hex.DecodeString(cipherHex)
ciphertext, err := hex.DecodeString(cipherhex)
if err != nil {
return "", fmt.Errorf("failed to decrypt by secret, invalid hex string: %w", err)
return "", err
}
plaintext, err := AesDecrypt(keyHash[:], ciphertext)
if err != nil {
return "", fmt.Errorf("failed to decrypt by secret, the key (maybe SECRET_KEY?) might be incorrect: %w", err)
return "", err
}
return string(plaintext), nil
}

View File

@ -10,22 +10,14 @@ import (
)
func TestEncryptDecrypt(t *testing.T) {
hex, err := EncryptSecret("foo", "baz")
assert.NoError(t, err)
str, _ := DecryptSecret("foo", hex)
var hex string
var str string
hex, _ = EncryptSecret("foo", "baz")
str, _ = DecryptSecret("foo", hex)
assert.Equal(t, "baz", str)
hex, err = EncryptSecret("bar", "baz")
assert.NoError(t, err)
hex, _ = EncryptSecret("bar", "baz")
str, _ = DecryptSecret("foo", hex)
assert.NotEqual(t, "baz", str)
_, err = DecryptSecret("a", "b")
assert.ErrorContains(t, err, "invalid hex string")
_, err = DecryptSecret("a", "bb")
assert.ErrorContains(t, err, "the key (maybe SECRET_KEY?) might be incorrect: AesDecrypt ciphertext too short")
_, err = DecryptSecret("a", "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")
assert.ErrorContains(t, err, "the key (maybe SECRET_KEY?) might be incorrect: AesDecrypt invalid decrypted base64 string")
}

View File

@ -179,6 +179,7 @@ func NewFuncMap() template.FuncMap {
// -----------------------------------------------------------------
// misc
"DiffLineTypeToStr": DiffLineTypeToStr,
"ShortSha": base.ShortSha,
"ActionContent2Commits": ActionContent2Commits,
"IsMultilineCommitMessage": IsMultilineCommitMessage,

View File

@ -122,6 +122,19 @@ func ActionContent2Commits(act Actioner) *repository.PushCommits {
return push
}
// DiffLineTypeToStr returns diff line type name
func DiffLineTypeToStr(diffType int) string {
switch diffType {
case 2:
return "add"
case 3:
return "del"
case 4:
return "tag"
}
return "same"
}
// MigrationIcon returns a SVG name matching the service an issue/comment was migrated from
func MigrationIcon(hostname string) string {
switch hostname {

View File

@ -1,17 +0,0 @@
ASWF Digital Assets License v1.0
License for <Asset Name> (the "Asset Name").
<Asset Name> Copyright <Year> <Asset Owner>. All rights reserved.
Redistribution and use of these digital assets, with or without modification, solely for education, training, research, software and hardware development, performance benchmarking (including publication of benchmark results and permitting reproducibility of the benchmark results by third parties), or software and hardware product demonstrations, are permitted provided that the following conditions are met:
1. Redistributions of these digital assets or any part of them must include the above copyright notice, this list of conditions and the disclaimer below.
2. Publications showing images derived from these digital assets must include the above copyright notice.
3. The names of copyright holder or the names of its contributors may NOT be used to promote or to imply endorsement, sponsorship, or affiliation with products developed or tested utilizing these digital assets or benchmarking results obtained from these digital assets, without prior written permission from copyright holder.
4. The assets and their output may only be referred to as the Asset Name listed above, and your use of the Asset Name shall be solely to identify the digital assets. Other than as expressly permitted by this License, you may NOT use any trade names, trademarks, service marks, or product names of the copyright holder for any purpose.
DISCLAIMER: THESE DIGITAL ASSETS ARE PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THESE DIGITAL ASSETS, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -308,7 +308,6 @@ repos = Repositories
users = Users
organizations = Organizations
search = Search
go_to = Go to
code = Code
search.type.tooltip = Search type
search.fuzzy = Fuzzy

View File

@ -104,19 +104,6 @@ func (d *DiffLine) GetType() int {
return int(d.Type)
}
// GetHTMLDiffLineType returns the diff line type name for HTML
func (d *DiffLine) GetHTMLDiffLineType() string {
switch d.Type {
case DiffLineAdd:
return "add"
case DiffLineDel:
return "del"
case DiffLineSection:
return "tag"
}
return "same"
}
// CanComment returns whether a line can get commented
func (d *DiffLine) CanComment() bool {
return len(d.Comments) == 0 && d.Type != DiffLineSection

View File

@ -1,6 +1,6 @@
{{if $.IsSplitStyle}}
{{range $k, $line := $.section.Lines}}
<tr class="{{.GetHTMLDiffLineType}}-code nl-{{$k}} ol-{{$k}}">
<tr class="{{DiffLineTypeToStr .GetType}}-code nl-{{$k}} ol-{{$k}}">
{{if eq .GetType 4}}
<td class="lines-num lines-num-old" data-line-num="{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}">
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5)}}
@ -44,7 +44,7 @@
{{end}}
{{else}}
{{range $k, $line := $.section.Lines}}
<tr class="{{.GetHTMLDiffLineType}}-code nl-{{$k}} ol-{{$k}}">
<tr class="{{DiffLineTypeToStr .GetType}}-code nl-{{$k}} ol-{{$k}}">
{{if eq .GetType 4}}
<td colspan="2" class="lines-num">
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5)}}

View File

@ -13,7 +13,7 @@
{{range $k, $line := $section.Lines}}
{{$hasmatch := ne $line.Match -1}}
{{if or (ne .GetType 2) (not $hasmatch)}}
<tr class="{{.GetHTMLDiffLineType}}-code nl-{{$k}} ol-{{$k}}" data-line-type="{{.GetHTMLDiffLineType}}">
<tr class="{{DiffLineTypeToStr .GetType}}-code nl-{{$k}} ol-{{$k}}" data-line-type="{{DiffLineTypeToStr .GetType}}">
{{if eq .GetType 4}}
<td class="lines-num lines-num-old">
{{if or (eq $line.GetExpandDirection 3) (eq $line.GetExpandDirection 5)}}
@ -107,7 +107,7 @@
{{if and (eq .GetType 3) $hasmatch}}
{{$match := index $section.Lines $line.Match}}
{{if or (gt (len $line.Comments) 0) (gt (len $match.Comments) 0)}}
<tr class="add-comment" data-line-type="{{.GetHTMLDiffLineType}}">
<tr class="add-comment" data-line-type="{{DiffLineTypeToStr .GetType}}">
<td class="add-comment-left" colspan="4">
{{if gt (len $line.Comments) 0}}
{{if eq $line.GetCommentSide "previous"}}
@ -133,7 +133,7 @@
</tr>
{{end}}
{{else if gt (len $line.Comments) 0}}
<tr class="add-comment" data-line-type="{{.GetHTMLDiffLineType}}">
<tr class="add-comment" data-line-type="{{DiffLineTypeToStr .GetType}}">
<td class="add-comment-left" colspan="4">
{{if gt (len $line.Comments) 0}}
{{if eq $line.GetCommentSide "previous"}}

View File

@ -8,7 +8,7 @@
</colgroup>
{{range $j, $section := $file.Sections}}
{{range $k, $line := $section.Lines}}
<tr class="{{.GetHTMLDiffLineType}}-code nl-{{$k}} ol-{{$k}}" data-line-type="{{.GetHTMLDiffLineType}}">
<tr class="{{DiffLineTypeToStr .GetType}}-code nl-{{$k}} ol-{{$k}}" data-line-type="{{DiffLineTypeToStr .GetType}}">
{{if eq .GetType 4}}
{{if $.root.AfterCommitID}}
<td colspan="2" class="lines-num">
@ -55,7 +55,7 @@
{{end}}
</tr>
{{if gt (len $line.Comments) 0}}
<tr class="add-comment" data-line-type="{{.GetHTMLDiffLineType}}">
<tr class="add-comment" data-line-type="{{DiffLineTypeToStr .GetType}}">
<td class="add-comment-left add-comment-right" colspan="5">
{{template "repo/diff/conversation" dict "." $.root "comments" $line.Comments}}
</td>

View File

@ -8,8 +8,7 @@
<input type="hidden" name="assignee" value="{{$.AssigneeID}}">
<input type="hidden" name="poster" value="{{$.PosterID}}">
<input name="q" value="{{.Keyword}}" placeholder="{{.locale.Tr "explore.search"}}...">
<button id="hashtag-button" class="ui small icon button gt-hidden" data-tooltip-content="{{.locale.Tr "explore.go_to"}}">{{svg "octicon-hash"}}</button>
<button id="search-button" class="ui small icon button" aria-label="{{.locale.Tr "explore.search"}}">
<button class="ui small icon button" type="submit" aria-label="{{.locale.Tr "explore.search"}}">
{{svg "octicon-search"}}
</button>
</div>

View File

@ -78,8 +78,7 @@
<input type="hidden" name="sort" value="{{$.SortType}}">
<input type="hidden" name="state" value="{{$.State}}">
<input name="q" value="{{$.Keyword}}" placeholder="{{.locale.Tr "explore.search"}}...">
<button id="hashtag-button" class="ui small icon button gt-hidden" data-tooltip-content="{{.locale.Tr "explore.go_to"}}">{{svg "octicon-hash"}}</button>
<button id="search-button" class="ui small icon button" aria-label="{{.locale.Tr "explore.search"}}">{{svg "octicon-search"}}</button>
<button class="ui small icon button" type="submit" aria-label="{{.locale.Tr "explore.search"}}">{{svg "octicon-search"}}</button>
</div>
</form>
<!-- Sort -->

View File

@ -1,6 +1,6 @@
# End to end tests
E2e tests largely follow the same syntax as [integration tests](../integration).
E2e tests largely follow the same syntax as [integration tests](tests/e2e/README.md).
Whereas integration tests are intended to mock and stress the back-end, server-side code, e2e tests the interface between front-end and back-end, as well as visual regressions with both assertions and visual comparisons.
They can be run with make commands for the appropriate backends, namely:
```shell

View File

@ -4,7 +4,6 @@ import {showTemporaryTooltip, createTippy} from '../modules/tippy.js';
import {hideElem, showElem, toggleElem} from '../utils/dom.js';
import {setFileFolding} from './file-fold.js';
import {getComboMarkdownEditor, initComboMarkdownEditor} from './comp/ComboMarkdownEditor.js';
import {parseIssueHref} from '../utils.js';
const {appSubUrl, csrfToken} = window.config;
@ -637,31 +636,3 @@ export function initRepoIssueBranchSelect() {
};
$('#branch-select > .item').on('click', changeBranchSelect);
}
export function initRepoIssueGotoID() {
const issueidre = /^(?:\w+\/\w+#\d+|#\d+|\d+)$/;
const isGlobalIssuesArea = $('.repo.name.item').length > 0; // for global issues area or repository issues area
$('form.list-header-search').on('submit', (e) => {
const qval = e.target.q.value;
const aElm = document.activeElement;
if (!$('#hashtag-button').length || aElm.id === 'search-button' || (aElm.name === 'q' && !qval.includes('#')) || (isGlobalIssuesArea && !qval.includes('/')) || !issueidre.test(qval)) return;
const pathname = window.location.pathname;
let gotoUrl = qval.includes('/') ? `${qval.replace('#', '/issues/')}` : `${pathname}/${qval.replace('#', '')}`;
if (appSubUrl.length) {
gotoUrl = qval.includes('/') ? `/${appSubUrl}/${qval.replace('#', '/issues/')}` : `/${appSubUrl}/${pathname}/${qval.replace('#', '')}`;
}
const {owner, repo, type, index} = parseIssueHref(gotoUrl);
if (owner && repo && type && index) {
e.preventDefault();
window.location.href = gotoUrl;
}
});
$('form.list-header-search input[name=q]').on('input', (e) => {
const qval = e.target.value;
if (isGlobalIssuesArea && qval.includes('/') && issueidre.test(qval) || !isGlobalIssuesArea && issueidre.test(qval)) {
showElem($('#hashtag-button'));
} else {
hideElem($('#hashtag-button'));
}
});
}

View File

@ -30,7 +30,7 @@ import {
initRepoIssueWipTitle,
initRepoPullRequestMergeInstruction,
initRepoPullRequestAllowMaintainerEdit,
initRepoPullRequestReview, initRepoIssueSidebarList, initRepoIssueGotoID
initRepoPullRequestReview, initRepoIssueSidebarList,
} from './features/repo-issue.js';
import {
initRepoEllipsisButton,
@ -175,5 +175,4 @@ onDomReady(() => {
initUserAuthWebAuthnRegister();
initUserSettings();
initRepoDiffView();
initRepoIssueGotoID();
});