mirror of
https://github.com/TitanEmbeds/Titan.git
synced 2024-12-26 06:57:04 +01:00
Support cross origin embedding
This commit is contained in:
parent
1e9d443756
commit
cba4014bde
@ -1,6 +1,6 @@
|
|||||||
from titanembeds.database import db, Guilds, UnauthenticatedUsers, UnauthenticatedBans, AuthenticatedUsers, get_administrators_list, get_badges, DiscordBotsOrgTransactions
|
from titanembeds.database import db, Guilds, UnauthenticatedUsers, UnauthenticatedBans, AuthenticatedUsers, get_administrators_list, get_badges, DiscordBotsOrgTransactions
|
||||||
from titanembeds.decorators import valid_session_required, discord_users_only, abort_if_guild_disabled
|
from titanembeds.decorators import valid_session_required, discord_users_only, abort_if_guild_disabled
|
||||||
from titanembeds.utils import check_guild_existance, guild_accepts_visitors, guild_query_unauth_users_bool, get_client_ipaddr, discord_api, rate_limiter, channel_ratelimit_key, guild_ratelimit_key, user_unauthenticated, checkUserRevoke, checkUserBanned, update_user_status, check_user_in_guild, get_guild_channels, guild_webhooks_enabled, guild_unauthcaptcha_enabled, get_member_roles, get_online_embed_user_keys, redis_store, redisqueue, get_forced_role
|
from titanembeds.utils import serializer, check_guild_existance, guild_accepts_visitors, guild_query_unauth_users_bool, get_client_ipaddr, discord_api, rate_limiter, channel_ratelimit_key, guild_ratelimit_key, user_unauthenticated, checkUserRevoke, checkUserBanned, update_user_status, check_user_in_guild, get_guild_channels, guild_webhooks_enabled, guild_unauthcaptcha_enabled, get_member_roles, get_online_embed_user_keys, redis_store, redisqueue, get_forced_role
|
||||||
from titanembeds.oauth import user_has_permission, generate_avatar_url, check_user_can_administrate_guild
|
from titanembeds.oauth import user_has_permission, generate_avatar_url, check_user_can_administrate_guild
|
||||||
import titanembeds.constants as constants
|
import titanembeds.constants as constants
|
||||||
from flask import Blueprint, abort, jsonify, session, request, url_for
|
from flask import Blueprint, abort, jsonify, session, request, url_for
|
||||||
@ -14,9 +14,29 @@ import datetime
|
|||||||
import re
|
import re
|
||||||
import requests
|
import requests
|
||||||
from config import config
|
from config import config
|
||||||
|
import copy
|
||||||
|
|
||||||
api = Blueprint("api", __name__)
|
api = Blueprint("api", __name__)
|
||||||
|
|
||||||
|
@api.after_request
|
||||||
|
def after_request(response):
|
||||||
|
if response.is_json:
|
||||||
|
session_copy = copy.deepcopy(dict(session))
|
||||||
|
data = response.get_json()
|
||||||
|
data["session"] = serializer.dumps(json.dumps(session_copy))
|
||||||
|
response.set_data(json.dumps(data))
|
||||||
|
return response
|
||||||
|
|
||||||
|
@api.before_request
|
||||||
|
def before_request():
|
||||||
|
authorization = request.headers.get("authorization", None)
|
||||||
|
if authorization:
|
||||||
|
try:
|
||||||
|
data = json.loads(serializer.loads(authorization))
|
||||||
|
session.update(data)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
def parse_emoji(textToParse, guild_id):
|
def parse_emoji(textToParse, guild_id):
|
||||||
guild_emojis = get_guild_emojis(guild_id)
|
guild_emojis = get_guild_emojis(guild_id)
|
||||||
for gemoji in guild_emojis:
|
for gemoji in guild_emojis:
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
from flask import Blueprint, render_template, abort, redirect, url_for, session, request, make_response
|
from flask import Blueprint, render_template, abort, redirect, url_for, session, request, make_response
|
||||||
from flask_babel import gettext
|
from flask_babel import gettext
|
||||||
from titanembeds.utils import check_guild_existance, guild_query_unauth_users_bool, guild_accepts_visitors, guild_unauthcaptcha_enabled, is_int, redisqueue, get_online_embed_user_keys
|
from titanembeds.utils import serializer, check_guild_existance, guild_query_unauth_users_bool, guild_accepts_visitors, guild_unauthcaptcha_enabled, is_int, redisqueue, get_online_embed_user_keys
|
||||||
from titanembeds.oauth import generate_guild_icon_url, generate_avatar_url
|
from titanembeds.oauth import generate_guild_icon_url, generate_avatar_url
|
||||||
from titanembeds.database import db, Guilds, UserCSS, list_disabled_guilds
|
from titanembeds.database import db, Guilds, UserCSS, list_disabled_guilds
|
||||||
from config import config
|
from config import config
|
||||||
import random
|
import random
|
||||||
import json
|
import json
|
||||||
|
import copy
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
embed = Blueprint("embed", __name__)
|
embed = Blueprint("embed", __name__)
|
||||||
@ -104,7 +105,10 @@ def guild_embed(guild_id):
|
|||||||
|
|
||||||
@embed.route("/signin_complete")
|
@embed.route("/signin_complete")
|
||||||
def signin_complete():
|
def signin_complete():
|
||||||
return render_template("signin_complete.html.j2")
|
sess = ""
|
||||||
|
session_copy = copy.deepcopy(dict(session))
|
||||||
|
sess = serializer.dumps(json.dumps(session_copy))
|
||||||
|
return render_template("signin_complete.html.j2", session=sess)
|
||||||
|
|
||||||
@embed.route("/login_discord")
|
@embed.route("/login_discord")
|
||||||
def login_discord():
|
def login_discord():
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from titanembeds.utils import socketio, guild_accepts_visitors, get_client_ipaddr, discord_api, check_user_in_guild, get_guild_channels, update_user_status, guild_webhooks_enabled, redis_store, redisqueue, get_forced_role
|
from titanembeds.utils import serializer, socketio, guild_accepts_visitors, get_client_ipaddr, discord_api, check_user_in_guild, get_guild_channels, update_user_status, guild_webhooks_enabled, redis_store, redisqueue, get_forced_role
|
||||||
from titanembeds.database import db
|
from titanembeds.database import db
|
||||||
from flask_socketio import Namespace, emit, disconnect, join_room, leave_room
|
from flask_socketio import Namespace, emit, disconnect, join_room, leave_room
|
||||||
import functools
|
import functools
|
||||||
@ -17,6 +17,13 @@ class Gateway(Namespace):
|
|||||||
emit('hello', {"gateway_identifier": gateway_identifier})
|
emit('hello', {"gateway_identifier": gateway_identifier})
|
||||||
|
|
||||||
def on_identify(self, data):
|
def on_identify(self, data):
|
||||||
|
authorization = data.get("session", None)
|
||||||
|
if authorization:
|
||||||
|
try:
|
||||||
|
data = json.loads(serializer.loads(authorization))
|
||||||
|
session.update(data)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
guild_id = data["guild_id"]
|
guild_id = data["guild_id"]
|
||||||
if not guild_accepts_visitors(guild_id) and not check_user_in_guild(guild_id):
|
if not guild_accepts_visitors(guild_id) and not check_user_in_guild(guild_id):
|
||||||
disconnect()
|
disconnect()
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
/* global is_peak */
|
/* global is_peak */
|
||||||
/* global cookie_test_s2_URL */
|
/* global cookie_test_s2_URL */
|
||||||
|
|
||||||
|
var passedCookieTest = true; // If passed cross origin test
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
const theme_options = ["DiscordDark", "FireWyvern", "IceWyvern", "MetroEdge", "BetterTitan"]; // All the avaliable theming names
|
const theme_options = ["DiscordDark", "FireWyvern", "IceWyvern", "MetroEdge", "BetterTitan"]; // All the avaliable theming names
|
||||||
const badges_options = ["administrator", "partner", "supporter", "discordbotsorgvoted"]; // All badges avaliable
|
const badges_options = ["administrator", "partner", "supporter", "discordbotsorgvoted"]; // All badges avaliable
|
||||||
@ -58,6 +60,19 @@
|
|||||||
var localstorage_avaliable = false; // Check if localstorage is avaliable on this browser
|
var localstorage_avaliable = false; // Check if localstorage is avaliable on this browser
|
||||||
var shouldUtilizeGateway = false; // Don't connect to gateway until page is focused or has interaction.
|
var shouldUtilizeGateway = false; // Don't connect to gateway until page is focused or has interaction.
|
||||||
var discord_users_list_enabled = false; // Allow automatic population of discord users list
|
var discord_users_list_enabled = false; // Allow automatic population of discord users list
|
||||||
|
var session = ""; // stores the session if cross origin requests are not honored
|
||||||
|
|
||||||
|
function ajax_before_send(jqXHR, settings) {
|
||||||
|
if (session && !passedCookieTest) {
|
||||||
|
jqXHR.setRequestHeader('Authorization', session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function ajax_always(data, textStatus, jqXHR) {
|
||||||
|
if (!passedCookieTest) {
|
||||||
|
session = data.session;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function element_in_view(element, fullyInView) {
|
function element_in_view(element, fullyInView) {
|
||||||
var pageTop = $(window).scrollTop();
|
var pageTop = $(window).scrollTop();
|
||||||
@ -103,8 +118,10 @@
|
|||||||
var funct = $.ajax({
|
var funct = $.ajax({
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
url: url,
|
url: url,
|
||||||
data: {"guild_id": guild_id}
|
beforeSend: ajax_before_send,
|
||||||
|
data: {"guild_id": guild_id},
|
||||||
});
|
});
|
||||||
|
funct.always(ajax_always);
|
||||||
return funct.promise();
|
return funct.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,8 +130,10 @@
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
url: "/api/create_authenticated_user",
|
url: "/api/create_authenticated_user",
|
||||||
|
beforeSend: ajax_before_send,
|
||||||
data: {"guild_id": guild_id}
|
data: {"guild_id": guild_id}
|
||||||
});
|
});
|
||||||
|
funct.always(ajax_always);
|
||||||
return funct.promise();
|
return funct.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,8 +142,10 @@
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
url: "/api/create_unauthenticated_user",
|
url: "/api/create_unauthenticated_user",
|
||||||
|
beforeSend: ajax_before_send,
|
||||||
data: {"username": username, "guild_id": guild_id, "captcha_response": captchaResponse}
|
data: {"username": username, "guild_id": guild_id, "captcha_response": captchaResponse}
|
||||||
});
|
});
|
||||||
|
funct.always(ajax_always);
|
||||||
return funct.promise();
|
return funct.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,8 +154,10 @@
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
url: "/api/change_unauthenticated_username",
|
url: "/api/change_unauthenticated_username",
|
||||||
|
beforeSend: ajax_before_send,
|
||||||
data: {"username": username, "guild_id": guild_id}
|
data: {"username": username, "guild_id": guild_id}
|
||||||
});
|
});
|
||||||
|
funct.always(ajax_always);
|
||||||
return funct.promise();
|
return funct.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,8 +173,10 @@
|
|||||||
method: "GET",
|
method: "GET",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
url: url,
|
url: url,
|
||||||
|
beforeSend: ajax_before_send,
|
||||||
data: {"guild_id": guild_id,"channel_id": channel_id, "after": after}
|
data: {"guild_id": guild_id,"channel_id": channel_id, "after": after}
|
||||||
});
|
});
|
||||||
|
funct.always(ajax_always);
|
||||||
return funct.promise();
|
return funct.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,6 +188,7 @@
|
|||||||
var ajaxobj = {
|
var ajaxobj = {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
|
beforeSend: ajax_before_send,
|
||||||
url: "/api/post"
|
url: "/api/post"
|
||||||
}
|
}
|
||||||
if (file) {
|
if (file) {
|
||||||
@ -198,6 +224,7 @@
|
|||||||
}
|
}
|
||||||
ajaxobj.data = data;
|
ajaxobj.data = data;
|
||||||
var funct = $.ajax(ajaxobj);
|
var funct = $.ajax(ajaxobj);
|
||||||
|
funct.always(ajax_always);
|
||||||
return funct.promise();
|
return funct.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,16 +239,20 @@
|
|||||||
function api_user(user_id) {
|
function api_user(user_id) {
|
||||||
var funct = $.ajax({
|
var funct = $.ajax({
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
|
beforeSend: ajax_before_send,
|
||||||
url: "/api/user/" + guild_id + "/" + user_id,
|
url: "/api/user/" + guild_id + "/" + user_id,
|
||||||
});
|
});
|
||||||
|
funct.always(ajax_always);
|
||||||
return funct.promise();
|
return funct.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
function list_users() {
|
function list_users() {
|
||||||
var funct = $.ajax({
|
var funct = $.ajax({
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
|
beforeSend: ajax_before_send,
|
||||||
url: "/api/user/" + guild_id,
|
url: "/api/user/" + guild_id,
|
||||||
});
|
});
|
||||||
|
funct.always(ajax_always);
|
||||||
return funct.promise();
|
return funct.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,8 +264,10 @@
|
|||||||
var funct = $.ajax({
|
var funct = $.ajax({
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
url: url,
|
url: url,
|
||||||
|
beforeSend: ajax_before_send,
|
||||||
data: {"guild_id": guild_id}
|
data: {"guild_id": guild_id}
|
||||||
});
|
});
|
||||||
|
funct.always(ajax_always);
|
||||||
return funct.promise();
|
return funct.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1999,7 +2032,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#discordlogin_btn").click(function() {
|
$("#discordlogin_btn").click(function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var wid = window.open($("#discordlogin_btn").attr("href"), "_blank");
|
||||||
|
postRobot.on("setSession", { window: wid }, function(event) {
|
||||||
|
if (!passedCookieTest) {
|
||||||
|
session = event.data.session;
|
||||||
|
}
|
||||||
|
});
|
||||||
lock_login_fields();
|
lock_login_fields();
|
||||||
wait_for_discord_login();
|
wait_for_discord_login();
|
||||||
});
|
});
|
||||||
@ -2374,7 +2414,11 @@
|
|||||||
|
|
||||||
socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + "/gateway", {path: '/gateway', transports: ['websocket'], query: "v=1"});
|
socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + "/gateway", {path: '/gateway', transports: ['websocket'], query: "v=1"});
|
||||||
socket.on('connect', function () {
|
socket.on('connect', function () {
|
||||||
socket.emit('identify', {"guild_id": guild_id, "visitor_mode": visitor_mode});
|
var sen = {"guild_id": guild_id, "visitor_mode": visitor_mode};
|
||||||
|
if (!passedCookieTest && session) {
|
||||||
|
sen["session"] = session;
|
||||||
|
}
|
||||||
|
socket.emit('identify', sen);
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('hello', function (msg) {
|
socket.on('hello', function (msg) {
|
||||||
@ -2720,12 +2764,16 @@ window._3rd_party_test_step1_loaded = function () {
|
|||||||
|
|
||||||
window._3rd_party_test_step2_loaded = function (cookieSuccess) {
|
window._3rd_party_test_step2_loaded = function (cookieSuccess) {
|
||||||
if (!cookieSuccess) {
|
if (!cookieSuccess) {
|
||||||
$("#third-party-cookies-notice").show().addClass("done");
|
//$("#third-party-cookies-notice").show().addClass("done");
|
||||||
$("#login-greeting-msg, #loginmodal-maincontent").hide();
|
//$("#login-greeting-msg, #loginmodal-maincontent").hide();
|
||||||
|
passedCookieTest = false;
|
||||||
} else {
|
} else {
|
||||||
$("#third-party-cookies-notice").hide().addClass("done");
|
//$("#third-party-cookies-notice").hide().addClass("done");
|
||||||
$("#login-greeting-msg, #loginmodal-maincontent").show();
|
//$("#login-greeting-msg, #loginmodal-maincontent").show();
|
||||||
|
passedCookieTest = true;
|
||||||
}
|
}
|
||||||
|
$("#third-party-cookies-notice").hide().addClass("done");
|
||||||
|
$("#login-greeting-msg, #loginmodal-maincontent").show();
|
||||||
};
|
};
|
||||||
|
|
||||||
window.setTimeout(function(){
|
window.setTimeout(function(){
|
||||||
|
@ -449,6 +449,7 @@
|
|||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/soundmanager2/2.97a.20150601/script/soundmanager2-nodebug-jsmin.js" integrity="sha256-5KBL+8gS3BkWOs22YOrezN3Djl4pwodgZaPQY9hgu4Y=" crossorigin="anonymous"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/soundmanager2/2.97a.20150601/script/soundmanager2-nodebug-jsmin.js" integrity="sha256-5KBL+8gS3BkWOs22YOrezN3Djl4pwodgZaPQY9hgu4Y=" crossorigin="anonymous"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.3/es6-shim.min.js" integrity="sha256-THlgZSjqt7idNSdnUvGypTuXB5C4hV9kSuPYrbiq19o=" crossorigin="anonymous"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.3/es6-shim.min.js" integrity="sha256-THlgZSjqt7idNSdnUvGypTuXB5C4hV9kSuPYrbiq19o=" crossorigin="anonymous"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/caret/1.0.0/jquery.caret.min.js" integrity="sha256-NfP6KWI/oETcPbLcLXVAamn8K2wJrYH8ZIRrOf1XNUE=" crossorigin="anonymous"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/caret/1.0.0/jquery.caret.min.js" integrity="sha256-NfP6KWI/oETcPbLcLXVAamn8K2wJrYH8ZIRrOf1XNUE=" crossorigin="anonymous"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/post-robot/10.0.42/post-robot.min.js" integrity="sha512-8rkatbA3uOONyiRqBiT5dvzaE7hWX6m0SpVr/4rpAxxuZX+Vjuvqp+DSmF1sQX3268hMk8BZxHVRdgHmuoDhXQ==" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script src="{{ url_for("static", filename="js/vendor/highlight.pack.js") }}"></script>
|
<script src="{{ url_for("static", filename="js/vendor/highlight.pack.js") }}"></script>
|
||||||
<script src="{{ url_for("static", filename="js/vendor/jquery.balloon.min.js") }}"></script>
|
<script src="{{ url_for("static", filename="js/vendor/jquery.balloon.min.js") }}"></script>
|
||||||
|
@ -5,8 +5,14 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<p>Sign in complete! You may now close the window.</p>
|
<p>Sign in complete! You may now close the window.</p>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/post-robot/10.0.42/post-robot.min.js" integrity="sha512-8rkatbA3uOONyiRqBiT5dvzaE7hWX6m0SpVr/4rpAxxuZX+Vjuvqp+DSmF1sQX3268hMk8BZxHVRdgHmuoDhXQ==" crossorigin="anonymous"></script>
|
||||||
<script>
|
<script>
|
||||||
window.close()
|
const session = {{ session|tojson|safe }};
|
||||||
|
postRobot
|
||||||
|
.send(window.opener, 'setSession', { session: session })
|
||||||
|
.then(function () {
|
||||||
|
window.close();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -7,6 +7,7 @@ from flask_babel import Babel
|
|||||||
from flask_redis import FlaskRedis
|
from flask_redis import FlaskRedis
|
||||||
from config import config
|
from config import config
|
||||||
from sqlalchemy import and_
|
from sqlalchemy import and_
|
||||||
|
from itsdangerous import URLSafeSerializer
|
||||||
#from raven.contrib.flask import Sentry
|
#from raven.contrib.flask import Sentry
|
||||||
import random
|
import random
|
||||||
import string
|
import string
|
||||||
@ -22,6 +23,8 @@ from titanembeds.redisqueue import RedisQueue
|
|||||||
discord_api = DiscordREST(config['bot-token'])
|
discord_api = DiscordREST(config['bot-token'])
|
||||||
redisqueue = RedisQueue()
|
redisqueue = RedisQueue()
|
||||||
|
|
||||||
|
serializer = URLSafeSerializer(config["app-secret"])
|
||||||
|
|
||||||
def get_client_ipaddr():
|
def get_client_ipaddr():
|
||||||
if request.headers.getlist("X-Forwarded-For"):
|
if request.headers.getlist("X-Forwarded-For"):
|
||||||
ip = request.headers.getlist("X-Forwarded-For")[0]
|
ip = request.headers.getlist("X-Forwarded-For")[0]
|
||||||
|
Loading…
Reference in New Issue
Block a user