Merge branch 'main' of github.com:openreplay/openreplay into main

This commit is contained in:
ShiKhu 2021-05-10 12:32:10 +02:00
commit eb0244da8d
61 changed files with 322 additions and 251 deletions

View file

@ -14,15 +14,15 @@
"isFOS": "true",
"isEE": "false",
"stage": "default-fos",
"jwt_issuer": "asayer-default-fos",
"jwt_issuer": "openreplay-default-fos",
"allowCron": "true",
"sentry": "false",
"sentryURL": "",
"pg_host": "",
"pg_host": "postgresql.db.svc.cluster.local",
"pg_port": "5432",
"pg_dbname": "",
"pg_user": "",
"pg_password": "",
"pg_dbname": "postgres",
"pg_user": "postgres",
"pg_password": "asayerPostgres",
"alert_ntf": "http://127.0.0.1:8000/async/alerts/notifications/%s",
"email_signup": "http://127.0.0.1:8000/async/email_signup/%s",
"email_funnel": "http://127.0.0.1:8000/async/funnel/%s",
@ -44,7 +44,6 @@
"sourcemaps_bucket_secret": "",
"sourcemaps_bucket_region": "",
"js_cache_bucket": "",
"web_mobs": "https://mobs-staging.asayer.io",
"async_Token": "",
"EMAIL_HOST": "",
"EMAIL_PORT": "587",
@ -56,10 +55,13 @@
"EMAIL_SSL_CERT": "",
"EMAIL_FROM": "OpenReplay<do-not-reply@openreplay.com>",
"SITE_URL": "",
"announcement_bucket": "",
"announcement_url": "",
"jwt_secret": "",
"jwt_algorithm": "HS512",
"jwt_exp_delta_seconds": "2592000"
"jwt_exp_delta_seconds": "2592000",
"S3_HOST": "",
"S3_KEY": "",
"S3_SECRET": ""
},
"lambda_timeout": 150,
"lambda_memory_size": 400,

View file

@ -13,4 +13,4 @@ ENV ENTERPRISE_BUILD ${envarg}
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
RUN chmod +x /tini
ENTRYPOINT ["/tini", "--"]
CMD chalice local --no-autoreload --host 0.0.0.0 --stage ${ENTERPRISE_BUILD}
CMD python env_handler.py && chalice local --no-autoreload --host 0.0.0.0 --stage ${ENTERPRISE_BUILD}

View file

@ -55,7 +55,7 @@ sys.stderr = F()
_overrides.chalice_app(app)
# v0505
# v0905
@app.middleware('http')
def asayer_middleware(event, get_response):
global ASAYER_SESSION_ID

View file

@ -13,7 +13,7 @@ base_time = datetime.now(pytz.utc)
cors_config = CORSConfig(
allow_origin='*',
allow_headers=['vnd.asayer.io.sid'],
allow_headers=['vnd.openreplay.com.sid'],
# max_age=600,
# expose_headers=['X-Special-Header'],
allow_credentials=True

View file

@ -22,7 +22,7 @@ def get_all(user_id):
for a in announcements:
a["createdAt"] = TimeUTC.datetime_to_timestamp(a["createdAt"])
if a["imageUrl"] is not None and len(a["imageUrl"]) > 0:
a["imageUrl"] = environ["announcement_bucket"] + a["imageUrl"]
a["imageUrl"] = environ["announcement_url"] + a["imageUrl"]
return announcements

View file

@ -40,20 +40,20 @@ def get_state(tenant_id):
meta = cur.fetchone()["sum"] > 0
return [
{"task": "Install Asayer",
{"task": "Install OpenReplay",
"done": recorded,
"URL": "https://docs.asayer.io/getting-started/quick-start"},
"URL": "https://docs.openreplay.com/getting-started/quick-start"},
{"task": "Identify Users",
"done": meta,
"URL": "https://docs.asayer.io/data-privacy-security/metadata"},
"URL": "https://docs.openreplay.com/data-privacy-security/metadata"},
{"task": "Invite Team Members",
"done": len(users.get_members(tenant_id=tenant_id)) > 1,
"URL": "https://app.asayer.io/client/manage-users"},
"URL": "https://app.openreplay.com/client/manage-users"},
{"task": "Integrations",
"done": len(log_tool_datadog.get_all(tenant_id=tenant_id)) > 0 \
or len(log_tool_sentry.get_all(tenant_id=tenant_id)) > 0 \
or len(log_tool_stackdriver.get_all(tenant_id=tenant_id)) > 0,
"URL": "https://docs.asayer.io/integrations"}
"URL": "https://docs.openreplay.com/integrations"}
]
@ -75,9 +75,9 @@ def get_state_installing(tenant_id):
)
recorded = cur.fetchone()["count"] > 0
return {"task": "Install Asayer",
return {"task": "Install OpenReplay",
"done": recorded,
"URL": "https://docs.asayer.io/getting-started/quick-start"}
"URL": "https://docs.openreplay.com/getting-started/quick-start"}
def get_state_identify_users(tenant_id):
@ -99,13 +99,13 @@ def get_state_identify_users(tenant_id):
return {"task": "Identify Users",
"done": meta,
"URL": "https://docs.asayer.io/data-privacy-security/metadata"}
"URL": "https://docs.openreplay.com/data-privacy-security/metadata"}
def get_state_manage_users(tenant_id):
return {"task": "Invite Team Members",
"done": len(users.get_members(tenant_id=tenant_id)) > 1,
"URL": "https://app.asayer.io/client/manage-users"}
"URL": "https://app.openreplay.com/client/manage-users"}
def get_state_integrations(tenant_id):
@ -113,4 +113,4 @@ def get_state_integrations(tenant_id):
"done": len(log_tool_datadog.get_all(tenant_id=tenant_id)) > 0 \
or len(log_tool_sentry.get_all(tenant_id=tenant_id)) > 0 \
or len(log_tool_stackdriver.get_all(tenant_id=tenant_id)) > 0,
"URL": "https://docs.asayer.io/integrations"}
"URL": "https://docs.openreplay.com/integrations"}

View file

