version 0.3.0, rev187, Trusted authorization sites support, --publish option on signing, cryptSign command line option, OpenSSL enabled on OSX, Crypto verify allows list of valid addresses, Option for version 2 json DB tables, DbCursor SELECT parameters bugfix, Add peer to site on ListModified, Download blind includes when new site added, Publish command better messages, Multi-threaded announce, New http Torrent trackers, Wait for dbschema.json on query, Handle json import errors, More compact writeJson storage command, Testcase for signing and verifying, Workaround to make non target=_top links work, More clean UiWebsocket command route, Send cert_user_id on siteinfo, Notify other local clients on local file modify, Option to wait for file download before sql query, File rules websocket API command, Cert add and select, set websocket API command, Put focus on innerframe, innerloaded wrapper api command to add hashtag, Allow more file error on big sites, Keep worker running after stuked on done task, New more stable openSSL layer that works on OSX, Noparallel parameter bugfix, RateLimit allowed again interval bugfix, Updater skips non-writeable files, Try to close openssl dll before update
This commit is contained in:
parent
c874726aba
commit
7e4f6bd38e
33 changed files with 1716 additions and 595 deletions
|
@ -170,7 +170,7 @@ class UiRequest(object):
|
|||
|
||||
if not site: return False
|
||||
|
||||
extra_headers.append(("X-Frame-Options", "DENY"))
|
||||
#extra_headers.append(("X-Frame-Options", "DENY"))
|
||||
|
||||
self.sendHeader(extra_headers=extra_headers[:])
|
||||
|
||||
|
|
|
@ -96,44 +96,13 @@ class UiWebsocket(object):
|
|||
permissions = permissions[:]
|
||||
permissions.append("ADMIN")
|
||||
|
||||
admin_commands = ("sitePause", "siteResume", "siteDelete", "siteList", "siteSetLimit", "channelJoinAllsite", "serverUpdate", "certSet")
|
||||
|
||||
if cmd == "response": # It's a response to a command
|
||||
return self.actionResponse(req["to"], req["result"])
|
||||
elif cmd == "ping":
|
||||
func = self.actionPing
|
||||
elif cmd == "channelJoin":
|
||||
func = self.actionChannelJoin
|
||||
elif cmd == "siteInfo":
|
||||
func = self.actionSiteInfo
|
||||
elif cmd == "serverInfo":
|
||||
func = self.actionServerInfo
|
||||
elif cmd == "siteUpdate":
|
||||
func = self.actionSiteUpdate
|
||||
elif cmd == "sitePublish":
|
||||
func = self.actionSitePublish
|
||||
elif cmd == "fileWrite":
|
||||
func = self.actionFileWrite
|
||||
elif cmd == "fileGet":
|
||||
func = self.actionFileGet
|
||||
elif cmd == "fileQuery":
|
||||
func = self.actionFileQuery
|
||||
elif cmd == "dbQuery":
|
||||
func = self.actionDbQuery
|
||||
# Admin commands
|
||||
elif cmd == "sitePause" and "ADMIN" in permissions:
|
||||
func = self.actionSitePause
|
||||
elif cmd == "siteResume" and "ADMIN" in permissions:
|
||||
func = self.actionSiteResume
|
||||
elif cmd == "siteDelete" and "ADMIN" in permissions:
|
||||
func = self.actionSiteDelete
|
||||
elif cmd == "siteList" and "ADMIN" in permissions:
|
||||
func = self.actionSiteList
|
||||
elif cmd == "siteSetLimit" and "ADMIN" in permissions:
|
||||
func = self.actionSiteSetLimit
|
||||
elif cmd == "channelJoinAllsite" and "ADMIN" in permissions:
|
||||
func = self.actionChannelJoinAllsite
|
||||
elif cmd == "serverUpdate" and "ADMIN" in permissions:
|
||||
func = self.actionServerUpdate
|
||||
else:
|
||||
elif cmd in admin_commands and "ADMIN" not in permissions: # Admin commands
|
||||
return self.response(req["id"], "You don't have permission to run %s" % cmd)
|
||||
else: # Normal command
|
||||
func_name = "action" + cmd[0].upper() + cmd[1:]
|
||||
func = getattr(self, func_name, None)
|
||||
if not func: # Unknown command
|
||||
|
@ -158,6 +127,7 @@ class UiWebsocket(object):
|
|||
content["includes"] = len(content.get("includes", {}))
|
||||
if "sign" in content: del(content["sign"])
|
||||
if "signs" in content: del(content["signs"])
|
||||
if "signers_sign" in content: del(content["signers_sign"])
|
||||
|
||||
settings = site.settings.copy()
|
||||
del settings["wrapper_key"] # Dont expose wrapper key
|
||||
|
@ -167,6 +137,7 @@ class UiWebsocket(object):
|
|||
"auth_key": self.site.settings["auth_key"], # Obsolete, will be removed
|
||||
"auth_key_sha512": hashlib.sha512(self.site.settings["auth_key"]).hexdigest()[0:64], # Obsolete, will be removed
|
||||
"auth_address": self.user.getAuthAddress(site.address, create=create_user),
|
||||
"cert_user_id": self.user.getCertUserId(site.address),
|
||||
"address": site.address,
|
||||
"settings": settings,
|
||||
"content_updated": site.content_updated,
|
||||
|
@ -236,8 +207,16 @@ class UiWebsocket(object):
|
|||
|
||||
def actionSitePublish(self, to, privatekey=None, inner_path="content.json"):
|
||||
site = self.site
|
||||
extend = {} # Extended info for signing
|
||||
if not inner_path.endswith("content.json"): # Find the content.json first
|
||||
inner_path = site.content_manager.getFileInfo(inner_path)["content_inner_path"]
|
||||
file_info = site.content_manager.getFileInfo(inner_path)
|
||||
inner_path = file_info["content_inner_path"]
|
||||
if "cert_signers" in file_info: # Its an user dir file
|
||||
cert = self.user.getCert(self.site.address)
|
||||
extend["cert_auth_type"] = cert["auth_type"]
|
||||
extend["cert_user_id"] = self.user.getCertUserId(site.address)
|
||||
extend["cert_sign"] = cert["cert_sign"]
|
||||
|
||||
|
||||
if not site.settings["own"] and self.user.getAuthAddress(self.site.address) not in self.site.content_manager.getValidSigners(inner_path):
|
||||
return self.response(to, "Forbidden, you can only modify your own sites")
|
||||
|
@ -246,7 +225,7 @@ class UiWebsocket(object):
|
|||
|
||||
# Signing
|
||||
site.content_manager.loadContent(add_bad_files=False) # Reload content.json, ignore errors to make it up-to-date
|
||||
signed = site.content_manager.sign(inner_path, privatekey) # Sign using private key sent by user
|
||||
signed = site.content_manager.sign(inner_path, privatekey, extend=extend) # Sign using private key sent by user
|
||||
if signed:
|
||||
if inner_path == "content_json": self.cmd("notification", ["done", "Private key correct, content signed!", 5000]) # Display message for 5 sec
|
||||
else:
|
||||
|
@ -301,7 +280,13 @@ class UiWebsocket(object):
|
|||
if inner_path.endswith("content.json"):
|
||||
self.site.content_manager.loadContent(inner_path, add_bad_files=False)
|
||||
|
||||
return self.response(to, "ok")
|
||||
self.response(to, "ok")
|
||||
|
||||
# Send sitechanged to other local users
|
||||
for ws in self.site.websockets:
|
||||
if ws != self:
|
||||
ws.event("siteChanged", self.site, {"event": ["file_done", inner_path]})
|
||||
|
||||
|
||||
|
||||
# Find data in json files
|
||||
|
@ -314,7 +299,7 @@ class UiWebsocket(object):
|
|||
|
||||
|
||||
# Sql query
|
||||
def actionDbQuery(self, to, query, params=None):
|
||||
def actionDbQuery(self, to, query, params=None, wait_for=None):
|
||||
rows = []
|
||||
try:
|
||||
res = self.site.storage.query(query, params)
|
||||
|
@ -327,15 +312,95 @@ class UiWebsocket(object):
|
|||
|
||||
|
||||
# Return file content
|
||||
def actionFileGet(self, to, inner_path):
|
||||
def actionFileGet(self, to, inner_path, required=True):
|
||||
try:
|
||||
self.site.needFile(inner_path, priority=1)
|
||||
if required: self.site.needFile(inner_path, priority=1)
|
||||
body = self.site.storage.read(inner_path)
|
||||
except:
|
||||
body = None
|
||||
return self.response(to, body)
|
||||
|
||||
|
||||
def actionFileRules(self, to, inner_path):
|
||||
rules = self.site.content_manager.getRules(inner_path)
|
||||
if inner_path.endswith("content.json"):
|
||||
content = self.site.content_manager.contents.get(inner_path)
|
||||
if content:
|
||||
rules["current_size"] = len(json.dumps(content)) + sum([file["size"] for file in content["files"].values()])
|
||||
else:
|
||||
rules["current_size"] = 0
|
||||
return self.response(to, rules)
|
||||
|
||||
|
||||
# Add certificate to user
|
||||
def actionCertAdd(self, to, domain, auth_type, auth_user_name, cert):
|
||||
try:
|
||||
res = self.user.addCert(self.user.getAuthAddress(self.site.address), domain, auth_type, auth_user_name, cert)
|
||||
if res == True:
|
||||
self.cmd("notification", ["done", "New certificate added: <b>%s/%s@%s</b>." % (auth_type, auth_user_name, domain)])
|
||||
self.response(to, "ok")
|
||||
else:
|
||||
self.response(to, "Not changed")
|
||||
except Exception, err:
|
||||
self.response(to, {"error": err.message})
|
||||
|
||||
|
||||
# Select certificate for site
|
||||
def actionCertSelect(self, to, accepted_domains=[]):
|
||||
accounts = []
|
||||
accounts.append(["", "Unique to site", ""]) # Default option
|
||||
active = "" # Make it active if no other option found
|
||||
|
||||
# Add my certs
|
||||
auth_address = self.user.getAuthAddress(self.site.address) # Current auth address
|
||||
for domain, cert in self.user.certs.items():
|
||||
if auth_address == cert["auth_address"]:
|
||||
active = domain
|
||||
title = cert["auth_user_name"]+"@"+domain
|
||||
if domain in accepted_domains:
|
||||
accounts.append([domain, title, ""])
|
||||
else:
|
||||
accounts.append([domain, title, "disabled"])
|
||||
|
||||
|
||||
# Render the html
|
||||
body = "<span style='padding-bottom: 5px; display: inline-block'>Select account you want to use in this site:</span>"
|
||||
# Accounts
|
||||
for domain, account, css_class in accounts:
|
||||
if domain == active:
|
||||
css_class += " active" # Currently selected option
|
||||
title = "<b>%s</b> <small>(currently selected)</small>" % account
|
||||
else:
|
||||
title = "<b>%s</b>" % account
|
||||
body += "<a href='#Select+account' class='select select-close cert %s' title='%s'>%s</a>" % (css_class, domain, title)
|
||||
# More avalible providers
|
||||
more_domains = [domain for domain in accepted_domains if domain not in self.user.certs] # Domainains we not displayed yet
|
||||
if more_domains:
|
||||
# body+= "<small style='margin-top: 10px; display: block'>Accepted authorization providers by the site:</small>"
|
||||
body+= "<div style='background-color: #F7F7F7; margin-right: -30px'>"
|
||||
for domain in more_domains:
|
||||
body += "<a href='/%s' onclick='wrapper.gotoSite(this)' target='_blank' class='select'><small style='float: right; margin-right: 40px; margin-top: -1px'>Register »</small>%s</a>" % (domain, domain)
|
||||
body+= "</div>"
|
||||
|
||||
body += """
|
||||
<script>
|
||||
$(".notification .select.cert").on("click", function() {
|
||||
$(".notification .select").removeClass('active')
|
||||
wrapper.ws.cmd('certSet', [this.title])
|
||||
return false
|
||||
})
|
||||
</script>
|
||||
"""
|
||||
|
||||
# Send the notification
|
||||
self.cmd("notification", ["ask", body])
|
||||
|
||||
|
||||
# Set certificate that used for authenticate user for site
|
||||
def actionCertSet(self, to, domain):
|
||||
self.user.setCert(self.site.address, domain)
|
||||
self.site.updateWebsocket(cert_changed=domain)
|
||||
|
||||
|
||||
# - Admin actions -
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ class Notifications
|
|||
|
||||
|
||||
add: (id, type, body, timeout=0) ->
|
||||
@log id, type, body, timeout
|
||||
# Close notifications with same id
|
||||
for elem in $(".notification-#{id}")
|
||||
@close $(elem)
|
||||
|
@ -55,15 +54,14 @@ class Notifications
|
|||
elem.animate({"width": width}, 700, "easeInOutCubic")
|
||||
$(".body", elem).cssLater("box-shadow", "0px 0px 5px rgba(0,0,0,0.1)", 1000)
|
||||
|
||||
# Close button
|
||||
$(".close", elem).on "click", =>
|
||||
# Close button or Confirm button
|
||||
$(".close, .button", elem).on "click", =>
|
||||
@close elem
|
||||
return false
|
||||
|
||||
# Close on button click within body (confirm dialog)
|
||||
$(".button", elem).on "click", =>
|
||||
# Select list
|
||||
$(".select", elem).on "click", =>
|
||||
@close elem
|
||||
return false
|
||||
|
||||
|
||||
close: (elem) ->
|
||||
|
|
|
@ -30,6 +30,12 @@ class Wrapper
|
|||
if window.location.hash
|
||||
src = $("#inner-iframe").attr("src").replace(/#.*/, "")+window.location.hash
|
||||
$("#inner-iframe").attr("src", src)
|
||||
|
||||
###setInterval (->
|
||||
console.log document.hasFocus()
|
||||
), 1000###
|
||||
$("#inner-iframe").focus()
|
||||
|
||||
@
|
||||
|
||||
|
||||
|
@ -67,6 +73,10 @@ class Wrapper
|
|||
if @ws.ws.readyState == 1 and not @wrapperWsInited # If ws already opened
|
||||
@sendInner {"cmd": "wrapperOpenedWebsocket"}
|
||||
@wrapperWsInited = true
|
||||
else if cmd == "innerLoaded"
|
||||
if window.location.hash
|
||||
$("#inner-iframe")[0].src += window.location.hash # Hash tag
|
||||
@log "Added hash to location", $("#inner-iframe")[0].src
|
||||
else if cmd == "wrapperNotification" # Display notification
|
||||
@actionNotification(message)
|
||||
else if cmd == "wrapperConfirm" # Display confirm message
|
||||
|
@ -208,7 +218,6 @@ class Wrapper
|
|||
@inner_loaded = true
|
||||
if not @inner_ready then @sendInner {"cmd": "wrapperReady"} # Inner frame loaded before wrapper
|
||||
#if not @site_error then @loading.hideScreen() # Hide loading screen
|
||||
if window.location.hash then $("#inner-iframe")[0].src += window.location.hash # Hash tag
|
||||
if @ws.ws.readyState == 1 and not @site_info # Ws opened
|
||||
@reloadSiteInfo()
|
||||
else if @site_info and @site_info.content?.title?
|
||||
|
@ -313,13 +322,27 @@ class Wrapper
|
|||
return false
|
||||
|
||||
|
||||
isProxyRequest: ->
|
||||
return window.location.pathname == "/"
|
||||
|
||||
|
||||
gotoSite: (elem) =>
|
||||
href = $(elem).attr("href")
|
||||
if @isProxyRequest() # Fix for proxy request
|
||||
$(elem).attr("href", "http://zero#{href}")
|
||||
|
||||
|
||||
|
||||
log: (args...) ->
|
||||
console.log "[Wrapper]", args...
|
||||
|
||||
origin = window.server_url or window.location.origin
|
||||
|
||||
if window.server_url
|
||||
ws_url = "ws://#{window.server_url.replace('http://', '')}/Websocket?wrapper_key=#{window.wrapper_key}"
|
||||
if origin.indexOf("https:") == 0
|
||||
proto = { ws: 'wss', http: 'https' }
|
||||
else
|
||||
ws_url = "ws://#{window.location.hostname}:#{window.location.port}/Websocket?wrapper_key=#{window.wrapper_key}"
|
||||
proto = { ws: 'ws', http: 'http' }
|
||||
|
||||
ws_url = proto.ws + ":" + origin.replace(proto.http+":", "") + "/Websocket?wrapper_key=" + window.wrapper_key
|
||||
|
||||
window.wrapper = new Wrapper(ws_url)
|
||||
|
|
|
@ -58,6 +58,16 @@ a { color: black }
|
|||
.notification small { color: #AAA }
|
||||
.body-white .notification { box-shadow: 0px 1px 9px rgba(0,0,0,0.1) }
|
||||
|
||||
/* Notification select */
|
||||
.notification .select {
|
||||
display: block; padding: 10px; margin-right: -32px; text-decoration: none; border-left: 3px solid #EEE;
|
||||
margin-top: 1px; transition: all 0.3s; color: #666
|
||||
}
|
||||
.notification .select:hover, .notification .select.active { background-color: #007AFF; border-left: 3px solid #5D68FF; color: white; transition: none }
|
||||
.notification .select:active, .notification .select:focus { background-color: #3396FF; color: white; transition: none; border-left-color: #3396FF }
|
||||
.notification .select.disabled { opacity: 0.5; pointer-events: none }
|
||||
.notification .select small { color: inherit; }
|
||||
|
||||
/* Notification types */
|
||||
.notification-ask .notification-icon { background-color: #f39c12; }
|
||||
.notification-info .notification-icon { font-size: 22px; font-weight: bold; background-color: #2980b9; line-height: 48px }
|
||||
|
@ -115,6 +125,10 @@ a { color: black }
|
|||
box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d; opacity: 1.0; transform: rotate(3deg) translate(0px, -4px);
|
||||
}
|
||||
|
||||
/* Icons */
|
||||
.icon-profile { font-size: 6px; top: 0em; border-radius: 0.7em 0.7em 0 0; background: #FFFFFF; width: 1.5em; height: 0.7em; position: relative; display: inline-block; margin-right: 4px }
|
||||
.icon-profile::before { position: absolute; content: ""; top: -1em; left: 0.38em; width: 0.8em; height: 0.85em; border-radius: 50%; background: #FFFFFF }
|
||||
|
||||
/* Animations */
|
||||
|
||||
@keyframes flip {
|
||||
|
@ -130,3 +144,9 @@ a { color: black }
|
|||
70% { opacity: 0 }
|
||||
100% { opacity: 0 }
|
||||
}
|
||||
|
||||
/* Print styles */
|
||||
@media print {
|
||||
#inner-iframe { position: fixed; }
|
||||
.progressbar, .fixbutton, .notifications, .loadingscreen { visibility: hidden; }
|
||||
}
|
|
@ -63,6 +63,16 @@ a { color: black }
|
|||
.notification small { color: #AAA }
|
||||
.body-white .notification { -webkit-box-shadow: 0px 1px 9px rgba(0,0,0,0.1) ; -moz-box-shadow: 0px 1px 9px rgba(0,0,0,0.1) ; -o-box-shadow: 0px 1px 9px rgba(0,0,0,0.1) ; -ms-box-shadow: 0px 1px 9px rgba(0,0,0,0.1) ; box-shadow: 0px 1px 9px rgba(0,0,0,0.1) }
|
||||
|
||||
/* Notification select */
|
||||
.notification .select {
|
||||
display: block; padding: 10px; margin-right: -32px; text-decoration: none; border-left: 3px solid #EEE;
|
||||
margin-top: 1px; -webkit-transition: all 0.3s; -moz-transition: all 0.3s; -o-transition: all 0.3s; -ms-transition: all 0.3s; transition: all 0.3s ; color: #666
|
||||
}
|
||||
.notification .select:hover, .notification .select.active { background-color: #007AFF; border-left: 3px solid #5D68FF; color: white; -webkit-transition: none ; -moz-transition: none ; -o-transition: none ; -ms-transition: none ; transition: none }
|
||||
.notification .select:active, .notification .select:focus { background-color: #3396FF; color: white; -webkit-transition: none; -moz-transition: none; -o-transition: none; -ms-transition: none; transition: none ; border-left-color: #3396FF }
|
||||
.notification .select.disabled { opacity: 0.5; pointer-events: none }
|
||||
.notification .select small { color: inherit; }
|
||||
|
||||
/* Notification types */
|
||||
.notification-ask .notification-icon { background-color: #f39c12; }
|
||||
.notification-info .notification-icon { font-size: 22px; font-weight: bold; background-color: #2980b9; line-height: 48px }
|
||||
|
@ -120,6 +130,10 @@ a { color: black }
|
|||
-webkit-box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d; -moz-box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d; -o-box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d; -ms-box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d; box-shadow: 0 0 10px #AF3BFF, 0 0 5px #29d ; opacity: 1.0; -webkit-transform: rotate(3deg) translate(0px, -4px); -moz-transform: rotate(3deg) translate(0px, -4px); -o-transform: rotate(3deg) translate(0px, -4px); -ms-transform: rotate(3deg) translate(0px, -4px); transform: rotate(3deg) translate(0px, -4px) ;
|
||||
}
|
||||
|
||||
/* Icons */
|
||||
.icon-profile { font-size: 6px; top: 0em; -webkit-border-radius: 0.7em 0.7em 0 0; -moz-border-radius: 0.7em 0.7em 0 0; -o-border-radius: 0.7em 0.7em 0 0; -ms-border-radius: 0.7em 0.7em 0 0; border-radius: 0.7em 0.7em 0 0 ; background: #FFFFFF; width: 1.5em; height: 0.7em; position: relative; display: inline-block; margin-right: 4px }
|
||||
.icon-profile::before { position: absolute; content: ""; top: -1em; left: 0.38em; width: 0.8em; height: 0.85em; -webkit-border-radius: 50%; -moz-border-radius: 50%; -o-border-radius: 50%; -ms-border-radius: 50%; border-radius: 50% ; background: #FFFFFF }
|
||||
|
||||
/* Animations */
|
||||
|
||||
@keyframes flip {
|
||||
|
@ -161,8 +175,9 @@ a { color: black }
|
|||
100% { opacity: 0 }
|
||||
}
|
||||
|
||||
|
||||
/* Print styles */
|
||||
@media print {
|
||||
#inner-iframe { position: fixed; }
|
||||
.progressbar, .fixbutton, .notifications, .loadingscreen { visibility: hidden; }
|
||||
}
|
||||
}
|
|
@ -595,7 +595,6 @@ jQuery.extend( jQuery.easing,
|
|||
if (timeout == null) {
|
||||
timeout = 0;
|
||||
}
|
||||
this.log(id, type, body, timeout);
|
||||
_ref = $(".notification-" + id);
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
elem = _ref[_i];
|
||||
|
@ -644,16 +643,15 @@ jQuery.extend( jQuery.easing,
|
|||
"width": width
|
||||
}, 700, "easeInOutCubic");
|
||||
$(".body", elem).cssLater("box-shadow", "0px 0px 5px rgba(0,0,0,0.1)", 1000);
|
||||
$(".close", elem).on("click", (function(_this) {
|
||||
$(".close, .button", elem).on("click", (function(_this) {
|
||||
return function() {
|
||||
_this.close(elem);
|
||||
return false;
|
||||
};
|
||||
})(this));
|
||||
return $(".button", elem).on("click", (function(_this) {
|
||||
return $(".select", elem).on("click", (function(_this) {
|
||||
return function() {
|
||||
_this.close(elem);
|
||||
return false;
|
||||
return _this.close(elem);
|
||||
};
|
||||
})(this));
|
||||
};
|
||||
|
@ -683,6 +681,7 @@ jQuery.extend( jQuery.easing,
|
|||
}).call(this);
|
||||
|
||||
|
||||
|
||||
/* ---- src/Ui/media/Sidebar.coffee ---- */
|
||||
|
||||
|
||||
|
@ -742,12 +741,13 @@ jQuery.extend( jQuery.easing,
|
|||
|
||||
|
||||
(function() {
|
||||
var Wrapper, ws_url,
|
||||
var Wrapper, origin, proto, ws_url,
|
||||
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
|
||||
__slice = [].slice;
|
||||
|
||||
Wrapper = (function() {
|
||||
function Wrapper(ws_url) {
|
||||
this.gotoSite = __bind(this.gotoSite, this);
|
||||
this.setSizeLimit = __bind(this.setSizeLimit, this);
|
||||
this.onLoad = __bind(this.onLoad, this);
|
||||
this.onCloseWebsocket = __bind(this.onCloseWebsocket, this);
|
||||
|
@ -785,6 +785,12 @@ jQuery.extend( jQuery.easing,
|
|||
}
|
||||
};
|
||||
})(this));
|
||||
|
||||
/*setInterval (->
|
||||
console.log document.hasFocus()
|
||||
), 1000
|
||||
*/
|
||||
$("#inner-iframe").focus();
|
||||
this;
|
||||
}
|
||||
|
||||
|
@ -831,6 +837,11 @@ jQuery.extend( jQuery.easing,
|
|||
});
|
||||
return this.wrapperWsInited = true;
|
||||
}
|
||||
} else if (cmd === "innerLoaded") {
|
||||
if (window.location.hash) {
|
||||
$("#inner-iframe")[0].src += window.location.hash;
|
||||
return this.log("Added hash to location", $("#inner-iframe")[0].src);
|
||||
}
|
||||
} else if (cmd === "wrapperNotification") {
|
||||
return this.actionNotification(message);
|
||||
} else if (cmd === "wrapperConfirm") {
|
||||
|
@ -1032,9 +1043,6 @@ jQuery.extend( jQuery.easing,
|
|||
"cmd": "wrapperReady"
|
||||
});
|
||||
}
|
||||
if (window.location.hash) {
|
||||
$("#inner-iframe")[0].src += window.location.hash;
|
||||
}
|
||||
if (this.ws.ws.readyState === 1 && !this.site_info) {
|
||||
return this.reloadSiteInfo();
|
||||
} else if (this.site_info && (((_ref = this.site_info.content) != null ? _ref.title : void 0) != null)) {
|
||||
|
@ -1163,6 +1171,18 @@ jQuery.extend( jQuery.easing,
|
|||
return false;
|
||||
};
|
||||
|
||||
Wrapper.prototype.isProxyRequest = function() {
|
||||
return window.location.pathname === "/";
|
||||
};
|
||||
|
||||
Wrapper.prototype.gotoSite = function(elem) {
|
||||
var href;
|
||||
href = $(elem).attr("href");
|
||||
if (this.isProxyRequest()) {
|
||||
return $(elem).attr("href", "http://zero" + href);
|
||||
}
|
||||
};
|
||||
|
||||
Wrapper.prototype.log = function() {
|
||||
var args;
|
||||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
||||
|
@ -1173,15 +1193,22 @@ jQuery.extend( jQuery.easing,
|
|||
|
||||
})();
|
||||
|
||||
var origin = window.server_url || window.location.origin;
|
||||
var proto;
|
||||
if (origin.indexOf('https:') === 0) {
|
||||
proto = { ws: 'wss', ht: 'https' };
|
||||
origin = window.server_url || window.location.origin;
|
||||
|
||||
if (origin.indexOf("https:") === 0) {
|
||||
proto = {
|
||||
ws: 'wss',
|
||||
http: 'https'
|
||||
};
|
||||
} else {
|
||||
proto = { ws: 'ws', ht: 'http' };
|
||||
proto = {
|
||||
ws: 'ws',
|
||||
http: 'http'
|
||||
};
|
||||
}
|
||||
ws_url = proto.ws + ":" + (origin.replace(proto.ht + ':', '')) + "/Websocket?wrapper_key=" + window.wrapper_key;
|
||||
|
||||
ws_url = proto.ws + ":" + origin.replace(proto.http + ":", "") + "/Websocket?wrapper_key=" + window.wrapper_key;
|
||||
|
||||
window.wrapper = new Wrapper(ws_url);
|
||||
|
||||
}).call(this);
|
||||
}).call(this);
|
|
@ -11,6 +11,12 @@
|
|||
</head>
|
||||
<body style="{body_style}">
|
||||
|
||||
<script>
|
||||
// If we are inside iframe escape from it
|
||||
if (window.self !== window.top) window.open(window.location.toString(), "_top");
|
||||
if (window.self !== window.top) window.stop();
|
||||
</script>
|
||||
|
||||
<div class="progressbar">
|
||||
<div class="peg"></div>
|
||||
</div>
|
||||
|
@ -40,15 +46,17 @@
|
|||
|
||||
|
||||
<!-- Site Iframe -->
|
||||
<iframe src='{inner_path}{query_string}' id='inner-iframe' sandbox="allow-forms allow-scripts allow-top-navigation"></iframe>
|
||||
<iframe src='{inner_path}{query_string}' id='inner-iframe' sandbox="allow-forms allow-scripts allow-top-navigation allow-popups"></iframe>
|
||||
|
||||
<!-- Site info -->
|
||||
<script>address = "{address}"</script>
|
||||
<script>wrapper_key = "{wrapper_key}"</script>
|
||||
<script>file_inner_path = "{file_inner_path}"</script>
|
||||
<script>permissions = {permissions}</script>
|
||||
<script>show_loadingscreen = {show_loadingscreen}</script>
|
||||
<script>server_url = '{server_url}'</script>
|
||||
<script>
|
||||
address = "{address}"
|
||||
wrapper_key = "{wrapper_key}"
|
||||
file_inner_path = "{file_inner_path}"
|
||||
permissions = {permissions}
|
||||
show_loadingscreen = {show_loadingscreen}
|
||||
server_url = '{server_url}'
|
||||
</script>
|
||||
<script type="text/javascript" src="{server_url}/uimedia/all.js" asyc></script>
|
||||
|
||||
</body>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue