1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-01 15:09:14 +00:00

Merge branch '7.0'

This commit is contained in:
lian
2020-01-06 16:25:55 +08:00
16 changed files with 118 additions and 1482 deletions

View File

@@ -64,11 +64,6 @@ module.exports = {
require.resolve('react-dev-utils/webpackHotDevClient'),
paths.appSrc + "/wiki.js",
],
repoview: [
require.resolve('./polyfills'),
require.resolve('react-dev-utils/webpackHotDevClient'),
paths.appSrc + "/repo-wiki-mode.js",
],
fileHistory: [
require.resolve('./polyfills'),
require.resolve('react-dev-utils/webpackHotDevClient'),

View File

@@ -61,7 +61,6 @@ module.exports = {
markdownEditor: [require.resolve('./polyfills'), paths.appIndexJs],
TCAccept: [require.resolve('./polyfills'), paths.appSrc + "/tc-accept.js"],
wiki: [require.resolve('./polyfills'), paths.appSrc + "/wiki.js"],
repoview: [require.resolve('./polyfills'), paths.appSrc + "/repo-wiki-mode.js"],
fileHistory: [require.resolve('./polyfills'), paths.appSrc + "/file-history.js"],
fileHistoryOld: [require.resolve('./polyfills'), paths.appSrc + "/file-history-old.js"],
app: [require.resolve('./polyfills'), paths.appSrc + "/app.js"],

View File

@@ -494,13 +494,10 @@ class DirentListItem extends React.Component {
}
renderItemOperation = () => {
let { dirent, selectedDirentList } = this.props;
let { dirent, currentRepoInfo, selectedDirentList } = this.props;
// no need to check whether show shareBtn or not.
// according to specification below, shareBtn aways show.
// check for "generate uploadlink" or other tabs should put inside the shareDialog.
// https://dev.seafile.com/seahub/lib/d6f300e7-bb2b-4722-b83e-cf45e370bfbc/file/seaf-server%20%E5%8A%9F%E8%83%BD%E8%AE%BE%E8%AE%A1/%E6%9D%83%E9%99%90%E7%9B%B8%E5%85%B3/%E8%B5%84%E6%96%99%E5%BA%93%E6%9D%83%E9%99%90%E8%A7%84%E8%8C%83.md
// let showShareBtn = Utils.isHasPermissionToShare(currentRepoInfo, dirent.permission, dirent);
let showShareBtn = Utils.isHasPermissionToShare(currentRepoInfo, dirent.permission, dirent);
return (
<Fragment>
@@ -514,9 +511,11 @@ class DirentListItem extends React.Component {
<i className="op-icon sf2-icon-download" title={gettext('Download')} onClick={this.onItemDownload}></i>
</li>
)}
<li className="operation-group-item">
<i className="op-icon sf2-icon-share" title={gettext('Share')} onClick={this.onItemShare}></i>
</li>
{showShareBtn && (
<li className="operation-group-item">
<i className="op-icon sf2-icon-share" title={gettext('Share')} onClick={this.onItemShare}></i>
</li>
)}
{dirent.permission === 'rw' && (
<li className="operation-group-item">
<i className="op-icon sf2-icon-delete" title={gettext('Delete')} onClick={this.onItemDelete}></i>
@@ -546,7 +545,7 @@ class DirentListItem extends React.Component {
<i className="op-icon sf2-icon-download" title={gettext('Download')} onClick={this.onItemDownload}></i>
</li>
)}
{(
{showShareBtn && (
<li className="operation-group-item">
<i className="op-icon sf2-icon-share" title={gettext('Share')} onClick={this.onItemShare}></i>
</li>

View File

@@ -2,7 +2,7 @@ import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import Resumablejs from '@seafile/resumablejs';
import MD5 from 'MD5';
import { enableResumableFileUpload, resumableUploadFileBlockSize } from '../../utils/constants';
import { enableResumableFileUpload, resumableUploadFileBlockSize, maxUploadFileSize } from '../../utils/constants';
import { seafileAPI } from '../../utils/seafile-api';
import { Utils } from '../../utils/utils';
import { gettext } from '../../utils/constants';
@@ -18,13 +18,11 @@ const propTypes = {
chunkSize: PropTypes.number,
withCredentials: PropTypes.bool,
maxFiles: PropTypes.number,
maxFileSize: PropTypes.number,
testMethod: PropTypes.string,
testChunks: PropTypes.number,
simultaneousUploads: PropTypes.number,
fileParameterName: PropTypes.string,
maxFilesErrorCallback: PropTypes.func,
maxFileSizeErrorCallback: PropTypes.func,
minFileSizeErrorCallback: PropTypes.func,
fileTypeErrorCallback: PropTypes.func,
dragAndDrop: PropTypes.bool.isRequired,
@@ -39,6 +37,7 @@ class FileUploader extends React.Component {
this.state = {
retryFileList: [],
uploadFileList: [],
forbidUploadFileList: [],
totalProgress: 0,
isUploadProgressDialogShow: false,
isUploadRemindDialogShow: false,
@@ -64,7 +63,7 @@ class FileUploader extends React.Component {
query: this.setQuery || {},
fileType: this.props.filetypes,
maxFiles: this.props.maxFiles,
maxFileSize: this.props.maxFileSize,
maxFileSize: maxUploadFileSize * 1000 * 1000 || undefined,
testMethod: this.props.testMethod || 'post',
testChunks: this.props.testChunks || false,
headers: this.setHeaders || {},
@@ -105,7 +104,7 @@ class FileUploader extends React.Component {
}
bindCallbackHandler = () => {
let {maxFilesErrorCallback, minFileSizeErrorCallback, maxFileSizeErrorCallback, fileTypeErrorCallback } = this.props;
let {maxFilesErrorCallback, minFileSizeErrorCallback, fileTypeErrorCallback } = this.props;
if (maxFilesErrorCallback) {
this.resumable.opts.maxFilesErrorCallback = this.props.maxFilesErrorCallback;
@@ -115,8 +114,8 @@ class FileUploader extends React.Component {
this.resumable.opts.minFileSizeErrorCallback = this.props.minFileSizeErrorCallback;
}
if (maxFileSizeErrorCallback) {
this.resumable.opts.maxFileSizeErrorCallback = this.props.maxFileSizeErrorCallback;
if (this.maxFileSizeErrorCallback) {
this.resumable.opts.maxFileSizeErrorCallback = this.maxFileSizeErrorCallback;
}
if (fileTypeErrorCallback) {
@@ -142,6 +141,12 @@ class FileUploader extends React.Component {
this.resumable.on('dragstart', this.onDragStart.bind(this));
}
maxFileSizeErrorCallback = (file) => {
let { forbidUploadFileList } = this.state;
forbidUploadFileList.push(file);
this.setState({forbidUploadFileList: forbidUploadFileList});
}
onChunkingComplete = (resumableFile) => {
let allFilesUploaded = this.state.allFilesUploaded;
@@ -229,7 +234,13 @@ class FileUploader extends React.Component {
}
filesAddedComplete = (resumable, files) => {
// single file uploading can check repetition, because custom dialog conn't prevent program execution;
let { forbidUploadFileList } = this.state;
if (forbidUploadFileList.length > 0 && files.length === 0) {
this.setState({
isUploadProgressDialogShow: true,
totalProgress: 100
});
}
}
setUploadFileList = () => {
@@ -377,7 +388,16 @@ class FileUploader extends React.Component {
if (!message) {
error = gettext('Network error');
} else {
error = message;
// eg: '{"error": "Internal error" \n }'
let errorMessage = message.replace(/\n/g, '');
errorMessage = JSON.parse(errorMessage);
error = errorMessage.error;
if (error === 'File locked by others.') {
error = gettext('File Locked by others.');
}
if (error === 'Internal error.') {
error = gettext('Internal error.');
}
}
let uploadFileList = this.state.uploadFileList.map(item => {
@@ -481,7 +501,7 @@ class FileUploader extends React.Component {
this.resumable.files = [];
// reset upload link loaded
this.isUploadLinkLoaded = false;
this.setState({isUploadProgressDialogShow: false, uploadFileList: []});
this.setState({isUploadProgressDialogShow: false, uploadFileList: [], forbidUploadFileList: []});
Utils.registerGlobalVariable('uploader', 'isUploadProgressDialogShow', false);
}
@@ -667,6 +687,7 @@ class FileUploader extends React.Component {
<UploadProgressDialog
retryFileList={this.state.retryFileList}
uploadFileList={this.state.uploadFileList}
forbidUploadFileList={this.state.forbidUploadFileList}
totalProgress={this.state.totalProgress}
uploadBitrate={this.state.uploadBitrate}
allFilesUploaded={this.state.allFilesUploaded}

View File

@@ -0,0 +1,28 @@
import React from 'react';
import PropTypes from 'prop-types';
import { gettext, maxUploadFileSize } from '../../utils/constants';
const propTypes = {
file: PropTypes.object,
};
class ForbidUploadListItem extends React.Component {
render() {
let { file } = this.props;
let msg = gettext('Please upload files less than {placeholder}M').replace('{placeholder}', maxUploadFileSize);
return (
<tr className="file-upload-item">
<td className="upload-name">
<div className="ellipsis">{file.name}</div>
</td>
<td colSpan={3} className="error">{msg}</td>
</tr>
);
}
}
ForbidUploadListItem.propTypes = propTypes;
export default ForbidUploadListItem;

View File

@@ -1,14 +1,16 @@
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { gettext } from '../../utils/constants';
import UploadListItem from './upload-list-item';
import { Utils } from '../../utils/utils';
import UploadListItem from './upload-list-item';
import ForbidUploadListItem from './forbid-upload-list-item';
const propTypes = {
uploadBitrate: PropTypes.number.isRequired,
totalProgress: PropTypes.number.isRequired,
retryFileList: PropTypes.array.isRequired,
uploadFileList: PropTypes.array.isRequired,
forbidUploadFileList: PropTypes.array.isRequired,
onCloseUploadDialog: PropTypes.func.isRequired,
onCancelAllUploading: PropTypes.func.isRequired,
onUploadCancel: PropTypes.func.isRequired,
@@ -94,6 +96,11 @@ class UploadProgressDialog extends React.Component {
}
</td>
</tr>
{
this.props.forbidUploadFileList.map((file, index) => {
return (<ForbidUploadListItem key={index} file={file} />);
})
}
{
this.props.uploadFileList.map((resumableFile, index) => {
return (

View File

@@ -1264,7 +1264,11 @@ class LibContentView extends React.Component {
let direntList = this.state.direntList.filter(item => {
return item.name !== name;
});
this.setState({ direntList: direntList });
// Recalculate the state of the selection
this.recaculateSelectedStateAfterDirentDeleted(name, direntList);
this.setState({direntList: direntList});
this.updateReadmeMarkdown(direntList);
} else if (Utils.isAncestorPath(direntPath, this.state.path)) {
// the deleted item is ancester of the current item
@@ -1283,6 +1287,10 @@ class LibContentView extends React.Component {
let direntList = this.state.direntList.filter(item => {
return item.name !== name;
});
// Recalculate the state of the selection
this.recaculateSelectedStateAfterDirentDeleted(name, direntList);
this.setState({direntList: direntList});
this.updateReadmeMarkdown(direntList);
}
@@ -1531,6 +1539,20 @@ class LibContentView extends React.Component {
});
}
recaculateSelectedStateAfterDirentDeleted = (name, newDirentList) => {
let selectedDirentList = this.state.selectedDirentList.slice(0);
if (selectedDirentList.length > 0) {
selectedDirentList = selectedDirentList.filter(item => {
return item.name !== name;
});
}
this.setState({
selectedDirentList: selectedDirentList,
isDirentSelected: selectedDirentList.length > 0,
isAllDirentSelected: selectedDirentList.length === newDirentList.length,
});
}
onLibDecryptDialog = () => {
this.setState({libNeedDecrypt: false});
this.loadDirData(this.state.path);

View File

@@ -1,315 +0,0 @@
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import cookie from 'react-cookies';
import { gettext, repoID, siteRoot, permission } from '../../utils/constants';
import { seafileAPI } from '../../utils/seafile-api';
import { Utils } from '../../utils/utils';
import RepoInfo from '../../models/repo-info';
import CommonToolbar from '../../components/toolbar/common-toolbar';
import ViewModeToolbar from '../../components/toolbar/view-mode-toolbar';
import DirOperationToolBar from '../../components/toolbar/dir-operation-toolbar';
import MultipleDirOperationToolbar from '../../components/toolbar/multiple-dir-operation-toolbar';
import CurDirPath from '../../components/cur-dir-path';
import WikiMarkdownViewer from '../../components/wiki-markdown-viewer';
import DirentListView from '../../components/dirent-list-view/dirent-list-view';
import DirentDetail from '../../components/dirent-detail/dirent-details';
import FileUploader from '../../components/file-uploader/file-uploader';
import RepoInfoBar from '../../components/repo-info-bar';
const propTypes = {
content: PropTypes.string,
lastModified: PropTypes.string,
latestContributor: PropTypes.string,
permission: PropTypes.string,
hash: PropTypes.string,
path: PropTypes.string.isRequired,
repoName: PropTypes.string.isRequired,
repoEncrypted: PropTypes.bool.isRequired,
showShareBtn: PropTypes.bool.isRequired,
enableDirPrivateShare: PropTypes.bool.isRequired,
userPerm: PropTypes.string.isRequired,
isAdmin: PropTypes.bool.isRequired,
isGroupOwnedRepo: PropTypes.bool.isRequired,
// whether the file or dir corresponding to the path exist
pathExist: PropTypes.bool.isRequired,
isFileLoading: PropTypes.bool.isRequired,
isViewFile: PropTypes.bool.isRequired,
isDirentListLoading: PropTypes.bool.isRequired,
isDirentSelected: PropTypes.bool.isRequired,
isAllDirentSelected: PropTypes.bool.isRequired,
direntList: PropTypes.array.isRequired,
sortBy: PropTypes.string.isRequired,
sortOrder: PropTypes.string.isRequired,
sortItems: PropTypes.func.isRequired,
selectedDirentList: PropTypes.array.isRequired,
updateDirent: PropTypes.func.isRequired,
onSideNavMenuClick: PropTypes.func.isRequired,
onSearchedClick: PropTypes.func.isRequired,
onMainNavBarClick: PropTypes.func.isRequired,
onItemClick: PropTypes.func.isRequired,
onAllDirentSelected: PropTypes.func.isRequired,
onItemSelected: PropTypes.func.isRequired,
onItemDelete: PropTypes.func.isRequired,
onItemRename: PropTypes.func.isRequired,
onItemMove: PropTypes.func.isRequired,
onItemCopy: PropTypes.func.isRequired,
onAddFile: PropTypes.func.isRequired,
onAddFolder: PropTypes.func.isRequired,
onFileTagChanged: PropTypes.func.isRequired,
onItemsMove: PropTypes.func.isRequired,
onItemsCopy: PropTypes.func.isRequired,
onItemsDelete: PropTypes.func.isRequired,
onLinkClick: PropTypes.func.isRequired,
onFileUploadSuccess: PropTypes.func.isRequired,
isDraft: PropTypes.bool,
hasDraft: PropTypes.bool,
goDraftPage: PropTypes.func,
usedRepoTags: PropTypes.array.isRequired,
readmeMarkdown: PropTypes.object,
draftCounts: PropTypes.number,
updateUsedRepoTags: PropTypes.func.isRequired,
};
class MainPanel extends Component {
constructor(props) {
super(props);
this.state = {
currentMode: 'wiki',
isDirentDetailShow: false,
currentDirent: null,
direntPath: '',
currentRepoInfo: null,
};
}
componentDidMount() {
seafileAPI.getRepoInfo(repoID).then(res => {
let repoInfo = new RepoInfo(res.data);
this.setState({
currentRepoInfo: repoInfo,
});
});
if (this.props.hash) {
let hash = this.props.hash;
setTimeout(function() {
window.location.hash = hash;
}, 500);
}
}
switchViewMode = (mode) => {
cookie.save('view_mode', mode, { path: '/' });
let repoName = this.state.currentRepoInfo.repo_name;
let dirPath = this.props.isViewFile ? Utils.getDirName(this.props.path) : this.props.path;
window.location.href = siteRoot + 'library/' + repoID + '/' + repoName + dirPath;
}
onSideNavMenuClick = () => {
this.props.onSideNavMenuClick();
}
onItemClick = (dirent) => {
this.setState({isDirentDetailShow: false});
this.props.onItemClick(dirent);
}
onMainNavBarClick = (path) => {
this.setState({isDirentDetailShow: false});
this.props.onMainNavBarClick(path);
}
// on '<tr>'
onDirentClick = (dirent) => {
if (this.state.isDirentDetailShow) {
this.onItemDetails(dirent);
}
}
onItemDetails = (dirent) => {
this.setState({
currentDirent: dirent,
isDirentDetailShow: true,
});
}
onItemDetailsClose = () => {
this.setState({isDirentDetailShow: false});
}
onFileTagChanged = (dirent, direntPath) => {
this.props.onFileTagChanged(dirent, direntPath);
}
onUploadFile = (e) => {
e.nativeEvent.stopImmediatePropagation();
this.uploader.onFileUpload();
}
onUploadFolder = (e) => {
e.nativeEvent.stopImmediatePropagation();
this.uploader.onFolderUpload();
}
onFileUploadSuccess = (direntObject) => {
this.props.onFileUploadSuccess(direntObject);
}
render() {
const ErrMessage = (<div className="message err-tip">{gettext('Folder does not exist.')}</div>);
const showRepoInfoBar = this.props.path === '/' && (
this.props.usedRepoTags.length != 0 || this.props.readmeMarkdown != null ||
this.props.draftCounts != 0);
return (
<div className="main-panel wiki-main-panel o-hidden">
<div className="main-panel-north border-left-show">
<div className="cur-view-toolbar">
<span className="sf2-icon-menu hidden-md-up d-md-none side-nav-toggle" title={gettext('Side Nav Menu')} onClick={this.onSideNavMenuClick}></span>
<div className="dir-operation">
{this.props.isDirentSelected ?
<MultipleDirOperationToolbar
repoID={repoID}
path={this.props.path}
selectedDirentList={this.props.selectedDirentList}
onItemsMove={this.props.onItemsMove}
onItemsCopy={this.props.onItemsCopy}
onItemsDelete={this.props.onItemsDelete}
/> :
<DirOperationToolBar
path={this.props.path}
repoID={repoID}
repoName={this.props.repoName}
repoEncrypted={this.props.repoEncrypted}
isDraft={this.props.isDraft}
hasDraft={this.props.hasDraft}
direntList={this.props.direntList}
permission={this.props.permission}
isViewFile={this.props.isViewFile}
showShareBtn={this.props.showShareBtn}
enableDirPrivateShare={this.props.enableDirPrivateShare}
userPerm={this.props.userPerm}
isAdmin={this.props.isAdmin}
isGroupOwnedRepo={this.props.isGroupOwnedRepo}
onAddFile={this.props.onAddFile}
onAddFolder={this.props.onAddFolder}
onUploadFile={this.onUploadFile}
onUploadFolder={this.onUploadFolder}
/>
}
</div>
<ViewModeToolbar currentMode={this.state.currentMode} switchViewMode={this.switchViewMode}/>
</div>
<CommonToolbar repoID={repoID} onSearchedClick={this.props.onSearchedClick} searchPlaceholder={gettext('Search files in this library')}/>
</div>
<div className="main-panel-center flex-row">
<div className="cur-view-container">
<div className="cur-view-path">
{this.state.currentRepoInfo && (
<CurDirPath
repoID={repoID}
repoName={this.state.currentRepoInfo.repo_name}
currentPath={this.props.path}
permission={permission}
onPathClick={this.onMainNavBarClick}
isViewFile={this.props.isViewFile}
updateUsedRepoTags={this.props.updateUsedRepoTags}
/>
)}
</div>
<div className="cur-view-content">
{!this.props.pathExist && ErrMessage }
{(this.props.pathExist && this.props.isViewFile) && (
<WikiMarkdownViewer
isFileLoading={this.props.isFileLoading}
markdownContent={this.props.content}
latestContributor={this.props.latestContributor}
lastModified = {this.props.lastModified}
onLinkClick={this.props.onLinkClick}
>
<Fragment>
{(!this.props.isDraft && this.props.hasDraft) &&
<div className='seafile-btn-view-review text-center'>
<div className='tag tag-green'>
{gettext('This file is in draft stage.')}
<a className="ml-2" onMouseDown={this.props.goDraftPage}>{gettext('View Draft')}</a>
</div>
</div>
}
</Fragment>
</WikiMarkdownViewer>
)}
{(this.props.pathExist && !this.props.isViewFile) && (
<Fragment>
{showRepoInfoBar && (
<RepoInfoBar
repoID={repoID}
currentPath={this.props.path}
usedRepoTags={this.props.usedRepoTags}
readmeMarkdown={this.props.readmeMarkdown}
draftCounts={this.props.draftCounts}
updateUsedRepoTags={this.props.updateUsedRepoTags}
/>
)}
<DirentListView
path={this.props.path}
repoID={repoID}
repoEncrypted={this.props.repoEncrypted}
isRepoOwner={this.props.isRepoOwner}
isAdmin={this.props.isAdmin}
isGroupOwnedRepo={this.props.isGroupOwnedRepo}
enableDirPrivateShare={this.props.enableDirPrivateShare}
direntList={this.props.direntList}
sortBy={this.props.sortBy}
sortOrder={this.props.sortOrder}
sortItems={this.props.sortItems}
onAddFile={this.props.onAddFile}
onItemClick={this.onItemClick}
onItemDelete={this.props.onItemDelete}
onItemRename={this.props.onItemRename}
onItemMove={this.props.onItemMove}
onItemCopy={this.props.onItemCopy}
onDirentClick={this.onDirentClick}
onItemDetails={this.onItemDetails}
isDirentListLoading={this.props.isDirentListLoading}
updateDirent={this.props.updateDirent}
currentRepoInfo={this.state.currentRepoInfo}
isAllItemSelected={this.props.isAllDirentSelected}
onAllItemSelected={this.props.onAllDirentSelected}
onItemSelected={this.props.onItemSelected}
/>
<FileUploader
ref={uploader => this.uploader = uploader}
dragAndDrop={true}
path={this.props.path}
repoID={repoID}
direntList={this.props.direntList}
onFileUploadSuccess={this.onFileUploadSuccess}
/>
</Fragment>
)}
</div>
</div>
{this.state.isDirentDetailShow && (
<div className="cur-view-detail">
<DirentDetail
repoID={repoID}
path={this.props.path}
dirent={this.state.currentDirent}
direntPath={this.state.direntPath}
onItemDetailsClose={this.onItemDetailsClose}
onFileTagChanged={this.onFileTagChanged}
/>
</div>
)}
</div>
</div>
);
}
}
MainPanel.propTypes = propTypes;
export default MainPanel;

File diff suppressed because it is too large Load Diff

View File

@@ -58,6 +58,7 @@ export const canAddPublicRepo = window.app.pageOptions.canAddPublicRepo;
export const canInvitePeople = window.app.pageOptions.canInvitePeople;
export const canLockUnlockFile = window.app.pageOptions.canLockUnlockFile;
export const customNavItems = window.app.pageOptions.customNavItems;
export const maxUploadFileSize = window.app.pageOptions.maxUploadFileSize;
export const curNoteMsg = window.app.pageOptions.curNoteMsg;
export const curNoteID = window.app.pageOptions.curNoteID;

View File

@@ -92,7 +92,7 @@ class Groups(APIView):
username = request.user.username
if is_org_context(request):
org_id = request.user.org.org_id
user_groups = seaserv.get_org_groups_by_user(org_id, username)
user_groups = seaserv.get_org_groups_by_user(org_id, username, return_ancestors=True)
else:
user_groups = ccnet_api.get_groups(username, return_ancestors=True)

View File

@@ -96,6 +96,9 @@
canAddPublicRepo: {% if can_add_public_repo %} true {% else %} false {% endif %},
canInvitePeople: {% if enable_guest_invitation and user.permissions.can_invite_guest %} true {% else %} false {% endif %},
customNavItems: {% if custom_nav_items %} JSON.parse('{{ custom_nav_items | escapejs }}') {% else %} {{'[]'}} {% endif %},
{% if max_upload_file_size > 0 %}
maxUploadFileSize: {{ max_upload_file_size }},
{% endif %}
{% if request.user.is_authenticated and request.cur_note %}
curNoteMsg: '{{ request.cur_note.message|urlize|escapejs }}',

View File

@@ -81,7 +81,6 @@ $('#signup-form').on('submit', function(){
var email = $.trim($('input[name="email"]').val()),
pwd1 = $.trim($('input[name="password1"]').val()),
pwd2 = $.trim($('input[name="password2"]').val());
level = getStrengthLevel(pwd1);
if (!email) {
$('.error').html("{% trans "Email cannot be blank" %}").removeClass('hide');
@@ -100,6 +99,7 @@ $('#signup-form').on('submit', function(){
return false;
}
{% if strong_pwd_required %}
var level = getStrengthLevel(pwd1);
if (level < {{level}}) {
$('.error').html(passwd_tip).removeClass('hide');
return false;

View File

@@ -1,22 +0,0 @@
{% extends "base_for_react.html" %}
{% load render_bundle from webpack_loader %}
{% block extra_style %}
{% render_bundle 'repoview' 'css' %}
{% endblock %}
{% block extra_script %}
<script type="text/javascript">
window.wiki = {
config: {
repoId: "{{ repo_id }}",
serviceUrl: "{{ service_url}}",
initial_path: "{{ initial_path|escapejs }}",
slug: "{{ repo_name }}",
isDir: "{{ is_dir }}",
permission: "{{ permission }}"
}
};
</script>
{% render_bundle 'repoview' 'js' %}
{% endblock %}

View File

@@ -1131,10 +1131,17 @@ def react_fake_view(request, **kwargs):
folder_perm_enabled = True if is_pro_version() and ENABLE_FOLDER_PERM else False
try:
max_upload_file_size = seafile_api.get_server_config_int('fileserver', 'max_upload_size')
except Exception as e:
logger.error(e)
max_upload_file_size = -1
return render(request, "react_app.html", {
"guide_enabled": guide_enabled,
'trash_repos_expire_days': expire_days if expire_days > 0 else 30,
'dtable_web_server': DTABLE_WEB_SERVER,
'max_upload_file_size': max_upload_file_size,
'seafile_collab_server': SEAFILE_COLLAB_SERVER,
'storages': get_library_storages(request),
'enable_repo_snapshot_label': settings.ENABLE_REPO_SNAPSHOT_LABEL,

View File

@@ -1,6 +1,7 @@
from django.conf import settings
from django.db import connection
from seaserv import ccnet_api
from seahub.auth.backends import RemoteUserBackend
from seahub.base.accounts import User
from registration.models import (
@@ -43,9 +44,12 @@ class ShibbolethRemoteUserBackend(RemoteUserBackend):
return
username = self.clean_username(remote_user)
try:
user = User.objects.get(email=username)
except User.DoesNotExist:
local_ccnet_users = ccnet_api.search_emailusers('DB', username, -1, -1)
if not local_ccnet_users:
local_ccnet_users = ccnet_api.search_emailusers('LDAP', username, -1, -1)
if not local_ccnet_users:
if self.create_unknown_user:
user = User.objects.create_user(
email=username, is_active=self.activate_after_creation)