@ -503,8 +503,8 @@ def search(data, project_id, user_id, flows=False, status="ALL", favorite_only=F
GROUP BY timestamp
ORDER BY timestamp) AS chart_details) AS chart_details ON (TRUE);"""
print("--------------------")
print(cur.mogrify(main_pg_query, params))
# print("--------------------")
# print(cur.mogrify(main_pg_query, params))
cur.execute(cur.mogrify(main_pg_query, params))
total = cur.rowcount
if flows:

View file

@ -41,7 +41,7 @@ class GithubIntegrationIssue(BaseIntegrationIssue):
if a == str(u["id"]):
real_assignees.append(u["login"])
break
real_labels = ["Asayer"]
real_labels = ["OpenReplay"]
for l in labels:
found = False
for ll in metas["issueTypes"]:

View file

@ -16,7 +16,7 @@ class JIRACloudIntegrationIssue(BaseIntegrationIssue):
'description': description,
'issuetype': {'id': issue_type},
'assignee': {"id": assignee},
"labels": ["Asayer"]
"labels": ["OpenReplay"]
}
return self._client.create_issue(data)
@ -30,7 +30,7 @@ class JIRACloudIntegrationIssue(BaseIntegrationIssue):
results = []
for integration_project_id in projects_map:
self._client.set_jira_project_id(integration_project_id)
jql = 'labels = Asayer'
jql = 'labels = OpenReplay'
if len(projects_map[integration_project_id]) > 0:
jql += f" AND ID IN ({','.join(projects_map[integration_project_id])})"
issues = self._client.get_issues(jql, offset=0)

View file

@ -47,7 +47,7 @@ def __find_events(client, log_group, streams, last_token, start_time, end_time):
"startTime": start_time,
"endTime": end_time,
"limit": 10000,
"filterPattern": "asayer_session_id"
"filterPattern": "openreplay_session_id"
}
if last_token is not None:
f_args["nextToken"] = last_token

View file

@ -1,11 +1,9 @@
from chalicelib.utils import pg_client, helper
from chalicelib.core import events, sessions_metas, socket_ios, metadata, events_ios, \
sessions_mobs
from chalicelib.utils import dev
from chalicelib.core import events, sessions_metas, socket_ios, metadata, events_ios, sessions_mobs
if helper.is_free_open_source_edition():
from chalicelib.core import projects, errors
else:
from chalicelib.ee import projects, errors
from chalicelib.core import projects, errors
from chalicelib.core import resources

View file

@ -56,8 +56,13 @@ def create_step1(data):
project_name = data.get("projectName")
if project_name is None or len(project_name) < 1:
project_name = "my first project"
if len(get_signed_ups()) > 0 and data.get("tenantId") is None:
signed_ups = get_signed_ups()
if len(signed_ups) > 0 and data.get("tenantId") is None:
errors.append("Tenant already exists, please select it from dropdown")
elif len(signed_ups) == 0 and data.get("tenantId") is not None \
or len(signed_ups) > 0 and data.get("tenantId") not in [t['tenantId'] for t in signed_ups]:
errors.append("Tenant does not exist")
if len(errors) > 0:
print("==> error")
print(errors)

View file

@ -30,7 +30,7 @@ def compute():
RETURNING *,(SELECT email FROM public.users WHERE role='owner' LIMIT 1);"""
)
data = cur.fetchone()
requests.post('https://parrot.asayer.io/os/telemetry', json=process_data(data))
requests.post('https://parrot.openreplay.com/os/telemetry', json=process_data(data))
def new_client():
@ -40,4 +40,4 @@ def new_client():
(SELECT email FROM public.users WHERE role='owner' LIMIT 1) AS email
FROM public.tenants;""")
data = cur.fetchone()
requests.post('https://parrot.asayer.io/os/signup', json=process_data(data))
requests.post('https://parrot.openreplay.com/os/signup', json=process_data(data))

View file

@ -21,7 +21,7 @@ def timed(f):
'handle_request', '_generic_handle', 'handle', '_bootstrap_inner', 'run',
'_bootstrap', '_main_rest_api_handler', '_user_handler',
'_get_view_function_response', 'wrapped_event', 'handle_one_request',
'_global_error_handler', 'asayer_middleware']]
'_global_error_handler', 'openreplay_middleware']]
print("DEBUG: %s > %s took %d s to finish" % (" > ".join(call_stack), f.__name__, elapsed))
return result

View file

@ -7,7 +7,7 @@ def send_team_invitation(recipient, user_name, temp_password, client_id, sender_
formatting_variables={"userName": __escape_text_html(user_name),
"password": temp_password, "clientId": client_id,
"sender": sender_name})
SUBJECT = "Welcome to Asayer"
SUBJECT = "Welcome to OpenReplay"
send_html(BODY_HTML, SUBJECT, recipient)
@ -115,5 +115,5 @@ def weekly_report2(recipients, data):
</table>
</td>"""
BODY_HTML = __get_html_from_file("chalicelib/utils/html/Project-Weekly-Report.html", formatting_variables=data)
SUBJECT = "Asayer Project Weekly Report"
SUBJECT = "OpenReplay Project Weekly Report"
send_html(BODY_HTML=BODY_HTML, SUBJECT=SUBJECT, recipient=recipients)

View file

@ -42,7 +42,7 @@ class github_formatters:
'createdAt': github_formatters.get_timestamp(issue["created_at"]),
'closed': issue["closed_at"] is not None,
'commentsCount': issue["comments"],
'issueType': [str(l["id"]) for l in labels if l["name"].lower() != "asayer"],
'issueType': [str(l["id"]) for l in labels if l["name"].lower() != "openreplay"],
'labels': [l["name"] for l in labels]
}
return result

View file

@ -40,17 +40,6 @@ def generate_salt():
return "".join(random.choices(string.hexdigits, k=36))
def remove_empty_none_values(dictionary):
aux = {}
for key in dictionary.keys():
if dictionary[key] is not None:
if isinstance(dictionary[key], dict):
aux[key] = remove_empty_none_values(dictionary[key])
elif not isinstance(dictionary[key], str) or len(dictionary[key]) > 0:
aux[key] = dictionary[key]
return aux
def unique_ordered_list(array):
uniq = []
[uniq.append(x) for x in array if x not in uniq]

View file

@ -11,7 +11,7 @@
<table style="width:100%;font-weight:300;margin-bottom:0;border-collapse:collapse">
<tbody><tr style="font-weight:300">
<td width="125px" style="font-size:14px;padding:0;font-weight:300;margin:0;text-align:left">
<a href="%(frontend_url)s" style="color:#394EFF;font-weight:300;text-decoration:none" target="_blank" data-saferedirecturl="" width="125px" height="29px" alt="asayer" style="font-weight:300"><img src="img/weekly/asayer-logo.png" style="width: 160px;"></a>
<a href="%(frontend_url)s" style="color:#394EFF;font-weight:300;text-decoration:none" target="_blank" data-saferedirecturl="" width="125px" height="29px" alt="openreplay" style="font-weight:300"><img src="img/weekly/logo.png" style="width: 160px;"></a>
</td>
<td style="font-size:14px;padding:0;font-weight:300;margin:0;text-align:right">
<table style="width:100%;font-weight:300;margin-bottom:0;border-collapse:collapse">
@ -154,7 +154,7 @@
<div style="padding:10px 20px;max-width:600px;font-weight:300;margin:0 auto;text-align:left">
<div style="padding:35px 0;border-top:1px solid #e7ebee;font-weight:300; font-size: 13px;">
<a href="%(frontend_url)s/%(project_id)s/metrics" style="color:#394EFF;float:right;font-weight:300;text-decoration:none" target="_blank" data-saferedirecturl="#">Asayer Metrics</a>
<a href="%(frontend_url)s/%(project_id)s/metrics" style="color:#394EFF;float:right;font-weight:300;text-decoration:none" target="_blank" data-saferedirecturl="#">OpenReplay Metrics</a>
<a href="%(frontend_url)s/client/notifications" style="color:#394EFF;font-weight:300;text-decoration:none" target="_blank" data-saferedirecturl="#">Manage Notifications</a>

View file

@ -11,7 +11,7 @@
<tr>
<td style="padding:10px 30px;">
<center>
<img src="img/asayer-logo.png" alt="Asayer" width="100%" style="max-width: 120px;">
<img src="img/logo.png" alt="OpenReplay" width="100%" style="max-width: 120px;">
</center>
</td>
</tr>
@ -38,9 +38,9 @@
<div style="border-top:1px dotted rgba(0,0,0,0.2); display: block; margin-top: 20px"></div>
<center>
<p style="font-size: 12px; font-family: -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,'Helvetica Neue',sans-serif; color: #6c757d">
Sent with &#9825; from Asayer &copy; 2021 - All rights reserved.<br><br>
<a href="https://asayer.io" target="_blank"
style="text-decoration: none; color: #6c757d">https://asayer.io/</a>
Sent with &#9825; from OpenReplay &copy; 2021 - All rights reserved.<br><br>
<a href="https://openreplay.com" target="_blank"
style="text-decoration: none; color: #6c757d">https://openreplay.com/</a>
</p>
</center>

View file

@ -385,7 +385,7 @@ width: 25%!important
<td style="padding-right: 0px;padding-left: 0px;" align="center">
<![endif]-->
<img style="width=124px; height=35px;" width="124px" height="35px"
src="img/asayer-logo.png"/>
src="img/logo.png"/>
<!--[if mso]></td></tr></table><![endif]-->
</div>
@ -401,7 +401,7 @@ width: 25%!important
<div style="color:#555555;font-family:'Helvetica Neue', Helvetica, Arial, sans-serif;line-height:120%;padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:10px;">
<div style="font-size: 12px; line-height: 14px; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: #555555;">
<!-- <p style="font-size: 18px; line-height: 21px; text-align: center; margin: 0;">
<span style="font-size: 18px;">Welcome to Asayer!</span>
<span style="font-size: 18px;">Welcome to OpenReplay!</span>
</p>-->
<h1 style="text-align: center; margin-top: 30px; line-height: 30px">Assigned session</h1>
@ -514,10 +514,10 @@ width: 25%!important
<div style="color:#555555;font-family:-apple-system,BlinkMacSystemFont,'Helvetica Neue','Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,sans-serif;line-height:120%;padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:10px;">
<div style="font-size: 12px; line-height: 14px; color: #555555; font-family: -apple-system,BlinkMacSystemFont,'Helvetica Neue','Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,sans-serif;">
<p style="font-size: 14px; line-height: 16px; text-align: center; margin: 0;">
<a href="mailto:support@asayer.io?subject=[User Invite] - Reporting issue"
<a href="mailto:support@openreplay.com?subject=[User Invite] - Reporting issue"
style="text-decoration: underline; color: #009193;"
title="support@asayer.io">Report an issue</a> | <a
href="https://asayer.io/" rel="noopener"
title="support@openreplay.com">Report an issue</a> | <a
href="https://openreplay.com/" rel="noopener"
style="text-decoration: underline; color: #009193;" target="_blank">Take
a tour</a></p>
</div>

View file

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View file

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -378,7 +378,7 @@ width: 25%!important
<tr style="line-height:0px">
<td style="padding-right: 0px;padding-left: 0px;" align="center">
<![endif]-->
<img style="width=124px; height=35px;" width="124px" height="35px" src="img/asayer-logo.png"/>
<img style="width=124px; height=35px;" width="124px" height="35px" src="img/logo.png"/>
<!--[if mso]></td></tr></table><![endif]-->
</div>
@ -394,7 +394,7 @@ width: 25%!important
<div style="color:#555555;font-family:'Helvetica Neue', Helvetica, Arial, sans-serif;line-height:120%;padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:10px;">
<div style="font-size: 12px; line-height: 14px; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: #555555;">
<p style="font-size: 14px; line-height: 21px; text-align: center; margin: 0;">
<span style="font-size: 18px;"><strong>Welcome to Asayer!</strong></span>
<span style="font-size: 18px;"><strong>Welcome to OpenReplay!</strong></span>
</p>
</div>
</div>
@ -407,7 +407,7 @@ width: 25%!important
<div style="color:#555555;font-family:-apple-system,BlinkMacSystemFont,'Helvetica Neue','Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,sans-serif;line-height:120%;padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:10px;">
<div style="font-size: 12px; line-height: 14px; color: #555555; font-family: -apple-system,BlinkMacSystemFont,'Helvetica Neue','Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,sans-serif;">
<p style="font-size: 12px; line-height: 16px; text-align: center; margin: 0;">
<span style="font-size: 14px;">You have been invited by %(sender)s to join %(clientId)s team on Asayer.</span>
<span style="font-size: 14px;">You have been invited by %(sender)s to join %(clientId)s team on OpenReplay.</span>
</p>
</div>
</div>
@ -450,7 +450,7 @@ width: 25%!important
<span style="font-size: 18px;"><a href="%(frontend_url)s"
rel="noopener"
style="text-decoration: underline; color: #009193;"
target="_blank" title="Asayer Login">%(frontend_url)s</a></span><span
target="_blank" title="OpenReplay Login">%(frontend_url)s</a></span><span
style="font-size: 18px; line-height: 21px;"></span></p>
</div>
</div>
@ -553,10 +553,10 @@ width: 25%!important
<div style="color:#555555;font-family:-apple-system,BlinkMacSystemFont,'Helvetica Neue','Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,sans-serif;line-height:120%;padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:10px;">
<div style="font-size: 12px; line-height: 14px; color: #555555; font-family: -apple-system,BlinkMacSystemFont,'Helvetica Neue','Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,sans-serif;">
<p style="font-size: 14px; line-height: 16px; text-align: center; margin: 0;">
<a href="mailto:support@asayer.io?subject=[User Invite] - Reporting issue"
<a href="mailto:support@openreplay.com?subject=[User Invite] - Reporting issue"
style="text-decoration: underline; color: #009193;"
title="support@asayer.io">Report an issue</a> | <a
href="https://asayer.io/" rel="noopener"
title="support@openreplay.com">Report an issue</a> | <a
href="https://openreplay.com/" rel="noopener"
style="text-decoration: underline; color: #009193;" target="_blank">Take
a tour</a></p>
</div>

View file

@ -385,7 +385,7 @@ width: 25%!important
<td style="padding-right: 0px;padding-left: 0px;" align="center">
<![endif]-->
<img style="width=124px; height=35px;" width="124px" height="35px"
src="img/asayer-logo.png"/>
src="img/logo.png"/>
<!--[if mso]></td></tr></table><![endif]-->
</div>

View file

@ -1,9 +1,15 @@
from botocore.exceptions import ClientError
from chalicelib.utils.helper import environ
import boto3
client = boto3.client('s3')
sts_client = boto3.client('sts')
from botocore.client import Config
client = boto3.client('s3', endpoint_url=environ["S3_HOST"],
aws_access_key_id=environ["S3_KEY"],
aws_secret_access_key=environ["S3_SECRET"],
config=Config(signature_version='s3v4'),
region_name='us-east-1')
def exists(bucket, key):

17
api/env_handler.py Normal file
View file

@ -0,0 +1,17 @@
from os import environ
import json
with open('.chalice/config.json') as json_file:
data = json.load(json_file)
stages = data.get("stages", {})
for s in stages.keys():
target = f'chalicelib/.configs/{stages[s].get("environment_variables", {}).get("stage", s)}.json'
data = {}
try:
with open(target) as stage_vars:
data = json.load(stage_vars)
except IOError:
pass
with open(target, 'w') as outfile:
json.dump({**data, **environ}, outfile, indent=2, sort_keys=True)
print(f"injected env-vars to {target}")

View file

@ -6,7 +6,7 @@ With regard to the OpenReplay Software:
This software and associated documentation files (the "Software") may only be
used in production, if you (and any entity that you represent) have agreed to,
and are in compliance with, the OpenReplay Subscription Terms of Service, available
at https://openreplay.com/terms.html (the “Enterprise Terms”), or other
at https://openreplay.com/terms.html (the “Enterprise Edition”), or other
agreement governing the use of the Software, as agreed by you and OpenReplay,
and otherwise have a valid OpenReplay Enterprise license for the
correct volume and number of seats. Subject to the foregoing sentence, you are free to

View file

@ -14,7 +14,7 @@
"isFOS": "false",
"isEE": "true",
"stage": "default-ee",
"jwt_issuer": "asayer-default-ee",
"jwt_issuer": "openreplay-default-ee",
"allowCron": "true",
"sentry": "false",
"sentryURL": "",
@ -49,7 +49,6 @@
"js_cache_bucket": "",
"SIGN_ID": "",
"SIGN_KEY": "",
"web_mobs": "https://mobs-staging.asayer.io",
"async_Token": "",
"EMAIL_HOST": "",
"EMAIL_PORT": "587",
@ -61,10 +60,13 @@
"EMAIL_SSL_CERT": "",
"EMAIL_FROM": "OpenReplay<do-not-reply@openreplay.com>",
"SITE_URL": "",
"announcement_bucket": "",
"announcement_url": "",
"jwt_secret": "",
"jwt_algorithm": "",
"jwt_exp_delta_seconds": ""
"jwt_exp_delta_seconds": "",
"S3_HOST": "",
"S3_KEY": "",
"S3_SECRET": ""
},
"lambda_timeout": 150,
"lambda_memory_size": 400,

View file

@ -60,6 +60,9 @@ _overrides.chalice_app(app)
@app.middleware('http')
def asayer_middleware(event, get_response):
from chalicelib.ee import unlock
if not unlock.is_valid():
return Response(body={"errors": ["expired license"]}, status_code=403)
if "{projectid}" in event.path.lower():
from chalicelib.ee import projects
if not projects.is_authorized(project_id=event.uri_params["projectId"],

View file

@ -13,7 +13,7 @@ base_time = datetime.now(pytz.utc)
cors_config = CORSConfig(
allow_origin='*',
allow_headers=['vnd.asayer.io.sid'],
allow_headers=['vnd.openreplay.com.sid'],
# max_age=600,
# expose_headers=['X-Special-Header'],
allow_credentials=True

View file

@ -5,9 +5,14 @@ from chalicelib.utils import helper
app = Blueprint(__name__)
_overrides.chalice_app(app)
from chalicelib.ee import telemetry
from chalicelib.ee import unlock
# Run every day.
@app.schedule(Cron('0', '0', '?', '*', '*', '*'))
def telemetry_cron(event):
telemetry.compute()
@app.schedule(Cron('0/60', '*', '*', '*', '?', '*'))
def unlock_cron(event):
unlock.check()

View file

@ -1,6 +1,9 @@
from chalice import Blueprint
from chalicelib import _overrides
from chalicelib.ee import unlock
app = Blueprint(__name__)
_overrides.chalice_app(app)
unlock.check()

View file

@ -22,7 +22,7 @@ def get_all(user_id):
for a in announcements:
a["createdAt"] = TimeUTC.datetime_to_timestamp(a["createdAt"])
if a["imageUrl"] is not None and len(a["imageUrl"]) > 0:
a["imageUrl"] = environ["announcement_bucket"] + a["imageUrl"]
a["imageUrl"] = environ["announcement_url"] + a["imageUrl"]
return announcements

View file

@ -41,7 +41,7 @@ class GithubIntegrationIssue(BaseIntegrationIssue):
if a == str(u["id"]):
real_assignees.append(u["login"])
break
real_labels = ["Asayer"]
real_labels = ["OpenReplay"]
for l in labels:
found = False
for ll in metas["issueTypes"]:

View file

@ -16,7 +16,7 @@ class JIRACloudIntegrationIssue(BaseIntegrationIssue):
'description': description,
'issuetype': {'id': issue_type},
'assignee': {"id": assignee},
"labels": ["Asayer"]
"labels": ["OpenReplay"]
}
return self._client.create_issue(data)
@ -30,7 +30,7 @@ class JIRACloudIntegrationIssue(BaseIntegrationIssue):
results = []
for integration_project_id in projects_map:
self._client.set_jira_project_id(integration_project_id)
jql = 'labels = Asayer'
jql = 'labels = OpenReplay'
if len(projects_map[integration_project_id]) > 0:
jql += f" AND ID IN ({','.join(projects_map[integration_project_id])})"
issues = self._client.get_issues(jql, offset=0)

View file

@ -47,7 +47,7 @@ def __find_events(client, log_group, streams, last_token, start_time, end_time):
"startTime": start_time,
"endTime": end_time,
"limit": 10000,
"filterPattern": "asayer_session_id"
"filterPattern": "openreplay_session_id"
}
if last_token is not None:
f_args["nextToken"] = last_token

View file

@ -1,43 +0,0 @@
from chalicelib.utils import pg_client
import requests
def process_data(data, edition='fos'):
return {
'edition': edition,
'tracking': data["opt_out"],
'version': data["version_number"],
'user_id': data["user_id"],
'owner_email': None if data["opt_out"] else data["email"],
'organization_name': None if data["opt_out"] else data["name"],
'users_count': data["t_users"],
'projects_count': data["t_projects"],
'sessions_count': data["t_sessions"],
'integrations_count': data["t_integrations"]
}
def compute():
with pg_client.PostgresClient() as cur:
cur.execute(
f"""UPDATE public.tenants
SET t_integrations = COALESCE((SELECT COUNT(DISTINCT provider) FROM public.integrations) +
(SELECT COUNT(*) FROM public.webhooks WHERE type = 'slack') +
(SELECT COUNT(*) FROM public.jira_cloud), 0),
t_projects=COALESCE((SELECT COUNT(*) FROM public.projects WHERE deleted_at ISNULL), 0),
t_sessions=COALESCE((SELECT COUNT(*) FROM public.sessions), 0),
t_users=COALESCE((SELECT COUNT(*) FROM public.users WHERE deleted_at ISNULL), 0)
RETURNING *,(SELECT email FROM public.users WHERE role='owner' LIMIT 1);"""
)
data = cur.fetchone()
requests.post('https://parrot.asayer.io/os/telemetry', json=process_data(data))
def new_client():
with pg_client.PostgresClient() as cur:
cur.execute(
f"""SELECT *,
(SELECT email FROM public.users WHERE role='owner' LIMIT 1) AS email
FROM public.tenants;""")
data = cur.fetchone()
requests.post('https://parrot.asayer.io/os/signup', json=process_data(data))

View file

@ -43,20 +43,20 @@ def get_state(tenant_id):
meta = cur.fetchone()["sum"] > 0
return [
{"task": "Install Asayer",
{"task": "Install OpenReplay",
"done": recorded,
"URL": "https://docs.asayer.io/getting-started/quick-start"},
"URL": "https://docs.openreplay.com/getting-started/quick-start"},
{"task": "Identify Users",
"done": meta,
"URL": "https://docs.asayer.io/data-privacy-security/metadata"},
"URL": "https://docs.openreplay.com/data-privacy-security/metadata"},
{"task": "Invite Team Members",
"done": len(users.get_members(tenant_id=tenant_id)) > 1,
"URL": "https://app.asayer.io/client/manage-users"},
"URL": "https://app.openreplay.com/client/manage-users"},
{"task": "Integrations",
"done": len(log_tool_datadog.get_all(tenant_id=tenant_id)) > 0 \
or len(log_tool_sentry.get_all(tenant_id=tenant_id)) > 0 \
or len(log_tool_stackdriver.get_all(tenant_id=tenant_id)) > 0,
"URL": "https://docs.asayer.io/integrations"}
"URL": "https://docs.openreplay.com/integrations"}
]
@ -78,9 +78,9 @@ def get_state_installing(tenant_id):
)
recorded = cur.fetchone()["count"] > 0
return {"task": "Install Asayer",
return {"task": "Install OpenReplay",
"done": recorded,
"URL": "https://docs.asayer.io/getting-started/quick-start"}
"URL": "https://docs.openreplay.com/getting-started/quick-start"}
def get_state_identify_users(tenant_id):
@ -104,13 +104,13 @@ def get_state_identify_users(tenant_id):
return {"task": "Identify Users",
"done": meta,
"URL": "https://docs.asayer.io/data-privacy-security/metadata"}
"URL": "https://docs.openreplay.com/data-privacy-security/metadata"}
def get_state_manage_users(tenant_id):
return {"task": "Invite Team Members",
"done": len(users.get_members(tenant_id=tenant_id)) > 1,
"URL": "https://app.asayer.io/client/manage-users"}
"URL": "https://app.openreplay.com/client/manage-users"}
def get_state_integrations(tenant_id):
@ -118,4 +118,4 @@ def get_state_integrations(tenant_id):
"done": len(log_tool_datadog.get_all(tenant_id=tenant_id)) > 0 \
or len(log_tool_sentry.get_all(tenant_id=tenant_id)) > 0 \
or len(log_tool_stackdriver.get_all(tenant_id=tenant_id)) > 0,
"URL": "https://docs.asayer.io/integrations"}
"URL": "https://docs.openreplay.com/integrations"}

View file

@ -8,12 +8,9 @@ from chalicelib.utils.TimeUTC import TimeUTC
def get_signed_ups():
with pg_client.PostgresClient() as cur:
query = cur.mogrify(f"SELECT tenant_id, name FROM public.tenants;")
cur.execute(
query
)
cur.execute("SELECT tenant_id, name FROM public.tenants;")
rows = cur.fetchall()
return {"data": helper.list_to_camel_case(rows)}
return helper.list_to_camel_case(rows)
def create_step1(data):
@ -48,15 +45,19 @@ def create_step1(data):
errors.append("Invalid full name.")
print("Verifying company's name validity")
company_name = data.get("companyName")
company_name = data.get("organizationName")
if company_name is None or len(company_name) < 1 or not helper.is_alphanumeric_space(company_name):
errors.append("invalid company's name")
errors.append("invalid organization's name")
print("Verifying project's name validity")
project_name = data.get("projectName")
if project_name is None or len(project_name) < 1:
project_name = "my first project"
signed_ups = get_signed_ups()
if len(signed_ups) == 0 and data.get("tenantId") is not None \
or len(signed_ups) > 0 and data.get("tenantId") not in [t['tenantId'] for t in signed_ups]:
errors.append("Tenant does not exist")
if len(errors) > 0:
print("==> error")
print(errors)
@ -64,64 +65,95 @@ def create_step1(data):
print("No errors detected")
print("Decomposed infos")
tenant_id = data.get("tenantId")
params = {"email": email, "password": password,
"fullname": fullname, "companyName": company_name,
"projectName": project_name,
"versionNumber": "0.0.0",
"data": json.dumps({"lastAnnouncementView": TimeUTC.now()})}
if tenant_id is not None:
with pg_client.PostgresClient() as cur:
print("Starting ACID insert")
query = cur.mogrify(f"""\
WITH t AS (
UPDATE public.tenants
SET name = %(companyName)s,
version_number = %(versionNumber)s,
licence = %(licence)s
WHERE tenant_id=%(tenant_id)s
),
u AS (
UPDATE public.users
SET email = %(email)s,
name = %(fullname)s,
WHERE role ='owner' AND tenant_id=%(tenant_id)s
RETURNING user_id,email, role, name
)
UPDATE public.basic_authentication
SET password= crypt(%(password)s, gen_salt('bf', 12))
WHERE user_id = (SELECT user_id FROM u)
RETURNING %(tenant_id)s AS tenant_id""",
{"email": email, "password": password,
"fullname": fullname, "companyName": company_name,
"projectName": project_name,
"tenant_id": tenant_id})
cur.execute(
query
)
data = cur.fetchone()
query = """\
WITH t AS (
UPDATE public.tenants
SET name = %(companyName)s,
version_number = %(versionNumber)s,
licence = %(licence)s
WHERE tenant_id=%(tenant_id)s
RETURNING tenant_id, api_key
),
u AS (
UPDATE public.users
SET email = %(email)s,
name = %(fullname)s,
WHERE role ='owner' AND tenant_id=%(tenant_id)s
RETURNING user_id,email, role, name
)
UPDATE public.basic_authentication
SET password= crypt(%(password)s, gen_salt('bf', 12))
WHERE user_id = (SELECT user_id FROM u)
RETURNING %(tenant_id)s AS tenant_id"""
else:
with pg_client.PostgresClient() as cur:
print("Starting ACID insert")
query = cur.mogrify(f"""\
WITH t AS (
INSERT INTO public.tenants (name, version_number, licence)
VALUES (%(companyName)s, %(versionNumber)s, %(licence)s)
RETURNING tenant_id
),
u AS (
INSERT INTO public.users (tenant_id, email, role, name, data)
VALUES ((SELECT tenant_id FROM t), %(email)s, 'owner', %(fullname)s,%(data)s)
RETURNING user_id,email,role,name
),
au AS (
INSERT INTO public.basic_authentication (user_id, password, generated_password)
VALUES ((SELECT user_id FROM u), crypt(%(password)s, gen_salt('bf', 12)), FALSE)
)
INSERT INTO public.projects (tenant_id, name, active)
VALUES ((SELECT t.tenant_id FROM t), %(projectName)s, TRUE)
RETURNING tenant_id,project_id;""",
{"email": email, "password": password,
"fullname": fullname, "companyName": company_name,
"projectName": project_name,
"data": json.dumps({"lastAnnouncementView": TimeUTC.now()})})
cur.execute(
query
)
data = cur.fetchone()
query = """\
WITH t AS (
INSERT INTO public.tenants (name, version_number, edition)
VALUES (%(companyName)s, %(versionNumber)s, 'ee')
RETURNING tenant_id, api_key
),
u AS (
INSERT INTO public.users (tenant_id, email, role, name, data)
VALUES ((SELECT tenant_id FROM t), %(email)s, 'owner', %(fullname)s,%(data)s)
RETURNING user_id,email,role,name
),
au AS (
INSERT INTO public.basic_authentication (user_id, password, generated_password)
VALUES ((SELECT user_id FROM u), crypt(%(password)s, gen_salt('bf', 12)), FALSE)
)
INSERT INTO public.projects (tenant_id, name, active)
VALUES ((SELECT t.tenant_id FROM t), %(projectName)s, TRUE)
RETURNING tenant_id,project_id, (SELECT api_key FROM t) AS api_key;"""
with pg_client.PostgresClient() as cur:
cur.execute(cur.mogrify(query, params))
cur = cur.fetchone()
project_id = cur["project_id"]
api_key = cur["api_key"]
telemetry.new_client(tenant_id=data["tenant_id"])
return {"data": {"state": "success"}}
created_at = TimeUTC.now()
r = users.authenticate(email, password)
r["banner"] = False
r["limits"] = {
"teamMember": {"limit": 99, "remaining": 98, "count": 1},
"projects": {"limit": 99, "remaining": 98, "count": 1},
"metadata": [{
"projectId": project_id,
"name": project_name,
"limit": 10,
"remaining": 10,
"count": 0
}]
}
c = {
"tenantId": 1,
"name": company_name,
"apiKey": api_key,
"remainingTrial": 14,
"trialEnded": False,
"billingPeriodStartDate": created_at,
"hasActivePlan": True,
"projects": [
{
"projectId": project_id,
"name": project_name,
"recorded": False,
"stackIntegrations": False,
"status": "red"
}
]
}
return {
'jwt': r.pop('jwt'),
'data': {
"user": r,
"client": c,
}
}

View file

@ -39,7 +39,7 @@ def compute():
RETURNING *,(SELECT email FROM users_ee WHERE role = 'owner' AND users_ee.tenant_id = tenants.tenant_id LIMIT 1);"""
)
data = cur.fetchall()
requests.post('https://parrot.asayer.io/os/telemetry',
requests.post('https://parrot.openreplay.com/os/telemetry',
json={"stats": [process_data(d, edition='ee') for d in data]})
@ -51,4 +51,4 @@ def new_client(tenant_id):
FROM public.tenants
WHERE tenant_id=%(tenant_id)s;""", {"tenant_id": tenant_id}))
data = cur.fetchone()
requests.post('https://parrot.asayer.io/os/signup', json=process_data(data, edition='ee'))
requests.post('https://parrot.openreplay.com/os/signup', json=process_data(data, edition='ee'))

View file

@ -0,0 +1,25 @@
from chalicelib.utils.helper import environ
from chalicelib.utils.TimeUTC import TimeUTC
import requests
import uuid
def __get_mid():
return str(uuid.UUID(int=uuid.getnode()))
def __get_license():
return
def check():
r = requests.post('https://parrot.openreplay.com/os/license', json={"mid": __get_mid(), "license": __get_license()})
if r.status_code != 200 or not r.json().get("valid"):
environ["expiration"] = "-1"
else:
environ["expiration"] = r.json().get("expiration")
environ["lastCheck"] = TimeUTC.now()
def is_valid():
return int(environ["lastCheck"]) + int(environ["expiration"]) - TimeUTC.now() > 0

View file

@ -21,7 +21,7 @@ def timed(f):
'handle_request', '_generic_handle', 'handle', '_bootstrap_inner', 'run',
'_bootstrap', '_main_rest_api_handler', '_user_handler',
'_get_view_function_response', 'wrapped_event', 'handle_one_request',
'_global_error_handler', 'asayer_middleware']]
'_global_error_handler', 'openreplay_middleware']]
print("DEBUG: %s > %s took %d s to finish" % (" > ".join(call_stack), f.__name__, elapsed))
return result

View file

@ -7,7 +7,7 @@ def send_team_invitation(recipient, user_name, temp_password, client_id, sender_
formatting_variables={"userName": __escape_text_html(user_name),
"password": temp_password, "clientId": client_id,
"sender": sender_name})
SUBJECT = "Welcome to Asayer"
SUBJECT = "Welcome to OpenReplay"
send_html(BODY_HTML, SUBJECT, recipient)
@ -115,5 +115,5 @@ def weekly_report2(recipients, data):
</table>
</td>"""
BODY_HTML = __get_html_from_file("chalicelib/utils/html/Project-Weekly-Report.html", formatting_variables=data)
SUBJECT = "Asayer Project Weekly Report"
SUBJECT = "OpenReplay Project Weekly Report"
send_html(BODY_HTML=BODY_HTML, SUBJECT=SUBJECT, recipient=recipients)

View file

@ -42,7 +42,7 @@ class github_formatters:
'createdAt': github_formatters.get_timestamp(issue["created_at"]),
'closed': issue["closed_at"] is not None,
'commentsCount': issue["comments"],
'issueType': [str(l["id"]) for l in labels if l["name"].lower() != "asayer"],
'issueType': [str(l["id"]) for l in labels if l["name"].lower() != "openreplay"],
'labels': [l["name"] for l in labels]
}
return result

View file

@ -40,17 +40,6 @@ def generate_salt():
return "".join(random.choices(string.hexdigits, k=36))
def remove_empty_none_values(dictionary):
aux = {}
for key in dictionary.keys():
if dictionary[key] is not None:
if isinstance(dictionary[key], dict):
aux[key] = remove_empty_none_values(dictionary[key])
elif not isinstance(dictionary[key], str) or len(dictionary[key]) > 0:
aux[key] = dictionary[key]
return aux
def unique_ordered_list(array):
uniq = []
[uniq.append(x) for x in array if x not in uniq]

View file

@ -11,7 +11,7 @@
<table style="width:100%;font-weight:300;margin-bottom:0;border-collapse:collapse">
<tbody><tr style="font-weight:300">
<td width="125px" style="font-size:14px;padding:0;font-weight:300;margin:0;text-align:left">
<a href="%(frontend_url)s" style="color:#394EFF;font-weight:300;text-decoration:none" target="_blank" data-saferedirecturl="" width="125px" height="29px" alt="asayer" style="font-weight:300"><img src="img/weekly/asayer-logo.png" style="width: 160px;"></a>
<a href="%(frontend_url)s" style="color:#394EFF;font-weight:300;text-decoration:none" target="_blank" data-saferedirecturl="" width="125px" height="29px" alt="openreplay" style="font-weight:300"><img src="img/weekly/logo.png" style="width: 160px;"></a>
</td>
<td style="font-size:14px;padding:0;font-weight:300;margin:0;text-align:right">
<table style="width:100%;font-weight:300;margin-bottom:0;border-collapse:collapse">
@ -154,7 +154,7 @@
<div style="padding:10px 20px;max-width:600px;font-weight:300;margin:0 auto;text-align:left">
<div style="padding:35px 0;border-top:1px solid #e7ebee;font-weight:300; font-size: 13px;">
<a href="%(frontend_url)s/%(project_id)s/metrics" style="color:#394EFF;float:right;font-weight:300;text-decoration:none" target="_blank" data-saferedirecturl="#">Asayer Metrics</a>
<a href="%(frontend_url)s/%(project_id)s/metrics" style="color:#394EFF;float:right;font-weight:300;text-decoration:none" target="_blank" data-saferedirecturl="#">OpenReplay Metrics</a>
<a href="%(frontend_url)s/client/notifications" style="color:#394EFF;font-weight:300;text-decoration:none" target="_blank" data-saferedirecturl="#">Manage Notifications</a>

View file

@ -11,7 +11,7 @@
<tr>
<td style="padding:10px 30px;">
<center>
<img src="img/asayer-logo.png" alt="Asayer" width="100%" style="max-width: 120px;">
<img src="img/logo.png" alt="OpenReplay" width="100%" style="max-width: 120px;">
</center>
</td>
</tr>
@ -38,9 +38,9 @@
<div style="border-top:1px dotted rgba(0,0,0,0.2); display: block; margin-top: 20px"></div>
<center>
<p style="font-size: 12px; font-family: -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,'Helvetica Neue',sans-serif; color: #6c757d">
Sent with &#9825; from Asayer &copy; 2021 - All rights reserved.<br><br>
<a href="https://asayer.io" target="_blank"
style="text-decoration: none; color: #6c757d">https://asayer.io/</a>
Sent with &#9825; from OpenReplay &copy; 2021 - All rights reserved.<br><br>
<a href="https://openreplay.com" target="_blank"
style="text-decoration: none; color: #6c757d">https://openreplay.com/</a>
</p>
</center>

View file

@ -385,7 +385,7 @@ width: 25%!important
<td style="padding-right: 0px;padding-left: 0px;" align="center">
<![endif]-->
<img style="width=124px; height=35px;" width="124px" height="35px"
src="img/asayer-logo.png"/>
src="img/logo.png"/>
<!--[if mso]></td></tr></table><![endif]-->
</div>
@ -401,7 +401,7 @@ width: 25%!important
<div style="color:#555555;font-family:'Helvetica Neue', Helvetica, Arial, sans-serif;line-height:120%;padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:10px;">
<div style="font-size: 12px; line-height: 14px; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: #555555;">
<!-- <p style="font-size: 18px; line-height: 21px; text-align: center; margin: 0;">
<span style="font-size: 18px;">Welcome to Asayer!</span>
<span style="font-size: 18px;">Welcome to OpenReplay!</span>
</p>-->
<h1 style="text-align: center; margin-top: 30px; line-height: 30px">Assigned session</h1>
@ -514,10 +514,10 @@ width: 25%!important
<div style="color:#555555;font-family:-apple-system,BlinkMacSystemFont,'Helvetica Neue','Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,sans-serif;line-height:120%;padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:10px;">
<div style="font-size: 12px; line-height: 14px; color: #555555; font-family: -apple-system,BlinkMacSystemFont,'Helvetica Neue','Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,sans-serif;">
<p style="font-size: 14px; line-height: 16px; text-align: center; margin: 0;">
<a href="mailto:support@asayer.io?subject=[User Invite] - Reporting issue"
<a href="mailto:support@openreplay.com?subject=[User Invite] - Reporting issue"
style="text-decoration: underline; color: #009193;"
title="support@asayer.io">Report an issue</a> | <a
href="https://asayer.io/" rel="noopener"
title="support@openreplay.com">Report an issue</a> | <a
href="https://openreplay.com/" rel="noopener"
style="text-decoration: underline; color: #009193;" target="_blank">Take
a tour</a></p>
</div>

View file

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View file

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -378,7 +378,7 @@ width: 25%!important
<tr style="line-height:0px">
<td style="padding-right: 0px;padding-left: 0px;" align="center">
<![endif]-->
<img style="width=124px; height=35px;" width="124px" height="35px" src="img/asayer-logo.png"/>
<img style="width=124px; height=35px;" width="124px" height="35px" src="img/logo.png"/>
<!--[if mso]></td></tr></table><![endif]-->
</div>
@ -394,7 +394,7 @@ width: 25%!important
<div style="color:#555555;font-family:'Helvetica Neue', Helvetica, Arial, sans-serif;line-height:120%;padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:10px;">
<div style="font-size: 12px; line-height: 14px; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: #555555;">
<p style="font-size: 14px; line-height: 21px; text-align: center; margin: 0;">
<span style="font-size: 18px;"><strong>Welcome to Asayer!</strong></span>
<span style="font-size: 18px;"><strong>Welcome to OpenReplay!</strong></span>
</p>
</div>
</div>
@ -407,7 +407,7 @@ width: 25%!important
<div style="color:#555555;font-family:-apple-system,BlinkMacSystemFont,'Helvetica Neue','Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,sans-serif;line-height:120%;padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:10px;">
<div style="font-size: 12px; line-height: 14px; color: #555555; font-family: -apple-system,BlinkMacSystemFont,'Helvetica Neue','Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,sans-serif;">
<p style="font-size: 12px; line-height: 16px; text-align: center; margin: 0;">
<span style="font-size: 14px;">You have been invited by %(sender)s to join %(clientId)s team on Asayer.</span>
<span style="font-size: 14px;">You have been invited by %(sender)s to join %(clientId)s team on OpenReplay.</span>
</p>
</div>
</div>
@ -450,7 +450,7 @@ width: 25%!important
<span style="font-size: 18px;"><a href="%(frontend_url)s"
rel="noopener"
style="text-decoration: underline; color: #009193;"
target="_blank" title="Asayer Login">%(frontend_url)s</a></span><span
target="_blank" title="OpenReplay Login">%(frontend_url)s</a></span><span
style="font-size: 18px; line-height: 21px;"></span></p>
</div>
</div>
@ -553,10 +553,10 @@ width: 25%!important
<div style="color:#555555;font-family:-apple-system,BlinkMacSystemFont,'Helvetica Neue','Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,sans-serif;line-height:120%;padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:10px;">
<div style="font-size: 12px; line-height: 14px; color: #555555; font-family: -apple-system,BlinkMacSystemFont,'Helvetica Neue','Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,sans-serif;">
<p style="font-size: 14px; line-height: 16px; text-align: center; margin: 0;">
<a href="mailto:support@asayer.io?subject=[User Invite] - Reporting issue"
<a href="mailto:support@openreplay.com?subject=[User Invite] - Reporting issue"
style="text-decoration: underline; color: #009193;"
title="support@asayer.io">Report an issue</a> | <a
href="https://asayer.io/" rel="noopener"
title="support@openreplay.com">Report an issue</a> | <a
href="https://openreplay.com/" rel="noopener"
style="text-decoration: underline; color: #009193;" target="_blank">Take
a tour</a></p>
</div>

View file

@ -385,7 +385,7 @@ width: 25%!important
<td style="padding-right: 0px;padding-left: 0px;" align="center">
<![endif]-->
<img style="width=124px; height=35px;" width="124px" height="35px"
src="img/asayer-logo.png"/>
src="img/logo.png"/>
<!--[if mso]></td></tr></table><![endif]-->
</div>

View file

@ -1,9 +1,19 @@
from botocore.exceptions import ClientError
from chalicelib.utils.helper import environ
from chalicelib.utils import helper
import boto3
client = boto3.client('s3')
sts_client = boto3.client('sts')
if helper.is_free_open_source_edition() or helper.is_enterprise_edition():
from botocore.client import Config
client = boto3.client('s3', endpoint_url=environ["S3_HOST"],
aws_access_key_id=environ["S3_KEY"],
aws_secret_access_key=environ["S3_SECRET"],
config=Config(signature_version='s3v4'),
region_name='us-east-1')
else:
client = boto3.client('s3')
def exists(bucket, key):

17
ee/api/env_handler.py Normal file
View file

@ -0,0 +1,17 @@
from os import environ
import json
with open('.chalice/config.json') as json_file:
data = json.load(json_file)
stages = data.get("stages", {})
for s in stages.keys():
target = f'chalicelib/.configs/{stages[s].get("environment_variables", {}).get("stage", s)}.json'
data = {}
try:
with open(target) as stage_vars:
data = json.load(stage_vars)
except IOError:
pass
with open(target, 'w') as outfile:
json.dump({**data, **environ}, outfile, indent=2, sort_keys=True)
print(f"injected env-vars to {target}")

View file

@ -1,4 +1,4 @@
import React from 'react'
import React, { useState } from 'react'
import { Input, Slider, Button, Popup, CircularLoader } from 'UI';
import { saveCaptureRate, editCaptureRate } from 'Duck/watchdogs';
import { connect } from 'react-redux';
@ -12,8 +12,10 @@ function isPercent(val) {
const SessionCaptureRate = props => {
const { captureRate, saveCaptureRate, editCaptureRate, loading, onClose } = props;
const sampleRate = captureRate.get('rate');
if (sampleRate == null) return null;
const _sampleRate = captureRate.get('rate');
if (_sampleRate == null) return null;
const [sampleRate, setSampleRate] = useState(_sampleRate)
const captureAll = captureRate.get('captureAll');
@ -46,7 +48,7 @@ const SessionCaptureRate = props => {
name="sampleRate"
disabled={ captureAll }
value={ captureAll ? '100' : sampleRate }
onChange={ ({ target: { value }}) => isPercent(value) && editCaptureRate(+value) }
onChange={ ({ target: { value }}) => isPercent(value) && setSampleRate(+value) }
size="small"
className={stl.inputField}
/>

View file

@ -26,6 +26,7 @@ const RehydrateSlidePanel = props => {
onClose={ onClose }
size="small"
content={
isModalDisplayed && (
<div className="px-4">
<hr className="mb-3" />
<div>
@ -33,6 +34,7 @@ const RehydrateSlidePanel = props => {
<SessionCaptureRate onClose={ onClose } />
</div>
</div>
)
}
/>
);

View file

@ -75,7 +75,7 @@ export default class IntegrationForm extends React.PureComponent {
<Form>
{!ignoreProject &&
<Form.Field>
<label>{ 'Site' }</label>
<label>{ 'OpenReplay Project' }</label>
<SiteDropdown
value={ currentSiteId }
onChange={ this.onChangeSelect }

View file

@ -5,6 +5,7 @@ import { hasSiteId, siteChangeAvaliable } from 'App/routes';
import { STATUS_COLOR_MAP, GREEN } from 'Types/site';
import { Icon, SlideModal } from 'UI';
import { pushNewSite } from 'Duck/user'
import { init } from 'Duck/site';
import styles from './siteDropdown.css';
import cn from 'classnames';
import NewSiteForm from '../Client/Sites/NewSiteForm';
@ -15,7 +16,8 @@ import NewSiteForm from '../Client/Sites/NewSiteForm';
siteId: state.getIn([ 'user', 'siteId' ]),
}), {
setSiteId,
pushNewSite
pushNewSite,
init
})
export default class SiteDropdown extends React.PureComponent {
state = { showProductModal: false }
@ -28,6 +30,11 @@ export default class SiteDropdown extends React.PureComponent {
}
};
newSite = () => {
this.props.init({})
this.setState({showProductModal: true})
}
render() {
const { sites, siteId, location: { pathname } } = this.props;
const { showProductModal } = this.state;
@ -62,7 +69,7 @@ export default class SiteDropdown extends React.PureComponent {
</ul>
<div
className={cn(styles.btnNew, 'flex items-center justify-center py-3 cursor-pointer')}
onClick={() => this.setState({showProductModal: true})}
onClick={this.newSite}
>
<Icon
name="plus"
@ -78,7 +85,7 @@ export default class SiteDropdown extends React.PureComponent {
title="New Project"
size="small"
isDisplayed={ showProductModal }
content={ <NewSiteForm onClose={ this.closeModal } /> }
content={ showProductModal && <NewSiteForm onClose={ this.closeModal } /> }
onClose={ this.closeModal }
/>
</div>

View file

@ -18,6 +18,7 @@ export default function EventSearch(props) {
value={value}
onChange={onChange}
style={{ height: '32px' }}
autocomplete="off"
/>
<div
onClick={() => { setShowSearch(!showSearch); clearSearch() }}

View file

@ -112,7 +112,6 @@ export default class Timeline extends React.PureComponent {
style={ {
left: `${ interval.start * scale }%`,
width: `${ (interval.end - interval.start) * scale }%`,
top: '-30px'
} }
/>))
}
@ -121,7 +120,7 @@ export default class Timeline extends React.PureComponent {
<div
key={ e.key }
className={ stl.event }
style={ { left: `${ e.time * scale }%`, top: '-30px' } }
style={ { left: `${ e.time * scale }%` } }
/>
))
}

View file

@ -12,7 +12,7 @@ const tracker = new Tracker({
tracker.start();`
function InstallDocs({ site }) {
const _usageCode = usageCode.replace('PROJECT_ID', site.projectKeKey)
const _usageCode = usageCode.replace('PROJECT_ID', site.projectKey)
return (
<div>
<div className="mb-3">