Changes:
- fixed env-vars - fixed EE signup - changed EE DB structure - changed FOS DB structure - fixed announcements - use minio for api - use minio for sourcemaps-reader - share env-vars with sourcemaps-reader
|
|
@ -14,15 +14,15 @@
|
||||||
"isFOS": "true",
|
"isFOS": "true",
|
||||||
"isEE": "false",
|
"isEE": "false",
|
||||||
"stage": "default-fos",
|
"stage": "default-fos",
|
||||||
"jwt_issuer": "asayer-default-fos",
|
"jwt_issuer": "openreplay-default-fos",
|
||||||
"allowCron": "true",
|
"allowCron": "true",
|
||||||
"sentry": "false",
|
"sentry": "false",
|
||||||
"sentryURL": "",
|
"sentryURL": "",
|
||||||
"pg_host": "",
|
"pg_host": "postgresql.db.svc.cluster.local",
|
||||||
"pg_port": "5432",
|
"pg_port": "5432",
|
||||||
"pg_dbname": "",
|
"pg_dbname": "postgres",
|
||||||
"pg_user": "",
|
"pg_user": "postgres",
|
||||||
"pg_password": "",
|
"pg_password": "asayerPostgres",
|
||||||
"alert_ntf": "http://127.0.0.1:8000/async/alerts/notifications/%s",
|
"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_signup": "http://127.0.0.1:8000/async/email_signup/%s",
|
||||||
"email_funnel": "http://127.0.0.1:8000/async/funnel/%s",
|
"email_funnel": "http://127.0.0.1:8000/async/funnel/%s",
|
||||||
|
|
@ -44,7 +44,6 @@
|
||||||
"sourcemaps_bucket_secret": "",
|
"sourcemaps_bucket_secret": "",
|
||||||
"sourcemaps_bucket_region": "",
|
"sourcemaps_bucket_region": "",
|
||||||
"js_cache_bucket": "",
|
"js_cache_bucket": "",
|
||||||
"web_mobs": "https://mobs-staging.asayer.io",
|
|
||||||
"async_Token": "",
|
"async_Token": "",
|
||||||
"EMAIL_HOST": "",
|
"EMAIL_HOST": "",
|
||||||
"EMAIL_PORT": "587",
|
"EMAIL_PORT": "587",
|
||||||
|
|
@ -56,10 +55,13 @@
|
||||||
"EMAIL_SSL_CERT": "",
|
"EMAIL_SSL_CERT": "",
|
||||||
"EMAIL_FROM": "OpenReplay<do-not-reply@openreplay.com>",
|
"EMAIL_FROM": "OpenReplay<do-not-reply@openreplay.com>",
|
||||||
"SITE_URL": "",
|
"SITE_URL": "",
|
||||||
"announcement_bucket": "",
|
"announcement_url": "",
|
||||||
"jwt_secret": "",
|
"jwt_secret": "",
|
||||||
"jwt_algorithm": "HS512",
|
"jwt_algorithm": "HS512",
|
||||||
"jwt_exp_delta_seconds": "2592000"
|
"jwt_exp_delta_seconds": "2592000",
|
||||||
|
"S3_HOST": "",
|
||||||
|
"S3_KEY": "",
|
||||||
|
"S3_SECRET": ""
|
||||||
},
|
},
|
||||||
"lambda_timeout": 150,
|
"lambda_timeout": 150,
|
||||||
"lambda_memory_size": 400,
|
"lambda_memory_size": 400,
|
||||||
|
|
|
||||||
|
|
@ -13,4 +13,4 @@ ENV ENTERPRISE_BUILD ${envarg}
|
||||||
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
|
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
|
||||||
RUN chmod +x /tini
|
RUN chmod +x /tini
|
||||||
ENTRYPOINT ["/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}
|
||||||
|
|
@ -55,7 +55,7 @@ sys.stderr = F()
|
||||||
|
|
||||||
_overrides.chalice_app(app)
|
_overrides.chalice_app(app)
|
||||||
|
|
||||||
# v0505
|
# v0905
|
||||||
@app.middleware('http')
|
@app.middleware('http')
|
||||||
def asayer_middleware(event, get_response):
|
def asayer_middleware(event, get_response):
|
||||||
global ASAYER_SESSION_ID
|
global ASAYER_SESSION_ID
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ def get_all(user_id):
|
||||||
for a in announcements:
|
for a in announcements:
|
||||||
a["createdAt"] = TimeUTC.datetime_to_timestamp(a["createdAt"])
|
a["createdAt"] = TimeUTC.datetime_to_timestamp(a["createdAt"])
|
||||||
if a["imageUrl"] is not None and len(a["imageUrl"]) > 0:
|
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
|
return announcements
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,20 +40,20 @@ def get_state(tenant_id):
|
||||||
meta = cur.fetchone()["sum"] > 0
|
meta = cur.fetchone()["sum"] > 0
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{"task": "Install Asayer",
|
{"task": "Install OpenReplay",
|
||||||
"done": recorded,
|
"done": recorded,
|
||||||
"URL": "https://docs.asayer.io/getting-started/quick-start"},
|
"URL": "https://docs.openreplay.com/getting-started/quick-start"},
|
||||||
{"task": "Identify Users",
|
{"task": "Identify Users",
|
||||||
"done": meta,
|
"done": meta,
|
||||||
"URL": "https://docs.asayer.io/data-privacy-security/metadata"},
|
"URL": "https://docs.openreplay.com/data-privacy-security/metadata"},
|
||||||
{"task": "Invite Team Members",
|
{"task": "Invite Team Members",
|
||||||
"done": len(users.get_members(tenant_id=tenant_id)) > 1,
|
"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",
|
{"task": "Integrations",
|
||||||
"done": len(log_tool_datadog.get_all(tenant_id=tenant_id)) > 0 \
|
"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_sentry.get_all(tenant_id=tenant_id)) > 0 \
|
||||||
or len(log_tool_stackdriver.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
|
recorded = cur.fetchone()["count"] > 0
|
||||||
|
|
||||||
return {"task": "Install Asayer",
|
return {"task": "Install OpenReplay",
|
||||||
"done": recorded,
|
"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):
|
def get_state_identify_users(tenant_id):
|
||||||
|
|
@ -99,13 +99,13 @@ def get_state_identify_users(tenant_id):
|
||||||
|
|
||||||
return {"task": "Identify Users",
|
return {"task": "Identify Users",
|
||||||
"done": meta,
|
"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):
|
def get_state_manage_users(tenant_id):
|
||||||
return {"task": "Invite Team Members",
|
return {"task": "Invite Team Members",
|
||||||
"done": len(users.get_members(tenant_id=tenant_id)) > 1,
|
"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):
|
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 \
|
"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_sentry.get_all(tenant_id=tenant_id)) > 0 \
|
||||||
or len(log_tool_stackdriver.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"}
|
||||||
|
|
|
||||||
|
|
@ -503,8 +503,8 @@ def search(data, project_id, user_id, flows=False, status="ALL", favorite_only=F
|
||||||
GROUP BY timestamp
|
GROUP BY timestamp
|
||||||
ORDER BY timestamp) AS chart_details) AS chart_details ON (TRUE);"""
|
ORDER BY timestamp) AS chart_details) AS chart_details ON (TRUE);"""
|
||||||
|
|
||||||
print("--------------------")
|
# print("--------------------")
|
||||||
print(cur.mogrify(main_pg_query, params))
|
# print(cur.mogrify(main_pg_query, params))
|
||||||
cur.execute(cur.mogrify(main_pg_query, params))
|
cur.execute(cur.mogrify(main_pg_query, params))
|
||||||
total = cur.rowcount
|
total = cur.rowcount
|
||||||
if flows:
|
if flows:
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ class GithubIntegrationIssue(BaseIntegrationIssue):
|
||||||
if a == str(u["id"]):
|
if a == str(u["id"]):
|
||||||
real_assignees.append(u["login"])
|
real_assignees.append(u["login"])
|
||||||
break
|
break
|
||||||
real_labels = ["Asayer"]
|
real_labels = ["OpenReplay"]
|
||||||
for l in labels:
|
for l in labels:
|
||||||
found = False
|
found = False
|
||||||
for ll in metas["issueTypes"]:
|
for ll in metas["issueTypes"]:
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ class JIRACloudIntegrationIssue(BaseIntegrationIssue):
|
||||||
'description': description,
|
'description': description,
|
||||||
'issuetype': {'id': issue_type},
|
'issuetype': {'id': issue_type},
|
||||||
'assignee': {"id": assignee},
|
'assignee': {"id": assignee},
|
||||||
"labels": ["Asayer"]
|
"labels": ["OpenReplay"]
|
||||||
}
|
}
|
||||||
return self._client.create_issue(data)
|
return self._client.create_issue(data)
|
||||||
|
|
||||||
|
|
@ -30,7 +30,7 @@ class JIRACloudIntegrationIssue(BaseIntegrationIssue):
|
||||||
results = []
|
results = []
|
||||||
for integration_project_id in projects_map:
|
for integration_project_id in projects_map:
|
||||||
self._client.set_jira_project_id(integration_project_id)
|
self._client.set_jira_project_id(integration_project_id)
|
||||||
jql = 'labels = Asayer'
|
jql = 'labels = OpenReplay'
|
||||||
if len(projects_map[integration_project_id]) > 0:
|
if len(projects_map[integration_project_id]) > 0:
|
||||||
jql += f" AND ID IN ({','.join(projects_map[integration_project_id])})"
|
jql += f" AND ID IN ({','.join(projects_map[integration_project_id])})"
|
||||||
issues = self._client.get_issues(jql, offset=0)
|
issues = self._client.get_issues(jql, offset=0)
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ def __find_events(client, log_group, streams, last_token, start_time, end_time):
|
||||||
"startTime": start_time,
|
"startTime": start_time,
|
||||||
"endTime": end_time,
|
"endTime": end_time,
|
||||||
"limit": 10000,
|
"limit": 10000,
|
||||||
"filterPattern": "asayer_session_id"
|
"filterPattern": "openreplay_session_id"
|
||||||
}
|
}
|
||||||
if last_token is not None:
|
if last_token is not None:
|
||||||
f_args["nextToken"] = last_token
|
f_args["nextToken"] = last_token
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
from chalicelib.utils import pg_client, helper
|
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.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
|
||||||
from chalicelib.core import projects, errors
|
|
||||||
else:
|
|
||||||
from chalicelib.ee import projects, errors
|
|
||||||
|
|
||||||
from chalicelib.core import resources
|
from chalicelib.core import resources
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,8 +56,13 @@ def create_step1(data):
|
||||||
project_name = data.get("projectName")
|
project_name = data.get("projectName")
|
||||||
if project_name is None or len(project_name) < 1:
|
if project_name is None or len(project_name) < 1:
|
||||||
project_name = "my first project"
|
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")
|
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:
|
if len(errors) > 0:
|
||||||
print("==> error")
|
print("==> error")
|
||||||
print(errors)
|
print(errors)
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ def compute():
|
||||||
RETURNING *,(SELECT email FROM public.users WHERE role='owner' LIMIT 1);"""
|
RETURNING *,(SELECT email FROM public.users WHERE role='owner' LIMIT 1);"""
|
||||||
)
|
)
|
||||||
data = cur.fetchone()
|
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():
|
def new_client():
|
||||||
|
|
@ -40,4 +40,4 @@ def new_client():
|
||||||
(SELECT email FROM public.users WHERE role='owner' LIMIT 1) AS email
|
(SELECT email FROM public.users WHERE role='owner' LIMIT 1) AS email
|
||||||
FROM public.tenants;""")
|
FROM public.tenants;""")
|
||||||
data = cur.fetchone()
|
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))
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ def timed(f):
|
||||||
'handle_request', '_generic_handle', 'handle', '_bootstrap_inner', 'run',
|
'handle_request', '_generic_handle', 'handle', '_bootstrap_inner', 'run',
|
||||||
'_bootstrap', '_main_rest_api_handler', '_user_handler',
|
'_bootstrap', '_main_rest_api_handler', '_user_handler',
|
||||||
'_get_view_function_response', 'wrapped_event', 'handle_one_request',
|
'_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))
|
print("DEBUG: %s > %s took %d s to finish" % (" > ".join(call_stack), f.__name__, elapsed))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ def send_team_invitation(recipient, user_name, temp_password, client_id, sender_
|
||||||
formatting_variables={"userName": __escape_text_html(user_name),
|
formatting_variables={"userName": __escape_text_html(user_name),
|
||||||
"password": temp_password, "clientId": client_id,
|
"password": temp_password, "clientId": client_id,
|
||||||
"sender": sender_name})
|
"sender": sender_name})
|
||||||
SUBJECT = "Welcome to Asayer"
|
SUBJECT = "Welcome to OpenReplay"
|
||||||
send_html(BODY_HTML, SUBJECT, recipient)
|
send_html(BODY_HTML, SUBJECT, recipient)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -115,5 +115,5 @@ def weekly_report2(recipients, data):
|
||||||
</table>
|
</table>
|
||||||
</td>"""
|
</td>"""
|
||||||
BODY_HTML = __get_html_from_file("chalicelib/utils/html/Project-Weekly-Report.html", formatting_variables=data)
|
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)
|
send_html(BODY_HTML=BODY_HTML, SUBJECT=SUBJECT, recipient=recipients)
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ class github_formatters:
|
||||||
'createdAt': github_formatters.get_timestamp(issue["created_at"]),
|
'createdAt': github_formatters.get_timestamp(issue["created_at"]),
|
||||||
'closed': issue["closed_at"] is not None,
|
'closed': issue["closed_at"] is not None,
|
||||||
'commentsCount': issue["comments"],
|
'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]
|
'labels': [l["name"] for l in labels]
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
|
|
||||||
|
|
@ -40,17 +40,6 @@ def generate_salt():
|
||||||
return "".join(random.choices(string.hexdigits, k=36))
|
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):
|
def unique_ordered_list(array):
|
||||||
uniq = []
|
uniq = []
|
||||||
[uniq.append(x) for x in array if x not in uniq]
|
[uniq.append(x) for x in array if x not in uniq]
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
<table style="width:100%;font-weight:300;margin-bottom:0;border-collapse:collapse">
|
<table style="width:100%;font-weight:300;margin-bottom:0;border-collapse:collapse">
|
||||||
<tbody><tr style="font-weight:300">
|
<tbody><tr style="font-weight:300">
|
||||||
<td width="125px" style="font-size:14px;padding:0;font-weight:300;margin:0;text-align:left">
|
<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>
|
||||||
<td style="font-size:14px;padding:0;font-weight:300;margin:0;text-align:right">
|
<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">
|
<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: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;">
|
<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>
|
<a href="%(frontend_url)s/client/notifications" style="color:#394EFF;font-weight:300;text-decoration:none" target="_blank" data-saferedirecturl="#">Manage Notifications</a>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td style="padding:10px 30px;">
|
<td style="padding:10px 30px;">
|
||||||
<center>
|
<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>
|
</center>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -38,9 +38,9 @@
|
||||||
<div style="border-top:1px dotted rgba(0,0,0,0.2); display: block; margin-top: 20px"></div>
|
<div style="border-top:1px dotted rgba(0,0,0,0.2); display: block; margin-top: 20px"></div>
|
||||||
<center>
|
<center>
|
||||||
<p style="font-size: 12px; font-family: -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,'Helvetica Neue',sans-serif; color: #6c757d">
|
<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 ♡ from Asayer © 2021 - All rights reserved.<br><br>
|
Sent with ♡ from OpenReplay © 2021 - All rights reserved.<br><br>
|
||||||
<a href="https://asayer.io" target="_blank"
|
<a href="https://openreplay.com" target="_blank"
|
||||||
style="text-decoration: none; color: #6c757d">https://asayer.io/</a>
|
style="text-decoration: none; color: #6c757d">https://openreplay.com/</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
</center>
|
</center>
|
||||||
|
|
|
||||||
|
|
@ -385,7 +385,7 @@ width: 25%!important
|
||||||
<td style="padding-right: 0px;padding-left: 0px;" align="center">
|
<td style="padding-right: 0px;padding-left: 0px;" align="center">
|
||||||
<![endif]-->
|
<![endif]-->
|
||||||
<img style="width=124px; height=35px;" width="124px" height="35px"
|
<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]-->
|
<!--[if mso]></td></tr></table><![endif]-->
|
||||||
</div>
|
</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="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;">
|
<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;">
|
<!-- <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>-->
|
</p>-->
|
||||||
<h1 style="text-align: center; margin-top: 30px; line-height: 30px">Assigned session</h1>
|
<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="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;">
|
<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;">
|
<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;"
|
style="text-decoration: underline; color: #009193;"
|
||||||
title="support@asayer.io">Report an issue</a> | <a
|
title="support@openreplay.com">Report an issue</a> | <a
|
||||||
href="https://asayer.io/" rel="noopener"
|
href="https://openreplay.com/" rel="noopener"
|
||||||
style="text-decoration: underline; color: #009193;" target="_blank">Take
|
style="text-decoration: underline; color: #009193;" target="_blank">Take
|
||||||
a tour</a></p>
|
a tour</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
|
@ -378,7 +378,7 @@ width: 25%!important
|
||||||
<tr style="line-height:0px">
|
<tr style="line-height:0px">
|
||||||
<td style="padding-right: 0px;padding-left: 0px;" align="center">
|
<td style="padding-right: 0px;padding-left: 0px;" align="center">
|
||||||
<![endif]-->
|
<![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]-->
|
<!--[if mso]></td></tr></table><![endif]-->
|
||||||
</div>
|
</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="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;">
|
<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;">
|
<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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</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="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;">
|
<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;">
|
<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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -450,7 +450,7 @@ width: 25%!important
|
||||||
<span style="font-size: 18px;"><a href="%(frontend_url)s"
|
<span style="font-size: 18px;"><a href="%(frontend_url)s"
|
||||||
rel="noopener"
|
rel="noopener"
|
||||||
style="text-decoration: underline; color: #009193;"
|
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>
|
style="font-size: 18px; line-height: 21px;"></span></p>
|
||||||
</div>
|
</div>
|
||||||
</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="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;">
|
<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;">
|
<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;"
|
style="text-decoration: underline; color: #009193;"
|
||||||
title="support@asayer.io">Report an issue</a> | <a
|
title="support@openreplay.com">Report an issue</a> | <a
|
||||||
href="https://asayer.io/" rel="noopener"
|
href="https://openreplay.com/" rel="noopener"
|
||||||
style="text-decoration: underline; color: #009193;" target="_blank">Take
|
style="text-decoration: underline; color: #009193;" target="_blank">Take
|
||||||
a tour</a></p>
|
a tour</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -385,7 +385,7 @@ width: 25%!important
|
||||||
<td style="padding-right: 0px;padding-left: 0px;" align="center">
|
<td style="padding-right: 0px;padding-left: 0px;" align="center">
|
||||||
<![endif]-->
|
<![endif]-->
|
||||||
<img style="width=124px; height=35px;" width="124px" height="35px"
|
<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]-->
|
<!--[if mso]></td></tr></table><![endif]-->
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,15 @@
|
||||||
from botocore.exceptions import ClientError
|
from botocore.exceptions import ClientError
|
||||||
|
from chalicelib.utils.helper import environ
|
||||||
|
|
||||||
import boto3
|
import boto3
|
||||||
|
|
||||||
client = boto3.client('s3')
|
from botocore.client import Config
|
||||||
sts_client = boto3.client('sts')
|
|
||||||
|
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):
|
def exists(bucket, key):
|
||||||
|
|
|
||||||
17
api/env_handler.py
Normal 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}")
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
"isFOS": "false",
|
"isFOS": "false",
|
||||||
"isEE": "true",
|
"isEE": "true",
|
||||||
"stage": "default-ee",
|
"stage": "default-ee",
|
||||||
"jwt_issuer": "asayer-default-ee",
|
"jwt_issuer": "openreplay-default-ee",
|
||||||
"allowCron": "true",
|
"allowCron": "true",
|
||||||
"sentry": "false",
|
"sentry": "false",
|
||||||
"sentryURL": "",
|
"sentryURL": "",
|
||||||
|
|
@ -49,7 +49,6 @@
|
||||||
"js_cache_bucket": "",
|
"js_cache_bucket": "",
|
||||||
"SIGN_ID": "",
|
"SIGN_ID": "",
|
||||||
"SIGN_KEY": "",
|
"SIGN_KEY": "",
|
||||||
"web_mobs": "https://mobs-staging.asayer.io",
|
|
||||||
"async_Token": "",
|
"async_Token": "",
|
||||||
"EMAIL_HOST": "",
|
"EMAIL_HOST": "",
|
||||||
"EMAIL_PORT": "587",
|
"EMAIL_PORT": "587",
|
||||||
|
|
@ -61,10 +60,13 @@
|
||||||
"EMAIL_SSL_CERT": "",
|
"EMAIL_SSL_CERT": "",
|
||||||
"EMAIL_FROM": "OpenReplay<do-not-reply@openreplay.com>",
|
"EMAIL_FROM": "OpenReplay<do-not-reply@openreplay.com>",
|
||||||
"SITE_URL": "",
|
"SITE_URL": "",
|
||||||
"announcement_bucket": "",
|
"announcement_url": "",
|
||||||
"jwt_secret": "",
|
"jwt_secret": "",
|
||||||
"jwt_algorithm": "",
|
"jwt_algorithm": "",
|
||||||
"jwt_exp_delta_seconds": ""
|
"jwt_exp_delta_seconds": "",
|
||||||
|
"S3_HOST": "",
|
||||||
|
"S3_KEY": "",
|
||||||
|
"S3_SECRET": ""
|
||||||
},
|
},
|
||||||
"lambda_timeout": 150,
|
"lambda_timeout": 150,
|
||||||
"lambda_memory_size": 400,
|
"lambda_memory_size": 400,
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,9 @@ _overrides.chalice_app(app)
|
||||||
|
|
||||||
@app.middleware('http')
|
@app.middleware('http')
|
||||||
def asayer_middleware(event, get_response):
|
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():
|
if "{projectid}" in event.path.lower():
|
||||||
from chalicelib.ee import projects
|
from chalicelib.ee import projects
|
||||||
if not projects.is_authorized(project_id=event.uri_params["projectId"],
|
if not projects.is_authorized(project_id=event.uri_params["projectId"],
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ base_time = datetime.now(pytz.utc)
|
||||||
|
|
||||||
cors_config = CORSConfig(
|
cors_config = CORSConfig(
|
||||||
allow_origin='*',
|
allow_origin='*',
|
||||||
allow_headers=['vnd.asayer.io.sid'],
|
allow_headers=['vnd.openreplay.com.sid'],
|
||||||
# max_age=600,
|
# max_age=600,
|
||||||
# expose_headers=['X-Special-Header'],
|
# expose_headers=['X-Special-Header'],
|
||||||
allow_credentials=True
|
allow_credentials=True
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,14 @@ from chalicelib.utils import helper
|
||||||
app = Blueprint(__name__)
|
app = Blueprint(__name__)
|
||||||
_overrides.chalice_app(app)
|
_overrides.chalice_app(app)
|
||||||
from chalicelib.ee import telemetry
|
from chalicelib.ee import telemetry
|
||||||
|
from chalicelib.ee import unlock
|
||||||
|
|
||||||
# Run every day.
|
# Run every day.
|
||||||
@app.schedule(Cron('0', '0', '?', '*', '*', '*'))
|
@app.schedule(Cron('0', '0', '?', '*', '*', '*'))
|
||||||
def telemetry_cron(event):
|
def telemetry_cron(event):
|
||||||
telemetry.compute()
|
telemetry.compute()
|
||||||
|
|
||||||
|
|
||||||
|
@app.schedule(Cron('0/60', '*', '*', '*', '?', '*'))
|
||||||
|
def unlock_cron(event):
|
||||||
|
unlock.check()
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
from chalice import Blueprint
|
from chalice import Blueprint
|
||||||
|
|
||||||
from chalicelib import _overrides
|
from chalicelib import _overrides
|
||||||
|
from chalicelib.ee import unlock
|
||||||
|
|
||||||
app = Blueprint(__name__)
|
app = Blueprint(__name__)
|
||||||
_overrides.chalice_app(app)
|
_overrides.chalice_app(app)
|
||||||
|
|
||||||
|
unlock.check()
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ def get_all(user_id):
|
||||||
for a in announcements:
|
for a in announcements:
|
||||||
a["createdAt"] = TimeUTC.datetime_to_timestamp(a["createdAt"])
|
a["createdAt"] = TimeUTC.datetime_to_timestamp(a["createdAt"])
|
||||||
if a["imageUrl"] is not None and len(a["imageUrl"]) > 0:
|
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
|
return announcements
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ class GithubIntegrationIssue(BaseIntegrationIssue):
|
||||||
if a == str(u["id"]):
|
if a == str(u["id"]):
|
||||||
real_assignees.append(u["login"])
|
real_assignees.append(u["login"])
|
||||||
break
|
break
|
||||||
real_labels = ["Asayer"]
|
real_labels = ["OpenReplay"]
|
||||||
for l in labels:
|
for l in labels:
|
||||||
found = False
|
found = False
|
||||||
for ll in metas["issueTypes"]:
|
for ll in metas["issueTypes"]:
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ class JIRACloudIntegrationIssue(BaseIntegrationIssue):
|
||||||
'description': description,
|
'description': description,
|
||||||
'issuetype': {'id': issue_type},
|
'issuetype': {'id': issue_type},
|
||||||
'assignee': {"id": assignee},
|
'assignee': {"id": assignee},
|
||||||
"labels": ["Asayer"]
|
"labels": ["OpenReplay"]
|
||||||
}
|
}
|
||||||
return self._client.create_issue(data)
|
return self._client.create_issue(data)
|
||||||
|
|
||||||
|
|
@ -30,7 +30,7 @@ class JIRACloudIntegrationIssue(BaseIntegrationIssue):
|
||||||
results = []
|
results = []
|
||||||
for integration_project_id in projects_map:
|
for integration_project_id in projects_map:
|
||||||
self._client.set_jira_project_id(integration_project_id)
|
self._client.set_jira_project_id(integration_project_id)
|
||||||
jql = 'labels = Asayer'
|
jql = 'labels = OpenReplay'
|
||||||
if len(projects_map[integration_project_id]) > 0:
|
if len(projects_map[integration_project_id]) > 0:
|
||||||
jql += f" AND ID IN ({','.join(projects_map[integration_project_id])})"
|
jql += f" AND ID IN ({','.join(projects_map[integration_project_id])})"
|
||||||
issues = self._client.get_issues(jql, offset=0)
|
issues = self._client.get_issues(jql, offset=0)
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ def __find_events(client, log_group, streams, last_token, start_time, end_time):
|
||||||
"startTime": start_time,
|
"startTime": start_time,
|
||||||
"endTime": end_time,
|
"endTime": end_time,
|
||||||
"limit": 10000,
|
"limit": 10000,
|
||||||
"filterPattern": "asayer_session_id"
|
"filterPattern": "openreplay_session_id"
|
||||||
}
|
}
|
||||||
if last_token is not None:
|
if last_token is not None:
|
||||||
f_args["nextToken"] = last_token
|
f_args["nextToken"] = last_token
|
||||||
|
|
|
||||||
|
|
@ -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))
|
|
||||||
|
|
@ -43,20 +43,20 @@ def get_state(tenant_id):
|
||||||
meta = cur.fetchone()["sum"] > 0
|
meta = cur.fetchone()["sum"] > 0
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{"task": "Install Asayer",
|
{"task": "Install OpenReplay",
|
||||||
"done": recorded,
|
"done": recorded,
|
||||||
"URL": "https://docs.asayer.io/getting-started/quick-start"},
|
"URL": "https://docs.openreplay.com/getting-started/quick-start"},
|
||||||
{"task": "Identify Users",
|
{"task": "Identify Users",
|
||||||
"done": meta,
|
"done": meta,
|
||||||
"URL": "https://docs.asayer.io/data-privacy-security/metadata"},
|
"URL": "https://docs.openreplay.com/data-privacy-security/metadata"},
|
||||||
{"task": "Invite Team Members",
|
{"task": "Invite Team Members",
|
||||||
"done": len(users.get_members(tenant_id=tenant_id)) > 1,
|
"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",
|
{"task": "Integrations",
|
||||||
"done": len(log_tool_datadog.get_all(tenant_id=tenant_id)) > 0 \
|
"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_sentry.get_all(tenant_id=tenant_id)) > 0 \
|
||||||
or len(log_tool_stackdriver.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
|
recorded = cur.fetchone()["count"] > 0
|
||||||
|
|
||||||
return {"task": "Install Asayer",
|
return {"task": "Install OpenReplay",
|
||||||
"done": recorded,
|
"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):
|
def get_state_identify_users(tenant_id):
|
||||||
|
|
@ -104,13 +104,13 @@ def get_state_identify_users(tenant_id):
|
||||||
|
|
||||||
return {"task": "Identify Users",
|
return {"task": "Identify Users",
|
||||||
"done": meta,
|
"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):
|
def get_state_manage_users(tenant_id):
|
||||||
return {"task": "Invite Team Members",
|
return {"task": "Invite Team Members",
|
||||||
"done": len(users.get_members(tenant_id=tenant_id)) > 1,
|
"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):
|
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 \
|
"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_sentry.get_all(tenant_id=tenant_id)) > 0 \
|
||||||
or len(log_tool_stackdriver.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"}
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,9 @@ from chalicelib.utils.TimeUTC import TimeUTC
|
||||||
|
|
||||||
def get_signed_ups():
|
def get_signed_ups():
|
||||||
with pg_client.PostgresClient() as cur:
|
with pg_client.PostgresClient() as cur:
|
||||||
query = cur.mogrify(f"SELECT tenant_id, name FROM public.tenants;")
|
cur.execute("SELECT tenant_id, name FROM public.tenants;")
|
||||||
cur.execute(
|
|
||||||
query
|
|
||||||
)
|
|
||||||
rows = cur.fetchall()
|
rows = cur.fetchall()
|
||||||
return {"data": helper.list_to_camel_case(rows)}
|
return helper.list_to_camel_case(rows)
|
||||||
|
|
||||||
|
|
||||||
def create_step1(data):
|
def create_step1(data):
|
||||||
|
|
@ -48,15 +45,19 @@ def create_step1(data):
|
||||||
errors.append("Invalid full name.")
|
errors.append("Invalid full name.")
|
||||||
|
|
||||||
print("Verifying company's name validity")
|
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):
|
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")
|
print("Verifying project's name validity")
|
||||||
project_name = data.get("projectName")
|
project_name = data.get("projectName")
|
||||||
if project_name is None or len(project_name) < 1:
|
if project_name is None or len(project_name) < 1:
|
||||||
project_name = "my first project"
|
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:
|
if len(errors) > 0:
|
||||||
print("==> error")
|
print("==> error")
|
||||||
print(errors)
|
print(errors)
|
||||||
|
|
@ -64,64 +65,95 @@ def create_step1(data):
|
||||||
print("No errors detected")
|
print("No errors detected")
|
||||||
print("Decomposed infos")
|
print("Decomposed infos")
|
||||||
tenant_id = data.get("tenantId")
|
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:
|
if tenant_id is not None:
|
||||||
with pg_client.PostgresClient() as cur:
|
query = """\
|
||||||
print("Starting ACID insert")
|
WITH t AS (
|
||||||
query = cur.mogrify(f"""\
|
UPDATE public.tenants
|
||||||
WITH t AS (
|
SET name = %(companyName)s,
|
||||||
UPDATE public.tenants
|
version_number = %(versionNumber)s,
|
||||||
SET name = %(companyName)s,
|
licence = %(licence)s
|
||||||
version_number = %(versionNumber)s,
|
WHERE tenant_id=%(tenant_id)s
|
||||||
licence = %(licence)s
|
RETURNING tenant_id, api_key
|
||||||
WHERE tenant_id=%(tenant_id)s
|
),
|
||||||
),
|
u AS (
|
||||||
u AS (
|
UPDATE public.users
|
||||||
UPDATE public.users
|
SET email = %(email)s,
|
||||||
SET email = %(email)s,
|
name = %(fullname)s,
|
||||||
name = %(fullname)s,
|
WHERE role ='owner' AND tenant_id=%(tenant_id)s
|
||||||
WHERE role ='owner' AND tenant_id=%(tenant_id)s
|
RETURNING user_id,email, role, name
|
||||||
RETURNING user_id,email, role, name
|
)
|
||||||
)
|
UPDATE public.basic_authentication
|
||||||
UPDATE public.basic_authentication
|
SET password= crypt(%(password)s, gen_salt('bf', 12))
|
||||||
SET password= crypt(%(password)s, gen_salt('bf', 12))
|
WHERE user_id = (SELECT user_id FROM u)
|
||||||
WHERE user_id = (SELECT user_id FROM u)
|
RETURNING %(tenant_id)s AS tenant_id"""
|
||||||
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()
|
|
||||||
else:
|
else:
|
||||||
with pg_client.PostgresClient() as cur:
|
query = """\
|
||||||
print("Starting ACID insert")
|
WITH t AS (
|
||||||
query = cur.mogrify(f"""\
|
INSERT INTO public.tenants (name, version_number, edition)
|
||||||
WITH t AS (
|
VALUES (%(companyName)s, %(versionNumber)s, 'ee')
|
||||||
INSERT INTO public.tenants (name, version_number, licence)
|
RETURNING tenant_id, api_key
|
||||||
VALUES (%(companyName)s, %(versionNumber)s, %(licence)s)
|
),
|
||||||
RETURNING tenant_id
|
u AS (
|
||||||
),
|
INSERT INTO public.users (tenant_id, email, role, name, data)
|
||||||
u AS (
|
VALUES ((SELECT tenant_id FROM t), %(email)s, 'owner', %(fullname)s,%(data)s)
|
||||||
INSERT INTO public.users (tenant_id, email, role, name, data)
|
RETURNING user_id,email,role,name
|
||||||
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)
|
||||||
au AS (
|
VALUES ((SELECT user_id FROM u), crypt(%(password)s, gen_salt('bf', 12)), FALSE)
|
||||||
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)
|
||||||
INSERT INTO public.projects (tenant_id, name, active)
|
RETURNING tenant_id,project_id, (SELECT api_key FROM t) AS api_key;"""
|
||||||
VALUES ((SELECT t.tenant_id FROM t), %(projectName)s, TRUE)
|
|
||||||
RETURNING tenant_id,project_id;""",
|
with pg_client.PostgresClient() as cur:
|
||||||
{"email": email, "password": password,
|
cur.execute(cur.mogrify(query, params))
|
||||||
"fullname": fullname, "companyName": company_name,
|
cur = cur.fetchone()
|
||||||
"projectName": project_name,
|
project_id = cur["project_id"]
|
||||||
"data": json.dumps({"lastAnnouncementView": TimeUTC.now()})})
|
api_key = cur["api_key"]
|
||||||
cur.execute(
|
|
||||||
query
|
|
||||||
)
|
|
||||||
data = cur.fetchone()
|
|
||||||
telemetry.new_client(tenant_id=data["tenant_id"])
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);"""
|
RETURNING *,(SELECT email FROM users_ee WHERE role = 'owner' AND users_ee.tenant_id = tenants.tenant_id LIMIT 1);"""
|
||||||
)
|
)
|
||||||
data = cur.fetchall()
|
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]})
|
json={"stats": [process_data(d, edition='ee') for d in data]})
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -51,4 +51,4 @@ def new_client(tenant_id):
|
||||||
FROM public.tenants
|
FROM public.tenants
|
||||||
WHERE tenant_id=%(tenant_id)s;""", {"tenant_id": tenant_id}))
|
WHERE tenant_id=%(tenant_id)s;""", {"tenant_id": tenant_id}))
|
||||||
data = cur.fetchone()
|
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'))
|
||||||
|
|
|
||||||
25
ee/api/chalicelib/ee/unlock.py
Normal 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
|
||||||
|
|
@ -21,7 +21,7 @@ def timed(f):
|
||||||
'handle_request', '_generic_handle', 'handle', '_bootstrap_inner', 'run',
|
'handle_request', '_generic_handle', 'handle', '_bootstrap_inner', 'run',
|
||||||
'_bootstrap', '_main_rest_api_handler', '_user_handler',
|
'_bootstrap', '_main_rest_api_handler', '_user_handler',
|
||||||
'_get_view_function_response', 'wrapped_event', 'handle_one_request',
|
'_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))
|
print("DEBUG: %s > %s took %d s to finish" % (" > ".join(call_stack), f.__name__, elapsed))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ def send_team_invitation(recipient, user_name, temp_password, client_id, sender_
|
||||||
formatting_variables={"userName": __escape_text_html(user_name),
|
formatting_variables={"userName": __escape_text_html(user_name),
|
||||||
"password": temp_password, "clientId": client_id,
|
"password": temp_password, "clientId": client_id,
|
||||||
"sender": sender_name})
|
"sender": sender_name})
|
||||||
SUBJECT = "Welcome to Asayer"
|
SUBJECT = "Welcome to OpenReplay"
|
||||||
send_html(BODY_HTML, SUBJECT, recipient)
|
send_html(BODY_HTML, SUBJECT, recipient)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -115,5 +115,5 @@ def weekly_report2(recipients, data):
|
||||||
</table>
|
</table>
|
||||||
</td>"""
|
</td>"""
|
||||||
BODY_HTML = __get_html_from_file("chalicelib/utils/html/Project-Weekly-Report.html", formatting_variables=data)
|
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)
|
send_html(BODY_HTML=BODY_HTML, SUBJECT=SUBJECT, recipient=recipients)
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ class github_formatters:
|
||||||
'createdAt': github_formatters.get_timestamp(issue["created_at"]),
|
'createdAt': github_formatters.get_timestamp(issue["created_at"]),
|
||||||
'closed': issue["closed_at"] is not None,
|
'closed': issue["closed_at"] is not None,
|
||||||
'commentsCount': issue["comments"],
|
'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]
|
'labels': [l["name"] for l in labels]
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
|
|
||||||
|
|
@ -40,17 +40,6 @@ def generate_salt():
|
||||||
return "".join(random.choices(string.hexdigits, k=36))
|
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):
|
def unique_ordered_list(array):
|
||||||
uniq = []
|
uniq = []
|
||||||
[uniq.append(x) for x in array if x not in uniq]
|
[uniq.append(x) for x in array if x not in uniq]
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
<table style="width:100%;font-weight:300;margin-bottom:0;border-collapse:collapse">
|
<table style="width:100%;font-weight:300;margin-bottom:0;border-collapse:collapse">
|
||||||
<tbody><tr style="font-weight:300">
|
<tbody><tr style="font-weight:300">
|
||||||
<td width="125px" style="font-size:14px;padding:0;font-weight:300;margin:0;text-align:left">
|
<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>
|
||||||
<td style="font-size:14px;padding:0;font-weight:300;margin:0;text-align:right">
|
<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">
|
<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: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;">
|
<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>
|
<a href="%(frontend_url)s/client/notifications" style="color:#394EFF;font-weight:300;text-decoration:none" target="_blank" data-saferedirecturl="#">Manage Notifications</a>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td style="padding:10px 30px;">
|
<td style="padding:10px 30px;">
|
||||||
<center>
|
<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>
|
</center>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -38,9 +38,9 @@
|
||||||
<div style="border-top:1px dotted rgba(0,0,0,0.2); display: block; margin-top: 20px"></div>
|
<div style="border-top:1px dotted rgba(0,0,0,0.2); display: block; margin-top: 20px"></div>
|
||||||
<center>
|
<center>
|
||||||
<p style="font-size: 12px; font-family: -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,'Helvetica Neue',sans-serif; color: #6c757d">
|
<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 ♡ from Asayer © 2021 - All rights reserved.<br><br>
|
Sent with ♡ from OpenReplay © 2021 - All rights reserved.<br><br>
|
||||||
<a href="https://asayer.io" target="_blank"
|
<a href="https://openreplay.com" target="_blank"
|
||||||
style="text-decoration: none; color: #6c757d">https://asayer.io/</a>
|
style="text-decoration: none; color: #6c757d">https://openreplay.com/</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
</center>
|
</center>
|
||||||
|
|
|
||||||
|
|
@ -385,7 +385,7 @@ width: 25%!important
|
||||||
<td style="padding-right: 0px;padding-left: 0px;" align="center">
|
<td style="padding-right: 0px;padding-left: 0px;" align="center">
|
||||||
<![endif]-->
|
<![endif]-->
|
||||||
<img style="width=124px; height=35px;" width="124px" height="35px"
|
<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]-->
|
<!--[if mso]></td></tr></table><![endif]-->
|
||||||
</div>
|
</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="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;">
|
<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;">
|
<!-- <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>-->
|
</p>-->
|
||||||
<h1 style="text-align: center; margin-top: 30px; line-height: 30px">Assigned session</h1>
|
<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="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;">
|
<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;">
|
<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;"
|
style="text-decoration: underline; color: #009193;"
|
||||||
title="support@asayer.io">Report an issue</a> | <a
|
title="support@openreplay.com">Report an issue</a> | <a
|
||||||
href="https://asayer.io/" rel="noopener"
|
href="https://openreplay.com/" rel="noopener"
|
||||||
style="text-decoration: underline; color: #009193;" target="_blank">Take
|
style="text-decoration: underline; color: #009193;" target="_blank">Take
|
||||||
a tour</a></p>
|
a tour</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
|
@ -378,7 +378,7 @@ width: 25%!important
|
||||||
<tr style="line-height:0px">
|
<tr style="line-height:0px">
|
||||||
<td style="padding-right: 0px;padding-left: 0px;" align="center">
|
<td style="padding-right: 0px;padding-left: 0px;" align="center">
|
||||||
<![endif]-->
|
<![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]-->
|
<!--[if mso]></td></tr></table><![endif]-->
|
||||||
</div>
|
</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="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;">
|
<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;">
|
<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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</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="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;">
|
<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;">
|
<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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -450,7 +450,7 @@ width: 25%!important
|
||||||
<span style="font-size: 18px;"><a href="%(frontend_url)s"
|
<span style="font-size: 18px;"><a href="%(frontend_url)s"
|
||||||
rel="noopener"
|
rel="noopener"
|
||||||
style="text-decoration: underline; color: #009193;"
|
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>
|
style="font-size: 18px; line-height: 21px;"></span></p>
|
||||||
</div>
|
</div>
|
||||||
</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="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;">
|
<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;">
|
<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;"
|
style="text-decoration: underline; color: #009193;"
|
||||||
title="support@asayer.io">Report an issue</a> | <a
|
title="support@openreplay.com">Report an issue</a> | <a
|
||||||
href="https://asayer.io/" rel="noopener"
|
href="https://openreplay.com/" rel="noopener"
|
||||||
style="text-decoration: underline; color: #009193;" target="_blank">Take
|
style="text-decoration: underline; color: #009193;" target="_blank">Take
|
||||||
a tour</a></p>
|
a tour</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -385,7 +385,7 @@ width: 25%!important
|
||||||
<td style="padding-right: 0px;padding-left: 0px;" align="center">
|
<td style="padding-right: 0px;padding-left: 0px;" align="center">
|
||||||
<![endif]-->
|
<![endif]-->
|
||||||
<img style="width=124px; height=35px;" width="124px" height="35px"
|
<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]-->
|
<!--[if mso]></td></tr></table><![endif]-->
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,19 @@
|
||||||
from botocore.exceptions import ClientError
|
from botocore.exceptions import ClientError
|
||||||
|
from chalicelib.utils.helper import environ
|
||||||
|
from chalicelib.utils import helper
|
||||||
|
|
||||||
import boto3
|
import boto3
|
||||||
|
|
||||||
client = boto3.client('s3')
|
if helper.is_free_open_source_edition() or helper.is_enterprise_edition():
|
||||||
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')
|
||||||
|
else:
|
||||||
|
client = boto3.client('s3')
|
||||||
|
|
||||||
|
|
||||||
def exists(bucket, key):
|
def exists(bucket, key):
|
||||||
|
|
|
||||||
17
ee/api/env_handler.py
Normal 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}")
|
||||||