Merge branch 'hotfix/v1.0.1' of github.com:ONLYOFFICE/AppServer into hotfix/campaigns-banner

This commit is contained in:
Viktor Fomin 2021-11-07 19:50:52 +03:00
commit 39be3b8619
61 changed files with 702 additions and 308 deletions

View File

@ -1,5 +1,5 @@
#!/bin/bash
PARAMETERS=${PARAMETERS:-""}
# read parameters
if [ -n "$1" ]; then
DOTNET_RUN="${1}";
@ -22,7 +22,6 @@ echo "#-------------------------------------#"
PRODUCT=${PRODUCT:-"onlyoffice"}
BASE_DIR="/app/${PRODUCT}"
PARAMETERS=""
PROXY_HOST=${PROXY_HOST:-"proxy"}
SHEME=${SHEME:-"http"}
SERVICE_PORT=${SERVICE_PORT:-"5050"}

View File

@ -49,7 +49,7 @@ namespace ASC.FederatedLogin.Helpers
ConsumerFactory = consumerFactory;
}
public string RequestCode<T>(string scope = null, Dictionary<string, string> additionalArgs = null) where T : Consumer, IOAuthProvider, new()
public string RequestCode<T>(string scope = null, IDictionary<string, string> additionalArgs = null, IDictionary<string, string> additionalStateArgs = null) where T : Consumer, IOAuthProvider, new()
{
var loginProvider = ConsumerFactory.Get<T>();
var requestUrl = loginProvider.CodeUrl;
@ -67,7 +67,20 @@ namespace ASC.FederatedLogin.Helpers
if (!string.IsNullOrEmpty(scope)) query += $"&scope={HttpUtility.UrlEncode(scope)}";
var u = HttpContextAccessor.HttpContext.Request.GetUrlRewriter();
var state = HttpUtility.UrlEncode(new UriBuilder(u.Scheme, u.Host, u.Port, $"thirdparty/{loginProvider.Name.ToLower()}/code").Uri.AbsoluteUri);
var stateUriBuilder = new UriBuilder(u.Scheme, u.Host, u.Port, $"thirdparty/{loginProvider.Name.ToLower()}/code");
if (additionalStateArgs != null && additionalStateArgs.Any())
{
var stateQuery = "";
stateQuery = additionalStateArgs.Keys
.Where(a => a != null)
.Aggregate(stateQuery, (current, a) => a != null ? $"{current}&{a.Trim()}={additionalStateArgs[a] ?? "".Trim()}" : null);
stateUriBuilder.Query = stateQuery.Substring(1);
}
var state = HttpUtility.UrlEncode(stateUriBuilder.Uri.AbsoluteUri);
query += $"&state={state}";
if (additionalArgs != null)

View File

@ -26,6 +26,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading;
@ -104,10 +105,22 @@ namespace ASC.FederatedLogin
{
try
{
var profile = ProviderManager.Process(Auth, context, _params);
var desktop = _params.ContainsKey("desktop") && _params["desktop"] == "true";
IDictionary<string, string> additionalStateArgs = null;
if (desktop)
{
additionalStateArgs = context.Request.Query.ToDictionary(r => r.Key, r => r.Value.FirstOrDefault());
if (!additionalStateArgs.ContainsKey("desktop"))
{
additionalStateArgs.Add("desktop", "true");
}
}
var profile = ProviderManager.Process(Auth, context, null, additionalStateArgs);
if (profile != null)
{
await SendClientData(context, profile);
await SendJsCallback(context, profile);
}
}
catch (ThreadAbortException)
@ -116,7 +129,7 @@ namespace ASC.FederatedLogin
}
catch (Exception ex)
{
await SendClientData(context, LoginProfile.FromError(Signature, InstanceCrypto, ex));
await SendJsCallback(context, LoginProfile.FromError(Signature, InstanceCrypto, ex));
}
}
else
@ -179,48 +192,16 @@ namespace ASC.FederatedLogin
get { return false; }
}
private async Task SendClientData(HttpContext context, LoginProfile profile)
{
switch (Mode)
{
case LoginMode.Redirect:
await RedirectToReturnUrl(context, profile);
break;
case LoginMode.Popup:
await SendJsCallback(context, profile);
break;
}
}
private async Task SendJsCallback(HttpContext context, LoginProfile profile)
{
//Render a page
context.Response.ContentType = "text/html";
await context.Response.WriteAsync(JsCallbackHelper.GetCallbackPage().Replace("%PROFILE%", profile.ToJson()).Replace("%CALLBACK%", Callback));
}
private async Task RedirectToReturnUrl(HttpContext context, LoginProfile profile)
{
var useMinimalProfile = Minimal;
if (useMinimalProfile)
profile = profile.GetMinimalProfile(); //Only id and provider
if (context.Session != null && !useMinimalProfile)
{
//Store in session
context.Response.Redirect(new Uri(ReturnUrl, UriKind.Absolute).AddProfileSession(profile, context).ToString(), true);
}
else if (MemoryCache != null && !useMinimalProfile)
{
context.Response.Redirect(new Uri(ReturnUrl, UriKind.Absolute).AddProfileCache(profile, MemoryCache).ToString(), true);
}
else
{
context.Response.Redirect(new Uri(ReturnUrl, UriKind.Absolute).AddProfile(profile).ToString(), true);
}
await context.Response.CompleteAsync();
return;
await context.Response.WriteAsync(
JsCallbackHelper.GetCallbackPage()
.Replace("%PROFILE%", $"\"{profile.Serialized}\"")
.Replace("%CALLBACK%", Callback)
.Replace("%DESKTOP%", (Mode == LoginMode.Redirect).ToString().ToLowerInvariant())
);
}
}

View File

@ -113,11 +113,11 @@ namespace ASC.FederatedLogin.LoginProviders
InstanceCrypto = instanceCrypto;
}
public virtual LoginProfile ProcessAuthoriztion(HttpContext context, IDictionary<string, string> @params)
public virtual LoginProfile ProcessAuthoriztion(HttpContext context, IDictionary<string, string> @params, IDictionary<string, string> additionalStateArgs = null)
{
try
{
var token = Auth(context, Scopes, out var redirect);
var token = Auth(context, Scopes, out var redirect, @params, additionalStateArgs);
if (redirect)
{
@ -136,7 +136,7 @@ namespace ASC.FederatedLogin.LoginProviders
}
}
protected virtual OAuth20Token Auth(HttpContext context, string scopes, out bool redirect, Dictionary<string, string> additionalArgs = null)
protected virtual OAuth20Token Auth(HttpContext context, string scopes, out bool redirect, IDictionary<string, string> additionalArgs = null, IDictionary<string, string> additionalStateArgs = null)
{
var error = context.Request.Query["error"];
if (!string.IsNullOrEmpty(error))
@ -151,7 +151,7 @@ namespace ASC.FederatedLogin.LoginProviders
var code = context.Request.Query["code"];
if (string.IsNullOrEmpty(code))
{
context.Response.Redirect(OAuth20TokenHelper.RequestCode<T>(scopes, additionalArgs));
context.Response.Redirect(OAuth20TokenHelper.RequestCode<T>(scopes, additionalArgs, additionalStateArgs));
redirect = true;
return null;
}

View File

@ -114,7 +114,7 @@ namespace ASC.FederatedLogin.LoginProviders
}
public override LoginProfile ProcessAuthoriztion(HttpContext context, IDictionary<string, string> @params)
public override LoginProfile ProcessAuthoriztion(HttpContext context, IDictionary<string, string> @params, IDictionary<string, string> additionalStateArgs = null)
{
try
{
@ -142,7 +142,7 @@ namespace ASC.FederatedLogin.LoginProviders
}
}
protected override OAuth20Token Auth(HttpContext context, string scopes, out bool redirect, Dictionary<string, string> additionalArgs = null)
protected override OAuth20Token Auth(HttpContext context, string scopes, out bool redirect, IDictionary<string, string> additionalArgs = null, IDictionary<string, string> additionalStateArgs = null)
{
var error = context.Request.Query["error"];
if (!string.IsNullOrEmpty(error))

View File

@ -34,7 +34,7 @@ namespace ASC.FederatedLogin.LoginProviders
{
public interface ILoginProvider : IOAuthProvider
{
LoginProfile ProcessAuthoriztion(HttpContext context, IDictionary<string, string> @params);
LoginProfile ProcessAuthoriztion(HttpContext context, IDictionary<string, string> @params, IDictionary<string, string> additionalStateArgs);
LoginProfile GetLoginProfile(string accessToken);
}

View File

@ -97,7 +97,7 @@ namespace ASC.FederatedLogin.LoginProviders
{
}
public override LoginProfile ProcessAuthoriztion(HttpContext context, IDictionary<string, string> @params)
public override LoginProfile ProcessAuthoriztion(HttpContext context, IDictionary<string, string> @params, IDictionary<string, string> additionalStateArgs = null)
{
try
{

View File

@ -53,7 +53,7 @@ namespace ASC.FederatedLogin.LoginProviders
ConsumerFactory = consumerFactory;
}
public LoginProfile ProcessAuthoriztion(HttpContext context, IDictionary<string, string> @params)
public LoginProfile ProcessAuthoriztion(HttpContext context, IDictionary<string, string> @params, IDictionary<string, string> additionalStateArgs = null)
{
var response = Openid.GetResponse();
if (response == null)

View File

@ -71,9 +71,9 @@ namespace ASC.FederatedLogin.LoginProviders
: ConsumerFactory.GetByKey(providerType) as ILoginProvider;
}
public LoginProfile Process(string providerType, HttpContext context, IDictionary<string, string> @params)
public LoginProfile Process(string providerType, HttpContext context, IDictionary<string, string> @params, IDictionary<string, string> additionalStateArgs = null)
{
return GetLoginProvider(providerType).ProcessAuthoriztion(context, @params);
return GetLoginProvider(providerType).ProcessAuthoriztion(context, @params, additionalStateArgs);
}
public LoginProfile GetLoginProfile(string providerType, string accessToken)

View File

@ -102,7 +102,7 @@ namespace ASC.FederatedLogin.LoginProviders
}
public override LoginProfile ProcessAuthoriztion(HttpContext context, IDictionary<string, string> @params)
public override LoginProfile ProcessAuthoriztion(HttpContext context, IDictionary<string, string> @params, IDictionary<string, string> additionalStateArgs = null)
{
try
{
@ -111,7 +111,7 @@ namespace ASC.FederatedLogin.LoginProviders
{
{ "revoke", "1" }
}
: null);
: null, additionalStateArgs);
if (redirect)
{

View File

@ -94,7 +94,7 @@ namespace ASC.FederatedLogin.LoginProviders
{
}
public override LoginProfile ProcessAuthoriztion(HttpContext context, IDictionary<string, string> @params)
public override LoginProfile ProcessAuthoriztion(HttpContext context, IDictionary<string, string> @params, IDictionary<string, string> additionalStateArgs = null)
{
try
{
@ -103,7 +103,7 @@ namespace ASC.FederatedLogin.LoginProviders
{
{ "force_confirm", "true" }
}
: null);
: null, additionalStateArgs);
if (redirect)
{
return null;

View File

@ -2,12 +2,17 @@
<html>
<head>
<script language="javascript" type="text/javascript">
try {
window.opener.%CALLBACK%(%PROFILE%);
if (%DESKTOP%) {
localStorage.setItem("profile", %PROFILE%);
window.location.href = "/";
} else {
try {
window.opener.%CALLBACK%(%PROFILE%);
}
catch (ex) {
}
window.close();
}
catch (ex) {
}
window.close();
</script>
</head>
<body></body>

View File

@ -1,5 +1,5 @@
{
"version": "1.0.0",
"version": "1.0.1",
"npmClient": "yarn",
"packages": [
"packages/asc-web-components",

View File

@ -518,6 +518,7 @@ class MediaViewer extends React.Component {
color="#fff"
iconName="/static/images/cross.react.svg"
size={25}
isClickable
/>
</ControlBtn>
</div>

View File

@ -36,9 +36,16 @@ const StyledMediaViewer = styled.div`
.deleteBtnContainer,
.downloadBtnContainer {
display: block;
width: 20px;
margin: 3px 10px;
width: 16px;
height: 16px;
margin: 4px 12px;
line-height: 19px;
svg {
path {
fill: #fff;
}
}
}
.details {
z-index: 302;

View File

@ -95,7 +95,7 @@ const StyledViewer = styled(Viewer)`
@media (max-width: 600px) {
position: initial;
}
bottom: 10px;
bottom: 9px;
.controlBtn {
margin: 0;
}
@ -107,20 +107,32 @@ const StyledViewer = styled(Viewer)`
right: 12px;
}
.iconContainer {
width: 20px;
width: 16px;
height: 16px;
line-height: 20px;
margin: 4px auto;
margin: 3px auto;
&.reset {
width: 18px;
}
path,
rect {
fill: #fff;
}
}
.btnContainer {
display: block;
width: 18px;
margin: 4px 10px;
width: 16px;
height: 16px;
margin: 4px 12px;
line-height: 19px;
path,
rect {
fill: #fff;
}
}
.scrollBtn {
cursor: ${(props) => (props.inactive ? "default" : "pointer")};

View File

@ -1,6 +1,6 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import styled from "styled-components";
import styled, { css } from "styled-components";
import { findDOMNode } from "react-dom";
import screenfull from "screenfull";
import ReactPlayer from "react-player";
@ -9,11 +9,19 @@ import Duration from "./duration";
import Progress from "./progress";
import MediaPauseIcon from "../../../../../public/images/media.pause.react.svg";
import MediaPlayIcon from "../../../../../public/images/media.play.react.svg";
import MediaFullScreenIcon from "../../../../../public/images/media.fullscreen.react.svg";
import MediaFullScreenIcon from "../../../../../public/images/media.fullscreen.video.react.svg";
import MediaMuteIcon from "../../../../../public/images/media.mute.react.svg";
import MediaMuteOffIcon from "../../../../../public/images/media.muteoff.react.svg";
import commonIconsStyles from "@appserver/components/utils/common-icons-style";
const iconsStyles = css`
path,
stroke,
rect {
fill: #fff;
}
`;
const controlsHeight = 40;
const StyledControls = styled.div`
height: ${(props) => props.height}px;
@ -26,10 +34,10 @@ const StyledControls = styled.div`
`;
const StyledVideoControlBtn = styled.div`
display: inline-block;
height: 30px;
height: 26px;
line-height: 30px;
margin: 5px;
width: 40px;
margin: 5px 2px;
width: 38px;
border-radius: 2px;
cursor: pointer;
text-align: center;
@ -39,43 +47,62 @@ const StyledVideoControlBtn = styled.div`
}
.playBtnContainer {
width: 23px;
width: 16px;
height: 16px;
line-height: 0;
margin: 3px auto;
margin: 5px auto;
}
.pauseBtnContainer {
display: block;
width: 19px;
width: 16px;
height: 16px;
margin: 3px 10px;
line-height: 19px;
}
.muteBtnContainer {
display: block;
width: 26px;
margin: 3px 7px;
width: 16px;
height: 16px;
margin: 3px 11px;
line-height: 19px;
}
.fullscreenBtnContainer {
display: block;
width: 20px;
margin: 3px 10px;
width: 16px;
height: 16px;
margin: 3px 11px;
line-height: 19px;
}
`;
const StyledMediaPauseIcon = styled(MediaPauseIcon)`
${commonIconsStyles}
${iconsStyles}
`;
const StyledMediaPlayIcon = styled(MediaPlayIcon)`
${commonIconsStyles}
${iconsStyles}
`;
const StyledMediaFullScreenIcon = styled(MediaFullScreenIcon)`
${commonIconsStyles}
${iconsStyles}
`;
const StyledMediaMuteIcon = styled(MediaMuteIcon)`
${commonIconsStyles}
path:first-child {
stroke: #fff;
}
path:last-child {
fill: #fff;
}
`;
const StyledMediaMuteOffIcon = styled(MediaMuteOffIcon)`
${commonIconsStyles}
path, rect {
fill: #fff;
}
`;
const VideoControlBtn = (props) => {
return (
@ -152,8 +179,8 @@ const StyledValumeContainer = styled.div`
`;
const StyledDuration = styled.div`
display: inline-block;
height: 30px;
line-height: 30px;
height: 26px;
line-height: 26px;
margin: 5px;
width: 60px;
text-align: center;

View File

@ -9,8 +9,8 @@ import { isMobile } from "react-device-detect";
const StyledArticleBody = styled.div`
${(props) => props.displayBorder && `outline: 1px dotted;`}
flex-grow: 1;
height: 100%;
${(props) => (props.isDesktop ? "height:auto" : "height:100%")};
.custom-scrollbar {
width: calc(100% + 24px) !important;
}

View File

@ -10,16 +10,32 @@ import Scrollbar from "@appserver/components/scrollbar";
import DragAndDrop from "@appserver/components/drag-and-drop";
import { tablet, desktop } from "@appserver/components/utils/device";
const paddingStyles = css`
padding: 17px 7px 16px 24px;
@media ${tablet} {
padding: 16px 0 16px 24px;
}
`;
const commonStyles = css`
flex-grow: 1;
height: 100%;
${(props) => (props.isDesktop ? "height: auto" : "height: 100%")};
border-left: none;
-webkit-user-select: none;
.section-wrapper {
${(props) =>
!props.withScroll &&
`display: flex; height: 100%; box-sizing:border-box`};
${(props) => !props.withScroll && paddingStyles}
}
.section-wrapper-content {
${paddingStyles}
flex: 1 0 auto;
padding: 17px 7px 16px 24px;
outline: none;
${(props) =>
props.viewAs == "tile" &&
@ -28,8 +44,10 @@ const commonStyles = css`
padding-left: 20px;
`}
@media ${tablet} {
padding: 16px 0 16px 24px;
.section-wrapper {
display: flex;
flex-direction: column;
min-height: 100%;
}
.section-wrapper {
@ -56,7 +74,16 @@ const StyledSectionBody = styled.div`
props.withScroll &&
`
margin-left: -24px;
`}
`}
.additional-scroll-height {
${(props) =>
!props.withScroll &&
!props.pinned &&
` height: 64px;
`}
}
`;
const StyledDropZoneBody = styled(DragAndDrop)`
@ -95,8 +122,9 @@ class SectionBody extends React.Component {
// }
componentDidMount() {
const { withScroll } = this.props;
if (!this.props.autoFocus) return;
this.focusRef.current.focus();
if (withScroll) this.focusRef.current.focus();
}
componentWillUnmount() {
@ -114,6 +142,7 @@ class SectionBody extends React.Component {
viewAs,
withScroll,
isLoaded,
isDesktop,
} = this.props;
const focusProps = autoFocus
@ -131,6 +160,7 @@ class SectionBody extends React.Component {
viewAs={viewAs}
pinned={pinned}
isLoaded={isLoaded}
isDesktop={isDesktop}
className="section-body"
>
{withScroll ? (
@ -164,6 +194,7 @@ class SectionBody extends React.Component {
withScroll={withScroll}
pinned={pinned}
isLoaded={isLoaded}
isDesktop={isDesktop}
>
{withScroll ? (
!isMobile ? (
@ -184,10 +215,7 @@ class SectionBody extends React.Component {
</div>
)
) : (
<div className="section-wrapper">
{children}
<StyledSpacer pinned={pinned} />
</div>
<div className="section-wrapper">{children}</div>
)}
</StyledSectionBody>
);
@ -219,7 +247,10 @@ SectionBody.defaultProps = {
};
export default inject(({ auth }) => {
const { settingsStore } = auth;
const { isDesktopClient: isDesktop } = settingsStore;
return {
isLoaded: auth.isLoaded,
isDesktop,
};
})(observer(SectionBody));

View File

@ -1,6 +1,6 @@
{
"name": "@appserver/common",
"version": "1.0.0",
"version": "1.0.1",
"private": true,
"scripts": {
"build": "echo 'skip it'",

View File

@ -192,9 +192,11 @@ class AuthStore {
setWithCredentialsStatus(true);
this.reset();
this.init();
return Promise.resolve(true);
return Promise.resolve(this.settingsStore.defaultPage);
} catch (e) {
return Promise.reject(e);
}

View File

@ -5,6 +5,7 @@ import NoUserSelect from "../utils/commonStyles";
const EmptyContentBody = styled.div`
margin: 0 auto;
padding: 64px 0;
grid-template-columns: 150px 1fr;
display: grid;
grid-template-areas:

View File

@ -1,6 +1,6 @@
{
"name": "@appserver/components",
"version": "1.0.0",
"version": "1.0.1",
"private": true,
"scripts": {
"build": "echo 'skip it'",

View File

@ -32,6 +32,7 @@ export class CustomScrollbars extends React.Component {
className={className}
>
{children}
<div className="additional-scroll-height"></div>
</Scrollbar>
);
}

View File

@ -1,6 +1,6 @@
{
"name": "@appserver/browserslist-config-asc",
"version": "1.0.0",
"version": "1.0.1",
"description": "Shared browserslist for AppServer libraries and apps",
"main": "browserlist.config.js",
"scripts": {

View File

@ -1,6 +1,6 @@
{
"name": "@appserver/debug-info",
"version": "1.0.0",
"version": "1.0.1",
"private": true,
"description": "Command line tool for generating debug info by commit history",
"main": "src/index.js",

View File

@ -1,6 +1,6 @@
{
"name": "@appserver/crm",
"version": "1.0.0",
"version": "1.0.1",
"private": true,
"homepage": "/products/crm",
"scripts": {

View File

@ -1,6 +1,6 @@
{
"name": "@appserver/calendar",
"version": "1.0.0",
"version": "1.0.1",
"private": true,
"homepage": "/products/calendar",
"scripts": {

View File

@ -1,6 +1,6 @@
{
"name": "@appserver/files",
"version": "1.0.0",
"version": "1.0.1",
"private": true,
"homepage": "/products/files",
"scripts": {

View File

@ -55,6 +55,7 @@ class SharingPanelComponent extends React.Component {
accessOptions: [],
filesOwnerId: null,
showEmbeddingContent: false,
isLoading: false,
};
this.ref = React.createRef();
@ -92,27 +93,8 @@ class SharingPanelComponent extends React.Component {
};
onSaveClick = () => {
const {
baseShareData,
isNotifyUsers,
message,
shareDataItems,
filesOwnerId,
} = this.state;
const {
selection,
setIsLoading,
isPrivacy,
replaceFileStream,
t,
uploadPanelVisible,
updateUploadedItem,
uploadSelection,
isDesktop,
setEncryptionAccess,
setShareFiles,
onSuccess,
} = this.props;
const { baseShareData, shareDataItems, filesOwnerId } = this.state;
const { selection } = this.props;
let folderIds = [];
let fileIds = [];
@ -163,8 +145,28 @@ class SharingPanelComponent extends React.Component {
const ownerId =
filesOwnerId !== owner.sharedTo.id ? owner.sharedTo.id : null;
setIsLoading(true);
this.setShareInfo(folderIds, fileIds, share, externalAccess, ownerId);
};
setShareInfo = (folderIds, fileIds, share, externalAccess, ownerId) => {
const { isNotifyUsers, message } = this.state;
const {
selection,
isPrivacy,
replaceFileStream,
t,
uploadPanelVisible,
updateUploadedItem,
uploadSelection,
isDesktop,
setEncryptionAccess,
setShareFiles,
onSuccess,
} = this.props;
this.onClose();
setShareFiles(
folderIds,
fileIds,
@ -210,9 +212,9 @@ class SharingPanelComponent extends React.Component {
return Promise.resolve();
})
.then(() => onSuccess && onSuccess())
.catch((err) => toastr.error(err))
.finally(() => setIsLoading(false));
.catch((err) => toastr.error(err));
};
onNotifyUsersChange = () =>
this.setState({ isNotifyUsers: !this.state.isNotifyUsers });
@ -264,47 +266,60 @@ class SharingPanelComponent extends React.Component {
};
getShareData = () => {
const {
getAccessOption,
getExternalAccessOption,
selection,
setIsLoading,
getShareUsers,
} = this.props;
const returnValue = this.getData();
const folderId = returnValue[0];
const fileId = returnValue[1];
if (folderId.length !== 0 || fileId.length !== 0) {
!isMobile && setIsLoading(true);
getShareUsers(folderId, fileId)
.then((shareDataItems) => {
const baseShareData = JSON.parse(JSON.stringify(shareDataItems));
const accessOptions = getAccessOption(selection);
const externalAccessOptions = getExternalAccessOption(selection);
const filesOwner = shareDataItems.find((x) => x.isOwner);
const filesOwnerId = filesOwner ? filesOwner.sharedTo.id : null;
this.setState({
baseShareData,
shareDataItems,
accessOptions,
externalAccessOptions,
//showPanel: true,
filesOwnerId,
});
})
.catch((err) => {
toastr.error(err);
this.onClose();
})
.finally(() => !isMobile && setIsLoading(false));
this.setState(
{
isLoading: true,
},
function () {
this.getShareUsers(folderId, fileId);
}
);
}
};
getShareUsers = (folderId, fileId) => {
const {
getAccessOption,
getExternalAccessOption,
selection,
getShareUsers,
} = this.props;
getShareUsers(folderId, fileId)
.then((shareDataItems) => {
const baseShareData = JSON.parse(JSON.stringify(shareDataItems));
const accessOptions = getAccessOption(selection);
const externalAccessOptions = getExternalAccessOption(selection);
const filesOwner = shareDataItems.find((x) => x.isOwner);
const filesOwnerId = filesOwner ? filesOwner.sharedTo.id : null;
this.setState({
baseShareData,
shareDataItems,
accessOptions,
externalAccessOptions,
//showPanel: true,
filesOwnerId,
});
})
.catch((err) => {
toastr.error(err);
this.onClose();
})
.finally(() =>
this.setState({
isLoading: false,
})
);
};
getInternalLink = () => {
const { homepage, selection } = this.props;
@ -414,7 +429,6 @@ class SharingPanelComponent extends React.Component {
selection,
groupsCaption,
canShareOwnerChange,
isLoading,
uploadPanelVisible,
documentTitle,
sharingPanelVisible,
@ -434,6 +448,7 @@ class SharingPanelComponent extends React.Component {
accessOptions,
externalAccessOptions,
showEmbeddingContent,
isLoading,
} = this.state;
const visible = sharingPanelVisible;
@ -707,10 +722,8 @@ const SharingPanel = inject(
setFolder,
getShareUsers,
setShareFiles,
setIsLoading,
getFileInfo,
getFolderInfo,
isLoading,
setBufferSelection,
} = filesStore;
const { isPrivacyFolder } = treeFoldersStore;
@ -732,12 +745,10 @@ const SharingPanel = inject(
: selection.length
? selection
: [bufferSelection],
isLoading,
isPrivacy: isPrivacyFolder,
selectedUploadFile,
canShareOwnerChange,
setIsLoading,
setSharingPanelVisible,
sharingPanelVisible,
selectUploadedFile,

View File

@ -108,10 +108,14 @@ const StyledVersionHistoryPanel = styled.div`
}
}
.version-history-panel-body {
padding: ${(props) => (props.isLoading ? "16px 0" : null)};
margin: 0 16px;
padding-top: ${(props) => (props.isLoading ? "16px" : null)};
padding-bottom: ${(props) => (props.isLoading ? "0px" : null)};
margin-left: 16px;
border-top: 1px solid #eceef1;
height: calc(100% - 53px);
box-sizing: border-box;
.version-comment-wrapper {
margin-left: 79px;
}
@ -170,6 +174,7 @@ const StyledContent = styled.div`
box-sizing: border-box;
position: relative;
width: 100%;
height: 100%;
background-color: #fff;
.header_aside-panel-header {

View File

@ -51,7 +51,7 @@ class PureVersionHistoryPanel extends React.Component {
zIndex={zIndex}
isAside={true}
/>
<Aside className="version-history-aside-panel">
<Aside className="version-history-aside-panel" withoutBodyScroll>
<StyledContent>
<StyledHeaderContent className="version-history-panel-header">
{versions && !isLoading ? (

View File

@ -1,19 +1,124 @@
import styled, { css } from "styled-components";
import styled from "styled-components";
import Row from "@appserver/components/row";
import { tablet } from "@appserver/components/utils/device";
const StyledVersionRow = styled(Row)`
min-height: 70px;
const StyledBody = styled.div`
height: 100%;
width: 100%;
.version-list {
height: 100%;
width: 100%;
}
.loader-history-rows {
padding-right: 16px;
}
`;
const StyledVersionList = styled.div`
.row_context-menu-wrapper {
.expandButton {
${(props) =>
props.isRestoreProcess &&
`
touch-action: none;
pointer-events: none;
`}
svg {
path {
${(props) =>
props.isRestoreProcess &&
`
fill: #d0d5da;
`};
}
}
}
}
.row_content {
.version_link,
.version-link-file,
.version_content-length,
.version_link-action,
.row_context-menu-wrapper,
.version_text {
${(props) =>
props.isRestoreProcess &&
`
color: #d0d5da;
touch-action: none;
pointer-events: none;
`}
}
.versioned, .not-versioned {
${(props) =>
props.isRestoreProcess &&
`
touch-action: none;
pointer-events: none;
`}
}
.versioned {
svg {
path {
${(props) =>
props.isRestoreProcess &&
`
fill: #d0d5da;
`};
}
}
}
.not-versioned{
svg {
path {
${(props) =>
props.isRestoreProcess &&
`
stroke: #d0d5da;
`};
}
}
}
}
.icon-link {
${(props) =>
props.isRestoreProcess &&
`
touch-action: none;
pointer-events: none;
`}
svg {
path {
${(props) => props.isRestoreProcess && " fill: #d0d5da"}
}
}
}
}
`;
const StyledVersionRow = styled(Row)`
@media ${tablet} {
min-height: 69px;
box-sizing: border-box;
position: relative;
}
.row_content {
position: relative;
padding-top: 14px;
padding-bottom: 14px;
padding-top: 12px;
padding-bottom: 12px;
${(props) => props.isTabletView && "height: auto"};
${(props) => !props.isTabletView && "padding-right:16px"};
}
.version_badge {
@ -133,6 +238,26 @@ const StyledVersionRow = styled(Row)`
.row_context-menu-wrapper {
display: none;
right: 16px !important;
.expandButton {
${(props) =>
props.isSavingComment &&
`
touch-action: none;
pointer-events: none;
`}
svg {
path {
${(props) =>
props.isSavingComment &&
`
fill: #d0d5da;
`};
}
}
}
@media ${tablet} {
display: block;
position: absolute;
@ -143,6 +268,16 @@ const StyledVersionRow = styled(Row)`
.row_content {
display: block;
.version_link-action {
${(props) =>
props.isSavingComment &&
`
color: #d0d5da;
touch-action: none;
pointer-events: none;
`}
}
}
.modal-dialog-aside-footer {
@ -168,4 +303,4 @@ const StyledVersionRow = styled(Row)`
}
`;
export default StyledVersionRow;
export { StyledBody, StyledVersionRow, StyledVersionList };

View File

@ -1,4 +1,4 @@
import React, { useState } from "react";
import React, { useState, useEffect } from "react";
import styled from "styled-components";
import Link from "@appserver/components/link";
import Text from "@appserver/components/text";
@ -9,7 +9,7 @@ import ModalDialog from "@appserver/components/modal-dialog";
import { withTranslation } from "react-i18next";
import { withRouter } from "react-router";
import VersionBadge from "./VersionBadge";
import StyledVersionRow from "./StyledVersionRow";
import { StyledVersionRow } from "./StyledVersionHistory";
import ExternalLinkIcon from "../../../../../public/images/external.link.react.svg";
import commonIconsStyles from "@appserver/components/utils/common-icons-style";
import { inject, observer } from "mobx-react";
@ -31,11 +31,14 @@ const VersionRow = (props) => {
markAsVersion,
restoreVersion,
updateCommentVersion,
onSetRestoreProcess,
isTabletView,
onUpdateHeight,
versionsListLength,
} = props;
const [showEditPanel, setShowEditPanel] = useState(false);
const [commentValue, setCommentValue] = useState(info.comment);
const [isRestoring, setIsRestoring] = useState(false);
const [isSavingComment, setIsSavingComment] = useState(false);
const canEdit = info.access === 1 || info.access === 0;
@ -52,10 +55,12 @@ const VersionRow = (props) => {
const onChange = (e) => setCommentValue(e.target.value);
const onSaveClick = () => {
setIsSavingComment(true);
updateCommentVersion(info.id, commentValue, info.version)
.catch((err) => toastr.error(err))
.finally(() => {
onEditComment();
setIsSavingComment(false);
});
};
@ -66,11 +71,12 @@ const VersionRow = (props) => {
const onOpenFile = () => window.open(info.webUrl);
const onRestoreClick = () => {
setIsRestoring(true);
onSetRestoreProcess(true);
restoreVersion(info.id, info.version)
.catch((err) => toastr.error(err))
.finally(() => setIsRestoring(false));
.finally(() => {
onSetRestoreProcess(false);
});
};
const onVersionClick = () => {
@ -94,17 +100,29 @@ const VersionRow = (props) => {
];
const onClickProp = canEdit ? { onClick: onVersionClick } : {};
useEffect(() => {
const newRowHeight = document.getElementsByClassName(
`version-row_${index}`
)[0]?.clientHeight;
newRowHeight && onUpdateHeight(index, newRowHeight);
}, [showEditPanel, versionsListLength]);
return (
<StyledVersionRow
showEditPanel={showEditPanel}
contextOptions={contextOptions}
canEdit={canEdit}
isRestoring={isRestoring}
isTabletView={isTabletView}
isSavingComment={isSavingComment}
>
<>
<div className={`version-row_${index}`}>
<Box displayProp="flex">
<VersionBadge
className="version_badge"
className={`version_badge ${
isVersion ? "versioned" : "not-versioned"
}`}
isVersion={isVersion}
index={index}
versionGroup={info.versionGroup}
@ -147,6 +165,7 @@ const VersionRow = (props) => {
fontSize={12}
heightTextArea={54}
value={commentValue}
isDisabled={isSavingComment}
/>
<Box className="version_modal-dialog">
<ModalDialog
@ -165,10 +184,12 @@ const VersionRow = (props) => {
onChange={onChange}
heightTextArea={298}
value={commentValue}
isDisabled={isSavingComment}
/>
</ModalDialog.Body>
<ModalDialog.Footer>
<Button
isDisabled={isSavingComment}
className="version_save-button"
label={t("Common:SaveButton")}
size="big"
@ -195,7 +216,7 @@ const VersionRow = (props) => {
<div className="version_links-container">
{canEdit && (
<Link
{...(!isRestoring && { onClick: onRestoreClick })}
onClick={onRestoreClick}
{...linkStyles}
className="version_link-action"
>
@ -218,6 +239,7 @@ const VersionRow = (props) => {
displayProp="inline-block"
>
<Button
isDisabled={isSavingComment}
size="base"
scale={true}
primary
@ -230,6 +252,7 @@ const VersionRow = (props) => {
displayProp="inline-block"
>
<Button
isDisabled={isSavingComment}
size="base"
scale={true}
onClick={onCancelClick}
@ -238,14 +261,14 @@ const VersionRow = (props) => {
</Box>
</Box>
)}
</>
</div>
</StyledVersionRow>
);
};
export default inject(({ auth, versionHistoryStore }) => {
const { user } = auth.userStore;
const { culture } = auth.settingsStore;
const { culture, isTabletView } = auth.settingsStore;
const language = (user && user.cultureName) || culture || "en-US";
const {
@ -256,7 +279,7 @@ export default inject(({ auth, versionHistoryStore }) => {
return {
culture: language,
isTabletView,
markAsVersion,
restoreVersion,
updateCommentVersion,

View File

@ -1,13 +1,26 @@
import React from "react";
import React, { memo } from "react";
import { withRouter } from "react-router";
import RowContainer from "@appserver/components/row-container";
import Loaders from "@appserver/common/components/Loaders";
import VersionRow from "./VersionRow";
import { inject, observer } from "mobx-react";
import { VariableSizeList as List, areEqual } from "react-window";
import AutoSizer from "react-virtualized-auto-sizer";
import CustomScrollbarsVirtualList from "@appserver/components/scrollbar/custom-scrollbars-virtual-list";
import { StyledBody, StyledVersionList } from "./StyledVersionHistory";
class SectionBodyContent extends React.Component {
constructor(props) {
super(props);
this.state = {
isRestoreProcess: false,
rowSizes: {},
};
this.listKey = 0;
this.listRef = React.createRef();
this.timerId = null;
}
componentDidMount() {
const { match, setFirstLoad } = this.props;
const { match, setFirstLoad, versions } = this.props;
const fileId = match.params.fileId || this.props.fileId;
if (fileId && fileId !== this.props.fileId) {
@ -21,36 +34,104 @@ class SectionBodyContent extends React.Component {
setIsLoading(true);
fetchFileVersions(fileId).then(() => setIsLoading(false));
};
onSetRestoreProcess = (restoring) => {
const { isRestoreProcess } = this.state;
if (restoring) {
this.timerId = setTimeout(
() =>
this.setState({
isRestoreProcess: restoring,
}),
100
);
} else {
clearTimeout(this.timerId);
this.timerId = null;
restoring !== isRestoreProcess &&
this.setState({
isRestoreProcess: restoring,
});
}
};
onUpdateHeight = (i, itemHeight) => {
if (this.listRef.current) {
this.listRef.current.resetAfterIndex(i);
}
this.setState((prevState) => ({
rowSizes: {
...prevState.rowSizes,
[i]: itemHeight + 24, //composed of itemHeight = clientHeight of div and padding-top = 12px and padding-bottom = 12px
},
}));
};
getSize = (i) => {
return this.state.rowSizes[i] ? this.state.rowSizes[i] : 66;
};
renderRow = memo(({ index, style }) => {
const { versions, culture } = this.props;
const prevVersion = versions[index > 0 ? index - 1 : index].versionGroup;
let isVersion = true;
if (index > 0 && prevVersion === versions[index].versionGroup) {
isVersion = false;
}
return (
<div style={style}>
<VersionRow
getFileVersions={this.getFileVersions}
isVersion={isVersion}
key={`${versions[index].id}-${index}`}
info={versions[index]}
versionsListLength={versions.length}
index={index}
culture={culture}
onSetRestoreProcess={this.onSetRestoreProcess}
onUpdateHeight={this.onUpdateHeight}
/>
</div>
);
}, areEqual);
render() {
const { versions, culture, isLoading } = this.props;
//console.log("VersionHistory SectionBodyContent render()", versions);
const { versions, isLoading } = this.props;
let itemVersion = null;
const renderList = ({ height, width }) => {
return (
<StyledVersionList isRestoreProcess={this.state.isRestoreProcess}>
<List
ref={this.listRef}
className="List"
height={height}
width={width}
itemSize={this.getSize}
itemCount={versions.length}
itemData={versions}
outerElementType={CustomScrollbarsVirtualList}
>
{this.renderRow}
</List>
</StyledVersionList>
);
};
return versions && !isLoading ? (
<RowContainer useReactWindow={false}>
{versions.map((info, index) => {
let isVersion = true;
if (itemVersion === info.versionGroup) {
isVersion = false;
} else {
itemVersion = info.versionGroup;
}
return (
<VersionRow
getFileVersions={this.getFileVersions}
isVersion={isVersion}
key={`${info.id}-${index}`}
info={info}
index={index}
culture={culture}
/>
);
})}
</RowContainer>
) : (
<Loaders.HistoryRows title="version-history-body-loader" />
return (
<StyledBody>
{versions && !isLoading ? (
<div className="version-list">
<AutoSizer>{renderList}</AutoSizer>
</div>
) : (
<div className="loader-history-rows">
<Loaders.HistoryRows title="version-history-body-loader" />
</div>
)}
</StyledBody>
);
}
}

View File

@ -45,12 +45,12 @@ class PureVersionHistory extends React.Component {
return (
<PageLayout
withBodyScroll={true}
withBodyAutoFocus={true}
headerBorderBottom={true}
showSecondaryProgressBar={showProgressBar}
secondaryProgressBarIcon="file"
showSecondaryButtonAlert={false}
withBodyScroll={false}
>
<PageLayout.ArticleHeader>
<ArticleHeaderContent />

View File

@ -7,6 +7,7 @@ class VersionHistoryStore {
versions = null;
filesStore = null;
showProgressBar = false;
timerId = null;
constructor(filesStore) {
makeObservable(this, {
@ -79,7 +80,7 @@ class VersionHistoryStore {
};
restoreVersion = (id, version) => {
this.setShowProgressBar(true);
this.timerId = setTimeout(() => this.setShowProgressBar(true), 100);
return api.files
.versionRestore(id, version)
@ -87,9 +88,13 @@ class VersionHistoryStore {
const updatedVersions = this.versions.slice();
updatedVersions.splice(1, 0, newVersion);
this.setVerHistoryFileVersions(updatedVersions);
this.setShowProgressBar(false);
})
.catch(() => this.setShowProgressBar(false));
.catch((e) => console.error(e))
.finally(() => {
clearTimeout(this.timerId);
this.timerId = null;
this.setShowProgressBar(false);
});
};
updateCommentVersion = (id, comment, version) => {

View File

@ -330,7 +330,8 @@ namespace ASC.Files.ThumbnailBuilder
fileDao.SaveThumbnail(file, targetStream);
}
}
}
}
GC.Collect();
}
private Image GetImageThumbnail(Bitmap sourceBitmap)

View File

@ -1,6 +1,6 @@
{
"name": "@appserver/mail",
"version": "1.0.0",
"version": "1.0.1",
"private": true,
"homepage": "/products/mail",
"scripts": {

View File

@ -1,6 +1,6 @@
{
"name": "@appserver/people",
"version": "1.0.0",
"version": "1.0.1",
"private": true,
"homepage": "/products/people",
"scripts": {

View File

@ -209,7 +209,7 @@ class SectionBodyContent extends React.PureComponent {
};
loginCallback = (profile) => {
const { setProviders, t } = this.props;
linkOAuth(profile.Serialized).then((resp) => {
linkOAuth(profile).then((resp) => {
getAuthProviders().then((providers) => {
setProviders(providers);
toastr.success(t("ProviderSuccessfullyConnected"));

View File

@ -1611,14 +1611,9 @@ namespace ASC.Employee.Core.Controllers
{
var url = VirtualPathUtility.ToAbsolute("~/login.ashx") + $"?auth={provider}";
var mode = (settingsView || inviteView || (!MobileDetector.IsMobile() && !Request.DesktopApp())
? ("&mode=popup&callback=" + clientCallback)
: ("&mode=Redirect&returnurl="
+ HttpUtility.UrlEncode(new Uri(Request.GetUrlRewriter(),
"Auth.aspx"
+ (Request.DesktopApp() ? "?desktop=true" : "")
).ToString())
));
var mode = settingsView || inviteView || (!MobileDetector.IsMobile() && !Request.DesktopApp())
? $"&mode=popup&callback={clientCallback}"
: "&mode=Redirect&desktop=true";
infos.Add(new AccountInfo
{

View File

@ -1,6 +1,6 @@
{
"name": "@appserver/projects",
"version": "1.0.0",
"version": "1.0.1",
"private": true,
"homepage": "/products/projects",
"scripts": {

View File

@ -1,3 +1,10 @@
<svg width="18" height="20" viewBox="0 0 18 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6 0H12V2H18V4H12H6H0V2H6V0ZM2 5H16V20H2V5Z" fill="white"/>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_14531:193499)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.49963 0H8.49963C9.32806 0 9.99963 0.671573 9.99963 1.5V2H10.0007H13.0007C14.1055 2 15.0007 2.89593 15.0007 4.00022H13.0007V4H10.0007H8.49963H7.49963H6.00067H3.00067V4.00022H1.00067C1.00067 2.89593 1.89582 2 3.00067 2H5.99963V1.5C5.99963 0.671573 6.67121 0 7.49963 0ZM3.00067 5.00023V13.0002C3.00067 14.6571 4.34382 16.0002 6.00067 16.0002H10.0007C11.6575 16.0002 13.0007 14.6571 13.0007 13.0002V5.00023H11.0007V13.0002C11.0007 13.5525 10.553 14.0002 10.0007 14.0002H6.00067C5.44839 14.0002 5.00067 13.5525 5.00067 13.0002V5.00023H3.00067ZM7.00067 6V14H9.00067V6H7.00067Z" fill="#657077"/>
</g>
<defs>
<clipPath id="clip0_14531:193499">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 212 B

After

Width:  |  Height:  |  Size: 896 B

View File

@ -1,3 +1,10 @@
<svg width="20" height="22" viewBox="0 0 20 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M14 0H6V10H1L10 19L19 10H14V0ZM20 22V20H0V22H20Z" fill="white"/>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_14531:193505)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.00082 6.58749V1H9.00082V6.58409L11.2914 4.29342L12.7056 5.70759L8.7065 9.70693C8.31602 10.0974 7.6829 10.0975 7.29236 9.70704L3.29226 5.70792L4.7063 4.29353L7.00082 6.58749ZM1.99988 8V12H13.9354V8H15.9354V12C15.9354 13.1046 15.0399 14 13.9354 14H1.99988C0.895307 14 -0.00012207 13.1046 -0.00012207 12V8H1.99988Z" fill="#657077"/>
</g>
<defs>
<clipPath id="clip0_14531:193505">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 217 B

After

Width:  |  Height:  |  Size: 637 B

View File

@ -1,3 +1,7 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11 0H18V7H16V3.41423L11.7071 7.70711L10.2929 6.29289L14.5858 2H11V0ZM7 16V18H0V11H2V14.5858L6.2929 10.2929L7.70712 11.7071L3.41423 16H7Z" fill="white"/>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M13 3H10V1H13C14.1046 1 15 1.89543 15 3V6H13V3Z" fill="#657077"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M3 3H6V1H3C1.89543 1 1 1.89543 1 3V6H3V3Z" fill="#657077"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M3 13H6V15H3C1.89543 15 1 14.1046 1 13V10H3V13Z" fill="#657077"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.9971 13H10V15H12.9971C14.1017 15 14.9971 14.1046 14.9971 13V10H12.9971V13Z" fill="#657077"/>
<rect x="5" y="5" width="6" height="6" rx="1" fill="#657077"/>
</svg>

Before

Width:  |  Height:  |  Size: 306 B

After

Width:  |  Height:  |  Size: 651 B

View File

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.5858 3H9.00001V1H14C14.5523 1 15 1.44772 15 2V7H13V4.41421L10.2071 7.20711L8.79291 5.79289L11.5858 3Z" fill="#657077"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.4142 13H6.99999V15H1.99999C1.4477 15 0.999986 14.5523 0.999986 14V9H2.99999V11.5858L5.79288 8.79289L7.20709 10.2071L4.4142 13Z" fill="#657077"/>
</svg>

After

Width:  |  Height:  |  Size: 473 B

View File

@ -1,5 +1,4 @@
<svg width="27" height="22" viewBox="0 0 27 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 5L15 0V22L8 17H0V5H8ZM13 3.88638V18.1136L8.64093 15H2V7H8.64093L13 3.88638Z" fill="white"/>
<path d="M19.5 11C19.5 9.23919 18.4887 7.71457 17.0152 6.97535L18.3288 4.84065C20.5152 6.02475 22 8.33898 22 11C22 13.6904 20.4822 16.0264 18.2561 17.1982L17.0143 15.0251C18.4883 14.286 19.5 12.7612 19.5 11Z" fill="white"/>
<path d="M20.7381 21.5417L19.4973 19.3702C22.4756 17.7666 24.5 14.6197 24.5 11C24.5 7.43877 22.5405 4.33521 19.6408 2.70872L20.9521 0.577835C24.5653 2.64579 27 6.53857 27 11C27 15.549 24.4689 19.5067 20.7381 21.5417Z" fill="white"/>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 11V5H5L10 2V14L5 11H1Z" stroke="#657077" stroke-width="2" stroke-linejoin="round"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M13 13.7455C14.8135 12.4806 16 10.3789 16 8.00019C16 5.62145 14.8135 3.51983 13 2.25488V4.99971C13.6279 5.83545 14 6.87437 14 8.00019C14 9.12602 13.6279 10.1649 13 11.0007V13.7455Z" fill="#657077"/>
</svg>

Before

Width:  |  Height:  |  Size: 704 B

After

Width:  |  Height:  |  Size: 447 B

View File

@ -1,6 +1,4 @@
<svg width="27" height="25" viewBox="0 0 27 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M15 17.5L22 24.5L23.5303 22.9697L1.53033 0.969666L0 2.5L3.5 6H0V18H8L15 23V17.5ZM13 15.5L5.5 8H2V16H8.64093L13 19.1136V15.5Z" fill="white"/>
<path d="M13 4.88638V10L15 12V1L8.58333 5.58334L10.017 7.01706L13 4.88638Z" fill="white"/>
<path d="M18.182 15.182L19.9498 16.9498C21.2165 15.683 22 13.933 22 12C22 9.33898 20.5152 7.02475 18.3288 5.84065L17.0152 7.97535C18.4887 8.71457 19.5 10.2392 19.5 12C19.5 13.2427 18.9963 14.3677 18.182 15.182Z" fill="white"/>
<path d="M21.7175 18.7175L23.4853 20.4853C25.6569 18.3137 27 15.3137 27 12C27 7.53857 24.5653 3.64579 20.9521 1.57784L19.6408 3.70872C22.5405 5.33521 24.5 8.43877 24.5 12C24.5 14.6234 23.4367 16.9984 21.7175 18.7175Z" fill="white"/>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.10812 4H1C0.447715 4 0 4.44772 0 5V11C0 11.5523 0.447715 12 1 12H4.72301L9.4855 14.8575C9.58288 14.9159 9.6878 14.9564 9.79564 14.9789L7.05733 11.0682L5.5145 10.1425C5.35908 10.0493 5.18124 10 5 10H2V6H3.50854L2.10812 4ZM9 6.76713V3.76619L7.52036 4.65398L6.37035 3.0116L9.4855 1.14251C9.79443 0.957149 10.1792 0.952295 10.4927 1.1298C10.8062 1.30731 11 1.63973 11 2V9.62342L9 6.76713ZM13.5739 13.2993L13 12.4797V11.0007C13.6279 10.1649 14 9.12602 14 8.00019C14 6.87437 13.6279 5.83545 13 4.99971V2.25488C14.8135 3.51983 16 5.62145 16 8.00019C16 10.1178 15.0597 12.0157 13.5739 13.2993Z" fill="#657077"/>
<rect x="1.47437" y="1.39648" width="2" height="16.9164" rx="1" transform="rotate(-35 1.47437 1.39648)" fill="#657077"/>
</svg>

Before

Width:  |  Height:  |  Size: 844 B

After

Width:  |  Height:  |  Size: 880 B

View File

@ -1,3 +1,4 @@
<svg width="15" height="18" viewBox="0 0 15 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5 0H0V18H5V0ZM15 0H10V18H15V0Z" fill="white"/>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="3" y="1" width="2" height="14" rx="1" fill="#657077"/>
<rect x="11" y="1" width="2" height="14" rx="1" fill="#657077"/>
</svg>

Before

Width:  |  Height:  |  Size: 200 B

After

Width:  |  Height:  |  Size: 232 B

View File

@ -1,3 +1,10 @@
<svg width="21" height="22" viewBox="0 0 21 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 20.3473V1.65269L18.8449 11L1 20.3473Z" stroke="white" stroke-width="2"/>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_14531:193615)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.4851 5.24297C15.505 6.46199 15.505 9.53801 13.4851 10.757L5.49871 15.5769C3.49434 16.7866 1.00043 15.258 1.00043 12.8199L1.00043 11.1754L3.00482 11.1754L3.00482 12.8199C3.00482 13.6326 3.83613 14.1421 4.50425 13.7389L12.4906 8.91901C13.1639 8.51267 13.1639 7.48733 12.4906 7.08099L4.50425 2.26109C3.83613 1.85787 3.00482 2.36739 3.00482 3.1801L3.00482 11.1754L1.00043 11.1754L1.00043 3.1801C1.00043 0.741951 3.49434 -0.786589 5.49871 0.423074L13.4851 5.24297Z" fill="#657077"/>
</g>
<defs>
<clipPath id="clip0_14531:193615">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 188 B

After

Width:  |  Height:  |  Size: 786 B

View File

@ -1,3 +1,3 @@
<svg width="22" height="18" viewBox="0 0 22 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13 16C16.866 16 20 12.866 20 9C20 5.13401 16.866 2 13 2C9.27739 2 6.23348 4.90585 6.01281 8.57299L8.29291 6.29289L9.70712 7.70711L5.00001 12.4142L0.292908 7.70711L1.70712 6.29289L4.00896 8.59473C4.2209 3.81225 8.16525 0 13 0C17.9706 0 22 4.02944 22 9C22 13.9706 17.9706 18 13 18C10.55 18 8.32866 17.021 6.70579 15.433L8.06432 13.9638C9.32995 15.2223 11.0742 16 13 16Z" fill="white"/>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.46447 4.46447C5.37038 3.55855 6.61901 3 8 3C10.7614 3 13 5.23858 13 8C13 10.7614 10.7614 13 8 13C5.23858 13 3 10.7614 3 8H1C1 11.866 4.13401 15 8 15C11.866 15 15 11.866 15 8C15 4.13401 11.866 1 8 1C6.07026 1 4.32132 1.78217 3.05612 3.04439L3.0548 3.04567L3.03407 3.066C3.02467 3.07528 3.01328 3.08659 3 3.09992V2H1V6C1 6.55228 1.44772 7 2 7H6V5H3.96528C4.048 4.90538 4.12216 4.8231 4.18619 4.75355C4.27504 4.65703 4.34423 4.58519 4.38956 4.53907C4.41223 4.51601 4.42891 4.4994 4.43908 4.48935L4.44939 4.47924L4.45047 4.47819L4.45051 4.47815L4.45075 4.47792L4.45707 4.47186L4.46447 4.46447Z" fill="#657077"/>
</svg>

Before

Width:  |  Height:  |  Size: 497 B

After

Width:  |  Height:  |  Size: 763 B

View File

@ -1,3 +1,3 @@
<svg width="22" height="18" viewBox="0 0 22 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9 16C5.13401 16 2 12.866 2 9C2 5.13401 5.13401 2 9 2C12.7226 2 15.7665 4.90585 15.9872 8.57299L13.7071 6.29289L12.2929 7.70711L17 12.4142L21.7071 7.70711L20.2929 6.29289L17.991 8.59473C17.7791 3.81225 13.8348 0 9 0C4.02944 0 0 4.02944 0 9C0 13.9706 4.02944 18 9 18C11.45 18 13.6713 17.021 15.2942 15.433L13.9357 13.9638C12.6701 15.2223 10.9258 16 9 16Z" fill="white"/>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.5355 4.46447C10.6296 3.55855 9.38099 3 8 3C5.23858 3 3 5.23858 3 8C3 10.7614 5.23858 13 8 13C10.7614 13 13 10.7614 13 8H15C15 11.866 11.866 15 8 15C4.13401 15 1 11.866 1 8C1 4.13401 4.13401 1 8 1C9.92974 1 11.6787 1.78217 12.9439 3.04439L12.9452 3.04567L12.9659 3.066C12.9753 3.07528 12.9867 3.08659 13 3.09992V2H15V6C15 6.55228 14.5523 7 14 7H10V5H12.0347C11.952 4.90538 11.8778 4.8231 11.8138 4.75355C11.725 4.65703 11.6558 4.58519 11.6104 4.53907C11.5878 4.51601 11.5711 4.4994 11.5609 4.48935L11.5506 4.47924L11.5495 4.47819L11.5495 4.47815L11.5492 4.47792L11.5429 4.47186L11.5355 4.46447Z" fill="#657077"/>
</svg>

Before

Width:  |  Height:  |  Size: 482 B

After

Width:  |  Height:  |  Size: 768 B

View File

@ -1,6 +1,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="8.5" cy="8.5" r="7.5" stroke="white" stroke-width="2"/>
<path d="M17.5 19.5L13 15L15 13L19.5 17.5L17.5 19.5Z" fill="white"/>
<rect x="8" y="5" width="1" height="7" fill="white"/>
<rect x="12" y="8" width="1" height="7" transform="rotate(90 12 8)" fill="white"/>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.00331 14C3.13704 14.0008 0.00248369 10.8687 1.63867e-07 7.00248C-0.000827171 3.13622 3.13125 0.0016573 6.99834 6.56004e-07C10.8596 -0.00165357 13.9925 3.12546 14 6.98676C14.0025 8.47474 13.5406 9.85499 12.751 10.9905C12.7616 11.0005 12.7722 11.0106 12.7826 11.021L15.6358 13.8743C16.1223 14.3607 16.1223 15.1494 15.6358 15.6359C15.1494 16.1224 14.3606 16.1224 13.8742 15.6359L11.021 12.7827C11.0105 12.7722 11.0003 12.7616 10.9902 12.7509C9.86056 13.5362 8.48841 13.9975 7.00827 14H7.00331ZM7.00226 12.2C4.13018 12.2006 1.80165 9.87393 1.79981 7.00185C1.79919 4.12976 4.12588 1.80123 6.99857 1.8C9.86696 1.79877 12.1943 4.12177 12.1998 6.99016C12.2047 9.86286 9.87926 12.1951 7.00595 12.2H7.00226Z" fill="#657077"/>
<rect x="4" y="6" width="6" height="2" rx="0.5" fill="#657077"/>
<rect x="6" y="10" width="6" height="2" rx="0.5" transform="rotate(-90 6 10)" fill="#657077"/>
</svg>

Before

Width:  |  Height:  |  Size: 377 B

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1,5 +1,4 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="8.5" cy="8.5" r="7.5" stroke="white" stroke-width="2"/>
<path d="M17.5 19.5L13 15L15 13L19.5 17.5L17.5 19.5Z" fill="white"/>
<rect x="12" y="8" width="1" height="7" transform="rotate(90 12 8)" fill="white"/>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.00331 14C3.13704 14.0008 0.00248369 10.8687 1.63867e-07 7.00248C-0.000827171 3.13622 3.13125 0.0016573 6.99834 6.56004e-07C10.8596 -0.00165357 13.9925 3.12546 14 6.98676C14.0025 8.47474 13.5406 9.85499 12.751 10.9905C12.7616 11.0005 12.7722 11.0106 12.7826 11.021L15.6358 13.8743C16.1223 14.3607 16.1223 15.1494 15.6358 15.6359C15.1494 16.1224 14.3606 16.1224 13.8742 15.6359L11.021 12.7827C11.0105 12.7722 11.0003 12.7616 10.9902 12.7509C9.86056 13.5362 8.48841 13.9975 7.00827 14H7.00331ZM7.00226 12.2C4.13018 12.2006 1.80165 9.87393 1.79981 7.00185C1.79919 4.12976 4.12588 1.80123 6.99857 1.8C9.86696 1.79877 12.1943 4.12177 12.1998 6.99016C12.2047 9.86286 9.87926 12.1951 7.00595 12.2H7.00226Z" fill="#657077"/>
<rect x="4" y="6" width="6" height="2" rx="0.5" fill="#657077"/>
</svg>

Before

Width:  |  Height:  |  Size: 323 B

After

Width:  |  Height:  |  Size: 936 B

View File

@ -52,10 +52,12 @@
const searchUrl = location.search.substring(1);
const object = JSON.parse(
'{"' +
decodeURIComponent(searchUrl)
.replace(/"/g, '\\"')
.replace(/&/g, '","')
.replace(/=/g, '":"') +
decodeURIComponent(
searchUrl
.replace(/"/g, '\\"')
.replace(/&/g, '","')
.replace(/=/g, '":"')
) +
'"}'
);
@ -70,6 +72,8 @@
const urlParams = getObjectByLocation(window.location);
const code = urlParams ? urlParams.code || null : null;
const error = urlParams ? urlParams.error || null : null;
const desktop = urlParams ? urlParams.desktop || false : false;
const p = urlParams ? urlParams.p || false : false;
</script>
</head>
<body id="third-party-body">
@ -78,6 +82,10 @@
<script>
if (code) {
localStorage.setItem("code", code);
if (desktop && p) {
window.location.href = `/login.ashx?p=${p}&code=${code}&desktop=true`;
}
} else if (error) {
renderError(error);
}

View File

@ -25,6 +25,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;
@ -52,6 +53,14 @@ namespace ASC.Web.Api.Controllers
[Read("{provider}")]
public object Get(LoginProviderEnum provider)
{
var desktop = HttpContext.Request.Query["desktop"] == "true";
var additionals = new Dictionary<string, string>();
if (desktop)
{
additionals = HttpContext.Request.Query.ToDictionary(r => r.Key, r => r.Value.FirstOrDefault());
}
switch (provider)
{
case LoginProviderEnum.Google:
@ -61,29 +70,30 @@ namespace ASC.Web.Api.Controllers
{
{ "access_type", "offline" },
{ "prompt", "consent" }
});
}, additionalStateArgs: additionals);
case LoginProviderEnum.Dropbox:
return OAuth20TokenHelper.RequestCode<DropboxLoginProvider>(
additionalArgs: new Dictionary<string, string>
{
{ "force_reauthentication", "true" }
});
}, additionalStateArgs: additionals);
case LoginProviderEnum.Docusign:
return OAuth20TokenHelper.RequestCode<DocuSignLoginProvider>(DocuSignLoginProvider.DocuSignLoginProviderScopes,
return OAuth20TokenHelper.RequestCode<DocuSignLoginProvider>(
DocuSignLoginProvider.DocuSignLoginProviderScopes,
new Dictionary<string, string>
{
{ "prompt", "login" }
});
}, additionalStateArgs: additionals);
case LoginProviderEnum.Box:
return OAuth20TokenHelper.RequestCode<BoxLoginProvider>();
return OAuth20TokenHelper.RequestCode<BoxLoginProvider>(additionalStateArgs: additionals);
case LoginProviderEnum.OneDrive:
return OAuth20TokenHelper.RequestCode<OneDriveLoginProvider>(OneDriveLoginProvider.OneDriveLoginProviderScopes);
return OAuth20TokenHelper.RequestCode<OneDriveLoginProvider>(OneDriveLoginProvider.OneDriveLoginProviderScopes, additionalStateArgs: additionals);
case LoginProviderEnum.Wordpress:
return OAuth20TokenHelper.RequestCode<WordpressLoginProvider>();
return OAuth20TokenHelper.RequestCode<WordpressLoginProvider>(additionalStateArgs: additionals);
}

View File

@ -1,6 +1,6 @@
{
"name": "@appserver/studio",
"version": "1.0.0",
"version": "1.0.1",
"private": true,
"homepage": "",
"scripts": {

View File

@ -1,6 +1,6 @@
{
"name": "@appserver/editor",
"version": "1.0.0",
"version": "1.0.1",
"private": true,
"homepage": "/products/files/doceditor",
"scripts": {

View File

@ -1,6 +1,6 @@
{
"name": "@appserver/login",
"version": "1.0.0",
"version": "1.0.1",
"private": true,
"homepage": "/login",
"scripts": {

View File

@ -176,7 +176,6 @@ const Form = (props) => {
login,
hashSettings,
isDesktop,
defaultPage,
match,
organizationName,
greetingTitle,
@ -187,6 +186,35 @@ const Form = (props) => {
const { error, confirmedEmail } = match.params;
const oAuthLogin = async (profile) => {
try {
await thirdPartyLogin(profile);
const redirectPath = localStorage.getItem("redirectPath");
if (redirectPath) {
localStorage.removeItem("redirectPath");
window.location.href = redirectPath;
}
}
catch(e) {
toastr.error(
t("Common:ProviderNotConnected"),
t("Common:ProviderLoginError")
);
}
localStorage.removeItem("profile");
localStorage.removeItem("code");
};
useEffect(() => {
const profile = localStorage.getItem("profile");
if (!profile) return;
oAuthLogin(profile);
}, []);
const onKeyDown = (e) => {
//console.log("onKeyDown", e.key);
if (e.key === "Enter") {
@ -206,22 +234,7 @@ const Form = (props) => {
//const throttledKeyPress = throttle(onKeyPress, 500);
const authCallback = (profile) => {
thirdPartyLogin(profile.Serialized)
.then(() => {
setIsLoading(true);
const redirectPath = localStorage.getItem("redirectPath");
if (redirectPath) {
localStorage.removeItem("redirectPath");
window.location.href = redirectPath;
} else history.push(defaultPage);
})
.catch(() => {
toastr.error(
t("Common:ProviderNotConnected"),
t("Common:ProviderLoginError")
);
});
oAuthLogin(profile);
};
const setProviders = async () => {
@ -335,11 +348,13 @@ const Form = (props) => {
const { getOAuthToken, getLoginLink } = props;
try {
const tokenGetterWin = window.open(
url,
"login",
"width=800,height=500,status=no,toolbar=no,menubar=no,resizable=yes,scrollbars=no"
);
const tokenGetterWin = isDesktop
? (window.location.href = url)
: window.open(
url,
"login",
"width=800,height=500,status=no,toolbar=no,menubar=no,resizable=yes,scrollbars=no"
);
getOAuthToken(tokenGetterWin).then((code) => {
const token = window.btoa(