* fix: changed sessions bucket * fix: text changes in login and signup forms * change: version number * change: config changes * fix: alerts image name * fix: alerts image name * Update README.md * chore(actions): pushing internalized to script. Signed-off-by: Rajesh Rajendran <rjshrjndrn@gmail.com> * feat(nginx): No redirection to HTTPS by default. Signed-off-by: Rajesh Rajendran <rjshrjndrn@gmail.com> * chore(deploy): optional nginx https redirect Signed-off-by: Rajesh Rajendran <rjshrjndrn@gmail.com> * fix: review fixes and other changes * fix: events modal openreplay logo * fix: stack event icon * Changes: - debugging - smtp status - session's issues - session's issue_types as array - changed Slack error message * Changes: - set chalice pull policy to always * fix(openreplay-cli): path issues. Signed-off-by: Rajesh Rajendran <rjshrjndrn@gmail.com> * fix(openreplay-cli): fix path Signed-off-by: Rajesh Rajendran <rjshrjndrn@gmail.com> * change: onboarding explore text changes * change: timeline issue pointers and static issue types * change: removed issues_types api call * connectors * Update README.md * Update README.md * Update README.md * Updating services * Update README.md * Updated alert-notification-string to chalice * Delete issues.md * Changes: - fixed connexion pool exhausted using Semaphores - fixed session-replay-url signing * Changes: - fixed connexion pool exhausted using Semaphores - fixed session-replay-url signing * Change pullPolicy to IfNotPresent * Fixed typo * Fixed typo * Fixed typos * Fixed typo * Fixed typo * Fixed typos * Fixed typos * Fixed typo * Fixed typo * Removed /ws * Update README.md * feat(nginx): increase minio upload size to 50M Signed-off-by: Rajesh Rajendran <rjshrjndrn@gmail.com> * fix(deploy): nginx custom changes are overriden in install Signed-off-by: Rajesh Rajendran <rjshrjndrn@gmail.com> * fix(nginx): deployment indentation issue Signed-off-by: Rajesh Rajendran <rjshrjndrn@gmail.com> * fix: revid filter crash * fix: onboarding links * fix: update password store new token * fix: report issue icon jira/github * fix: onboarding redirect on signup * Changes: - hardcoded S3_HOST * Changes: - changed "sourcemaps" env var to "sourcemaps_reader" - set "sourcemaps_reader" env var value * chore(script): remove logo Signed-off-by: Rajesh Rajendran <rjshrjndrn@gmail.com> * Making domain_name mandatory Signed-off-by: Rajesh Rajendran <rjshrjndrn@gmail.com> * Changes: - un-ignore *.js * feat(install): auto create jwt_secret for chalice. * docs(script): Adding Banner Signed-off-by: Rajesh Rajendran <rjshrjndrn@gmail.com> * chore(script): Remove verbose logging Signed-off-by: Rajesh Rajendran <rjshrjndrn@gmail.com> * Change: - use boto3-resource instead of boto3-client to check if file exists - changed .gitignore to allow *.js files - changed sourcemaps_reader env-var & env-var-value * fix (baxkend-ender): skip inputs with no label (technical) * Change: - changed DB structure * change: removed /flows api call * fix: skipping errorOnFetch check * Change: - changed sourcemaps_reader-nodejs script * Change: - changed sourcemaps_reader-nodejs script * fix (backend-postgres): correct autocomplete type-value * fix: slack webhooks PUT call * change: added external icon for integration doc links * fix: updated the sourcemap upload doc link * fix: link color of no sessions message * fix (frontend-player): show original domContentLoaded text values, while adjusted on timeline * fix (frontend-player): syntax * Changes: - changed requirements - changed slack add integration - added slack edit integration - removed sourcemaps_reader extra payload * Changes: - fixed sentry-issue-reporter - fixed telemetry reporter - fixed DB schema * fix(cli): fix logs flag Signed-off-by: Rajesh Rajendran <rjshrjndrn@gmail.com> * ci(deploy): Injecting domain_name Signed-off-by: Rajesh Rajendran <rjshrjndrn@gmail.com> * feat(nginx): Get real client ip Signed-off-by: Rajesh Rajendran <rjshrjndrn@gmail.com> * chore(nginx): restart on helm installation. Signed-off-by: Rajesh Rajendran <rjshrjndrn@gmail.com> * fix(deployment): respect image tags. * Changes: - changed sentry tags - changed asayer_session_id to openReplaySessionToken - EE full merge * fix: close the issue modal after creating * fix: show description in issue details modal * fix: integrate slack button redirect, and doc link * fix: code snippet conflict set back * fix: slack share channel selection * Changes: - fixed DB structure * Changes: - return full integration body on add slack * fix (integrations): ignore token expired + some logs * feat (sourcemaps-uploader): v.3.0.2 filename fix + logging arg * fix (tracker): 3.0.3 version: start before auth * fix: funnel calendar position * fix: fetch issue types * fix: missing icon blocking the session to play * change: sessions per browser widget bar height reduced * fix: github colored circles * Changes: - changed session-assignment-jira response * chore(nginx): pass x-forward-for Signed-off-by: Rajesh Rajendran <rjshrjndrn@gmail.com> * feat(chalice): included sourcemaps_reader It's not advised to run multiple processes in a single docker container. In Kubernetes we can run this as sidecar, but other platforms such as Heroku, and vanilla docker doesn't support such feature. So till we figure out better solution, this is the workaround. * chore(install): Remove sqs * feat(deployment): restart pods on installations. Signed-off-by: Rajesh Rajendran <rjshrjndrn@gmail.com> * Changes: - changed DB-oauth-unique constraint Co-authored-by: Shekar Siri <sshekarsiri@gmail.com> Co-authored-by: Mehdi Osman <estradino@users.noreply.github.com> Co-authored-by: KRAIEM Taha Yassine <tahayk2@gmail.com> Co-authored-by: ourvakan <hi-psi@yandex.com> Co-authored-by: ShiKhu <alex.kaminsky.11@gmail.com>
885 lines
34 KiB
Python
885 lines
34 KiB
Python
from chalicelib.utils.helper import environ
|
|
|
|
from chalice import Blueprint
|
|
from chalice import Response
|
|
|
|
from chalicelib import _overrides
|
|
from chalicelib.blueprints import bp_authorizers
|
|
from chalicelib.core import log_tool_rollbar, sourcemaps, events, sessions_assignments, projects, \
|
|
sessions_metas, alerts, funnels, issues, integrations_manager, errors_favorite_viewed, metadata, \
|
|
log_tool_elasticsearch, log_tool_datadog, \
|
|
log_tool_stackdriver, reset_password, sessions_favorite_viewed, \
|
|
log_tool_cloudwatch, log_tool_sentry, log_tool_sumologic, log_tools, errors, sessions, \
|
|
log_tool_newrelic, announcements, log_tool_bugsnag, weekly_report, integration_jira_cloud, integration_github
|
|
from chalicelib.core.collaboration_slack import Slack
|
|
from chalicelib.utils import email_helper
|
|
|
|
app = Blueprint(__name__)
|
|
_overrides.chalice_app(app)
|
|
|
|
|
|
@app.route('/{projectId}/sessions2/favorite', methods=['GET'])
|
|
def get_favorite_sessions2(projectId, context):
|
|
params = app.current_request.query_params
|
|
|
|
return {
|
|
'data': sessions.get_favorite_sessions(project_id=projectId, user_id=context["userId"], include_viewed=True)
|
|
}
|
|
|
|
|
|
@app.route('/{projectId}/sessions2/{sessionId}', methods=['GET'])
|
|
def get_session2(projectId, sessionId, context):
|
|
data = sessions.get_by_id2_pg(project_id=projectId, session_id=sessionId, full_data=True, user_id=context["userId"],
|
|
include_fav_viewed=True, group_metadata=True)
|
|
if data is not None:
|
|
sessions_favorite_viewed.view_session(project_id=projectId, user_id=context['userId'], session_id=sessionId)
|
|
return {
|
|
'data': data
|
|
}
|
|
|
|
|
|
@app.route('/{projectId}/sessions2/{sessionId}/favorite', methods=['GET'])
|
|
def add_remove_favorite_session2(projectId, sessionId, context):
|
|
return {
|
|
"data": sessions_favorite_viewed.favorite_session(project_id=projectId, user_id=context['userId'],
|
|
session_id=sessionId)}
|
|
|
|
|
|
@app.route('/{projectId}/sessions2/{sessionId}/assign', methods=['GET'])
|
|
def assign_session(projectId, sessionId, context):
|
|
data = sessions_assignments.get_by_session(project_id=projectId, session_id=sessionId,
|
|
tenant_id=context['tenantId'],
|
|
user_id=context["userId"])
|
|
if "errors" in data:
|
|
return data
|
|
return {
|
|
'data': data
|
|
}
|
|
|
|
|
|
@app.route('/{projectId}/sessions2/{sessionId}/errors/{errorId}/sourcemaps', methods=['GET'])
|
|
def get_error_trace(projectId, sessionId, errorId, context):
|
|
data = errors.get_trace(project_id=projectId, error_id=errorId)
|
|
if "errors" in data:
|
|
return data
|
|
return {
|
|
'data': data
|
|
}
|
|
|
|
|
|
@app.route('/{projectId}/sessions2/{sessionId}/assign/{issueId}', methods=['GET'])
|
|
def assign_session(projectId, sessionId, issueId, context):
|
|
data = sessions_assignments.get(project_id=projectId, session_id=sessionId, assignment_id=issueId,
|
|
tenant_id=context['tenantId'], user_id=context["userId"])
|
|
if "errors" in data:
|
|
return data
|
|
return {
|
|
'data': data
|
|
}
|
|
|
|
|
|
@app.route('/{projectId}/sessions2/{sessionId}/assign/{issueId}/comment', methods=['POST', 'PUT'])
|
|
def comment_assignment(projectId, sessionId, issueId, context):
|
|
data = app.current_request.json_body
|
|
data = sessions_assignments.comment(tenant_id=context['tenantId'], project_id=projectId,
|
|
session_id=sessionId, assignment_id=issueId,
|
|
user_id=context["userId"], message=data["message"])
|
|
if "errors" in data.keys():
|
|
return data
|
|
return {
|
|
'data': data
|
|
}
|
|
|
|
|
|
@app.route('/{projectId}/events/search', methods=['GET'])
|
|
def events_search(projectId, context):
|
|
params = app.current_request.query_params
|
|
if params is None:
|
|
return {"data": []}
|
|
|
|
q = params.get('q', '')
|
|
if len(q) == 0:
|
|
return {"data": []}
|
|
result = events.search_pg2(q, params.get('type', ''), project_id=projectId, source=params.get('source'),
|
|
key=params.get("key"))
|
|
return result
|
|
|
|
|
|
@app.route('/{projectId}/sessions/search2', methods=['POST'])
|
|
def sessions_search2(projectId, context):
|
|
data = app.current_request.json_body
|
|
|
|
data = sessions.search2_pg(data, projectId, user_id=context["userId"])
|
|
return {'data': data}
|
|
|
|
|
|
@app.route('/{projectId}/sessions/filters', methods=['GET'])
|
|
def session_filter_values(projectId, context):
|
|
return {'data': sessions_metas.get_key_values(projectId)}
|
|
|
|
|
|
@app.route('/{projectId}/sessions/filters/top', methods=['GET'])
|
|
def session_top_filter_values(projectId, context):
|
|
return {'data': sessions_metas.get_top_key_values(projectId)}
|
|
|
|
|
|
@app.route('/{projectId}/sessions/filters/search', methods=['GET'])
|
|
def get_session_filters_meta(projectId, context):
|
|
params = app.current_request.query_params
|
|
if params is None:
|
|
return {"data": []}
|
|
|
|
meta_type = params.get('type', '')
|
|
if len(meta_type) == 0:
|
|
return {"data": []}
|
|
q = params.get('q', '')
|
|
if len(q) == 0:
|
|
return {"data": []}
|
|
return sessions_metas.search(project_id=projectId, meta_type=meta_type, text=q)
|
|
|
|
|
|
@app.route('/{projectId}/integrations/{integration}/notify/{integrationId}/{source}/{sourceId}',
|
|
methods=['POST', 'PUT'])
|
|
def integration_notify(projectId, integration, integrationId, source, sourceId, context):
|
|
data = app.current_request.json_body
|
|
comment = None
|
|
if "comment" in data:
|
|
comment = data["comment"]
|
|
if integration == "slack":
|
|
args = {"tenant_id": context["tenantId"],
|
|
"user": context['email'], "comment": comment, "project_id": projectId,
|
|
"integration_id": integrationId}
|
|
if source == "sessions":
|
|
return Slack.share_session(session_id=sourceId, **args)
|
|
elif source == "errors":
|
|
return Slack.share_error(error_id=sourceId, **args)
|
|
return {"data": None}
|
|
|
|
|
|
@app.route('/integrations/sentry', methods=['GET'])
|
|
def get_all_sentry(context):
|
|
return {"data": log_tool_sentry.get_all(tenant_id=context["tenantId"])}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/sentry', methods=['GET'])
|
|
def get_sentry(projectId, context):
|
|
return {"data": log_tool_sentry.get(project_id=projectId)}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/sentry', methods=['POST', 'PUT'])
|
|
def add_edit_sentry(projectId, context):
|
|
data = app.current_request.json_body
|
|
|
|
return {"data": log_tool_sentry.add_edit(tenant_id=context["tenantId"], project_id=projectId, data=data)}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/sentry', methods=['DELETE'])
|
|
def delete_sentry(projectId, context):
|
|
return {"data": log_tool_sentry.delete(tenant_id=context["tenantId"], project_id=projectId)}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/sentry/events/{eventId}', methods=['GET'])
|
|
def proxy_sentry(projectId, eventId, context):
|
|
return {"data": log_tool_sentry.proxy_get(tenant_id=context["tenantId"], project_id=projectId, event_id=eventId)}
|
|
|
|
|
|
@app.route('/integrations/datadog', methods=['GET'])
|
|
def get_all_datadog(context):
|
|
return {"data": log_tool_datadog.get_all(tenant_id=context["tenantId"])}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/datadog', methods=['GET'])
|
|
def get_datadog(projectId, context):
|
|
return {"data": log_tool_datadog.get(project_id=projectId)}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/datadog', methods=['POST', 'PUT'])
|
|
def add_edit_datadog(projectId, context):
|
|
data = app.current_request.json_body
|
|
|
|
return {"data": log_tool_datadog.add_edit(tenant_id=context["tenantId"], project_id=projectId, data=data)}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/datadog', methods=['DELETE'])
|
|
def delete_datadog(projectId, context):
|
|
return {"data": log_tool_datadog.delete(tenant_id=context["tenantId"], project_id=projectId)}
|
|
|
|
|
|
@app.route('/integrations/stackdriver', methods=['GET'])
|
|
def get_all_stackdriver(context):
|
|
return {"data": log_tool_stackdriver.get_all(tenant_id=context["tenantId"])}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/stackdriver', methods=['GET'])
|
|
def get_stackdriver(projectId, context):
|
|
return {"data": log_tool_stackdriver.get(project_id=projectId)}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/stackdriver', methods=['POST', 'PUT'])
|
|
def add_edit_stackdriver(projectId, context):
|
|
data = app.current_request.json_body
|
|
|
|
return {"data": log_tool_stackdriver.add_edit(tenant_id=context["tenantId"], project_id=projectId, data=data)}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/stackdriver', methods=['DELETE'])
|
|
def delete_stackdriver(projectId, context):
|
|
return {"data": log_tool_stackdriver.delete(tenant_id=context["tenantId"], project_id=projectId)}
|
|
|
|
|
|
@app.route('/integrations/newrelic', methods=['GET'])
|
|
def get_all_newrelic(context):
|
|
return {"data": log_tool_newrelic.get_all(tenant_id=context["tenantId"])}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/newrelic', methods=['GET'])
|
|
def get_newrelic(projectId, context):
|
|
return {"data": log_tool_newrelic.get(project_id=projectId)}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/newrelic', methods=['POST', 'PUT'])
|
|
def add_edit_newrelic(projectId, context):
|
|
data = app.current_request.json_body
|
|
|
|
return {"data": log_tool_newrelic.add_edit(tenant_id=context["tenantId"], project_id=projectId, data=data)}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/newrelic', methods=['DELETE'])
|
|
def delete_newrelic(projectId, context):
|
|
return {"data": log_tool_newrelic.delete(tenant_id=context["tenantId"], project_id=projectId)}
|
|
|
|
|
|
@app.route('/integrations/rollbar', methods=['GET'])
|
|
def get_all_rollbar(context):
|
|
return {"data": log_tool_rollbar.get_all(tenant_id=context["tenantId"])}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/rollbar', methods=['GET'])
|
|
def get_rollbar(projectId, context):
|
|
return {"data": log_tool_rollbar.get(project_id=projectId)}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/rollbar', methods=['POST', 'PUT'])
|
|
def add_edit_rollbar(projectId, context):
|
|
data = app.current_request.json_body
|
|
|
|
return {"data": log_tool_rollbar.add_edit(tenant_id=context["tenantId"], project_id=projectId, data=data)}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/rollbar', methods=['DELETE'])
|
|
def delete_datadog(projectId, context):
|
|
return {"data": log_tool_rollbar.delete(tenant_id=context["tenantId"], project_id=projectId)}
|
|
|
|
|
|
@app.route('/integrations/bugsnag/list_projects', methods=['POST'])
|
|
def list_projects_bugsnag(context):
|
|
data = app.current_request.json_body
|
|
return {"data": log_tool_bugsnag.list_projects(auth_token=data["authorizationToken"])}
|
|
|
|
|
|
@app.route('/integrations/bugsnag', methods=['GET'])
|
|
def get_all_bugsnag(context):
|
|
return {"data": log_tool_bugsnag.get_all(tenant_id=context["tenantId"])}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/bugsnag', methods=['GET'])
|
|
def get_bugsnag(projectId, context):
|
|
return {"data": log_tool_bugsnag.get(project_id=projectId)}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/bugsnag', methods=['POST', 'PUT'])
|
|
def add_edit_bugsnag(projectId, context):
|
|
data = app.current_request.json_body
|
|
|
|
return {"data": log_tool_bugsnag.add_edit(tenant_id=context["tenantId"], project_id=projectId, data=data)}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/bugsnag', methods=['DELETE'])
|
|
def delete_bugsnag(projectId, context):
|
|
return {"data": log_tool_bugsnag.delete(tenant_id=context["tenantId"], project_id=projectId)}
|
|
|
|
|
|
@app.route('/integrations/cloudwatch/list_groups', methods=['POST'])
|
|
def list_groups_cloudwatch(context):
|
|
data = app.current_request.json_body
|
|
return {"data": log_tool_cloudwatch.list_log_groups(aws_access_key_id=data["awsAccessKeyId"],
|
|
aws_secret_access_key=data["awsSecretAccessKey"],
|
|
region=data["region"])}
|
|
|
|
|
|
@app.route('/integrations/cloudwatch', methods=['GET'])
|
|
def get_all_cloudwatch(context):
|
|
return {"data": log_tool_cloudwatch.get_all(tenant_id=context["tenantId"])}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/cloudwatch', methods=['GET'])
|
|
def get_cloudwatch(projectId, context):
|
|
return {"data": log_tool_cloudwatch.get(project_id=projectId)}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/cloudwatch', methods=['POST', 'PUT'])
|
|
def add_edit_cloudwatch(projectId, context):
|
|
data = app.current_request.json_body
|
|
|
|
return {"data": log_tool_cloudwatch.add_edit(tenant_id=context["tenantId"], project_id=projectId, data=data)}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/cloudwatch', methods=['DELETE'])
|
|
def delete_cloudwatch(projectId, context):
|
|
return {"data": log_tool_cloudwatch.delete(tenant_id=context["tenantId"], project_id=projectId)}
|
|
|
|
|
|
@app.route('/integrations/elasticsearch', methods=['GET'])
|
|
def get_all_elasticsearch(context):
|
|
return {"data": log_tool_elasticsearch.get_all(tenant_id=context["tenantId"])}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/elasticsearch', methods=['GET'])
|
|
def get_elasticsearch(projectId, context):
|
|
return {"data": log_tool_elasticsearch.get(project_id=projectId)}
|
|
|
|
|
|
@app.route('/integrations/elasticsearch/test', methods=['POST'])
|
|
def test_elasticsearch_connection(context):
|
|
data = app.current_request.json_body
|
|
return {"data": log_tool_elasticsearch.ping(tenant_id=context["tenantId"], **data)}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/elasticsearch', methods=['POST', 'PUT'])
|
|
def add_edit_elasticsearch(projectId, context):
|
|
data = app.current_request.json_body
|
|
|
|
return {"data": log_tool_elasticsearch.add_edit(tenant_id=context["tenantId"], project_id=projectId, data=data)}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/elasticsearch', methods=['DELETE'])
|
|
def delete_elasticsearch(projectId, context):
|
|
return {"data": log_tool_elasticsearch.delete(tenant_id=context["tenantId"], project_id=projectId)}
|
|
|
|
|
|
@app.route('/integrations/sumologic', methods=['GET'])
|
|
def get_all_sumologic(context):
|
|
return {"data": log_tool_sumologic.get_all(tenant_id=context["tenantId"])}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/sumologic', methods=['GET'])
|
|
def get_sumologic(projectId, context):
|
|
return {"data": log_tool_sumologic.get(project_id=projectId)}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/sumologic', methods=['POST', 'PUT'])
|
|
def add_edit_sumologic(projectId, context):
|
|
data = app.current_request.json_body
|
|
|
|
return {"data": log_tool_sumologic.add_edit(tenant_id=context["tenantId"], project_id=projectId, data=data)}
|
|
|
|
|
|
@app.route('/{projectId}/integrations/sumologic', methods=['DELETE'])
|
|
def delete_sumologic(projectId, context):
|
|
return {"data": log_tool_sumologic.delete(tenant_id=context["tenantId"], project_id=projectId)}
|
|
|
|
|
|
@app.route('/integrations/issues', methods=['GET'])
|
|
def get_integration_status(context):
|
|
error, integration = integrations_manager.get_integration(tenant_id=context["tenantId"],
|
|
user_id=context["userId"])
|
|
if error is not None:
|
|
return {"data": {}}
|
|
return {"data": integration.get_obfuscated()}
|
|
|
|
|
|
@app.route('/integrations/jira', methods=['POST', 'PUT'])
|
|
def add_edit_jira_cloud(context):
|
|
data = app.current_request.json_body
|
|
error, integration = integrations_manager.get_integration(tool=integration_jira_cloud.PROVIDER,
|
|
tenant_id=context["tenantId"],
|
|
user_id=context["userId"])
|
|
if error is not None:
|
|
return error
|
|
return {"data": integration.add_edit(data=data)}
|
|
|
|
|
|
@app.route('/integrations/github', methods=['POST', 'PUT'])
|
|
def add_edit_github(context):
|
|
data = app.current_request.json_body
|
|
error, integration = integrations_manager.get_integration(tool=integration_github.PROVIDER,
|
|
tenant_id=context["tenantId"],
|
|
user_id=context["userId"])
|
|
if error is not None:
|
|
return error
|
|
return {"data": integration.add_edit(data=data)}
|
|
|
|
|
|
@app.route('/integrations/issues', methods=['DELETE'])
|
|
def delete_default_issue_tracking_tool(context):
|
|
error, integration = integrations_manager.get_integration(tenant_id=context["tenantId"],
|
|
user_id=context["userId"])
|
|
if error is not None:
|
|
return error
|
|
return {"data": integration.delete()}
|
|
|
|
|
|
@app.route('/integrations/jira', methods=['DELETE'])
|
|
def delete_jira_cloud(context):
|
|
error, integration = integrations_manager.get_integration(tool=integration_jira_cloud.PROVIDER,
|
|
tenant_id=context["tenantId"],
|
|
user_id=context["userId"])
|
|
if error is not None:
|
|
return error
|
|
return {"data": integration.delete()}
|
|
|
|
|
|
@app.route('/integrations/github', methods=['DELETE'])
|
|
def delete_github(context):
|
|
error, integration = integrations_manager.get_integration(tool=integration_github.PROVIDER,
|
|
tenant_id=context["tenantId"],
|
|
user_id=context["userId"])
|
|
if error is not None:
|
|
return error
|
|
return {"data": integration.delete()}
|
|
|
|
|
|
@app.route('/integrations/issues/list_projects', methods=['GET'])
|
|
def get_all_issue_tracking_projects(context):
|
|
error, integration = integrations_manager.get_integration(tenant_id=context["tenantId"],
|
|
user_id=context["userId"])
|
|
if error is not None:
|
|
return error
|
|
data = integration.issue_handler.get_projects()
|
|
if "errors" in data:
|
|
return data
|
|
return {"data": data}
|
|
|
|
|
|
@app.route('/integrations/issues/{integrationProjectId}', methods=['GET'])
|
|
def get_integration_metadata(integrationProjectId, context):
|
|
error, integration = integrations_manager.get_integration(tenant_id=context["tenantId"],
|
|
user_id=context["userId"])
|
|
if error is not None:
|
|
return error
|
|
data = integration.issue_handler.get_metas(integrationProjectId)
|
|
if "errors" in data.keys():
|
|
return data
|
|
return {"data": data}
|
|
|
|
|
|
@app.route('/{projectId}/assignments', methods=['GET'])
|
|
def get_all_assignments(projectId, context):
|
|
data = sessions_assignments.get_all(project_id=projectId, user_id=context["userId"])
|
|
return {
|
|
'data': data
|
|
}
|
|
|
|
|
|
@app.route('/{projectId}/sessions2/{sessionId}/assign/projects/{integrationProjectId}', methods=['POST', 'PUT'])
|
|
def create_issue_assignment(projectId, sessionId, integrationProjectId, context):
|
|
data = app.current_request.json_body
|
|
data = sessions_assignments.create_new_assignment(tenant_id=context['tenantId'], project_id=projectId,
|
|
session_id=sessionId,
|
|
creator_id=context["userId"], assignee=data["assignee"],
|
|
description=data["description"], title=data["title"],
|
|
issue_type=data["issueType"],
|
|
integration_project_id=integrationProjectId)
|
|
if "errors" in data.keys():
|
|
return data
|
|
return {
|
|
'data': data
|
|
}
|
|
|
|
|
|
@app.route('/{projectId}/gdpr', methods=['GET'])
|
|
def get_gdpr(projectId, context):
|
|
return {"data": projects.get_gdpr(project_id=projectId)}
|
|
|
|
|
|
@app.route('/{projectId}/gdpr', methods=['POST', 'PUT'])
|
|
def edit_gdpr(projectId, context):
|
|
data = app.current_request.json_body
|
|
|
|
return {"data": projects.edit_gdpr(project_id=projectId, gdpr=data)}
|
|
|
|
|
|
@app.route('/password/reset/{step}', methods=['PUT', 'POST'], authorizer=None)
|
|
def reset_password_handler(step):
|
|
data = app.current_request.json_body
|
|
if step == "1":
|
|
if "email" not in data or len(data["email"]) < 5:
|
|
return {"errors": ["please provide a valid email address"]}
|
|
return reset_password.step1(data)
|
|
elif step == "2":
|
|
return reset_password.step2(data)
|
|
|
|
|
|
@app.route('/{projectId}/metadata', methods=['GET'])
|
|
def get_metadata(projectId, context):
|
|
return {"data": metadata.get(project_id=projectId)}
|
|
|
|
|
|
@app.route('/{projectId}/metadata/list', methods=['POST', 'PUT'])
|
|
def add_edit_delete_metadata(projectId, context):
|
|
data = app.current_request.json_body
|
|
|
|
return metadata.add_edit_delete(tenant_id=context["tenantId"], project_id=projectId, new_metas=data["list"])
|
|
|
|
|
|
@app.route('/{projectId}/metadata', methods=['POST', 'PUT'])
|
|
def add_metadata(projectId, context):
|
|
data = app.current_request.json_body
|
|
|
|
return metadata.add(tenant_id=context["tenantId"], project_id=projectId, new_name=data["key"])
|
|
|
|
|
|
@app.route('/{projectId}/metadata/{index}', methods=['POST', 'PUT'])
|
|
def edit_metadata(projectId, index, context):
|
|
data = app.current_request.json_body
|
|
|
|
return metadata.edit(tenant_id=context["tenantId"], project_id=projectId, index=int(index),
|
|
new_name=data["key"])
|
|
|
|
|
|
@app.route('/{projectId}/metadata/{index}', methods=['DELETE'])
|
|
def delete_metadata(projectId, index, context):
|
|
return metadata.delete(tenant_id=context["tenantId"], project_id=projectId, index=index)
|
|
|
|
|
|
@app.route('/{projectId}/metadata/search', methods=['GET'])
|
|
def search_metadata(projectId, context):
|
|
params = app.current_request.query_params
|
|
q = params.get('q', '')
|
|
key = params.get('key', '')
|
|
if len(q) == 0 and len(key) == 0:
|
|
return {"data": []}
|
|
if len(q) == 0:
|
|
return {"errors": ["please provide a value for search"]}
|
|
if len(key) == 0:
|
|
return {"errors": ["please provide a key for search"]}
|
|
return metadata.search(tenant_id=context["tenantId"], project_id=projectId, value=q, key=key)
|
|
|
|
|
|
@app.route('/{projectId}/integration/sources', methods=['GET'])
|
|
def search_integrations(projectId, context):
|
|
return log_tools.search(project_id=projectId)
|
|
|
|
|
|
@app.route('/async/email_assignment', methods=['POST', 'PUT'], authorizer=None)
|
|
def async_send_signup_emails():
|
|
data = app.current_request.json_body
|
|
if data.pop("auth") != environ["async_Token"]:
|
|
return {}
|
|
email_helper.send_assign_session(recipient=data["email"], link=data["link"], message=data["message"])
|
|
|
|
|
|
@app.route('/async/funnel/weekly_report2', methods=['POST', 'PUT'], authorizer=None)
|
|
def async_weekly_report():
|
|
print("=========================> Sending weekly report")
|
|
data = app.current_request.json_body
|
|
if data.pop("auth") != environ["async_Token"]:
|
|
return {}
|
|
email_helper.weekly_report2(recipients=data["email"], data=data.get("data", None))
|
|
|
|
|
|
@app.route('/async/basic/{step}', methods=['POST', 'PUT'], authorizer=None)
|
|
def async_basic_emails(step):
|
|
data = app.current_request.json_body
|
|
if data.pop("auth") != environ["async_Token"]:
|
|
return {}
|
|
if step.lower() == "member_invitation":
|
|
email_helper.send_team_invitation(recipient=data["email"], user_name=data["userName"],
|
|
temp_password=data["tempPassword"], client_id=data["clientId"],
|
|
sender_name=data["senderName"])
|
|
|
|
|
|
@app.route('/{projectId}/sample_rate', methods=['GET'])
|
|
def get_capture_status(projectId, context):
|
|
return {"data": projects.get_capture_status(project_id=projectId)}
|
|
|
|
|
|
@app.route('/{projectId}/sample_rate', methods=['POST', 'PUT'])
|
|
def update_capture_status(projectId, context):
|
|
data = app.current_request.json_body
|
|
|
|
return {"data": projects.update_capture_status(project_id=projectId, changes=data)}
|
|
|
|
|
|
@app.route('/announcements', methods=['GET'])
|
|
def get_all_announcements(context):
|
|
return {"data": announcements.get_all(context["userId"])}
|
|
|
|
|
|
@app.route('/announcements/view', methods=['GET'])
|
|
def get_all_announcements(context):
|
|
return {"data": announcements.view(user_id=context["userId"])}
|
|
|
|
|
|
@app.route('/{projectId}/errors/{errorId}/{action}', methods=['GET'])
|
|
def add_remove_favorite_error(projectId, errorId, action, context):
|
|
if action == "favorite":
|
|
return errors_favorite_viewed.favorite_error(project_id=projectId, user_id=context['userId'], error_id=errorId)
|
|
elif action == "sessions":
|
|
params = app.current_request.query_params
|
|
if params is None:
|
|
params = {}
|
|
start_date = params.get("startDate")
|
|
end_date = params.get("endDate")
|
|
return {
|
|
"data": errors.get_sessions(project_id=projectId, user_id=context['userId'], error_id=errorId,
|
|
start_date=start_date, end_date=end_date)}
|
|
elif action in list(errors.ACTION_STATE.keys()):
|
|
return errors.change_state(project_id=projectId, user_id=context['userId'], error_id=errorId, action=action)
|
|
else:
|
|
return {"errors": ["undefined action"]}
|
|
|
|
|
|
@app.route('/{projectId}/errors/merge', methods=['POST'])
|
|
def errors_merge(projectId, context):
|
|
data = app.current_request.json_body
|
|
|
|
data = errors.merge(error_ids=data.get("errors", []))
|
|
return data
|
|
|
|
|
|
@app.route('/show_banner', methods=['GET'])
|
|
def errors_merge(context):
|
|
return {"data": False}
|
|
|
|
|
|
@app.route('/{projectId}/alerts', methods=['POST', 'PUT'])
|
|
def create_alert(projectId, context):
|
|
data = app.current_request.json_body
|
|
return alerts.create(projectId, data)
|
|
|
|
|
|
@app.route('/{projectId}/alerts', methods=['GET'])
|
|
def get_all_alerts(projectId, context):
|
|
return {"data": alerts.get_all(projectId)}
|
|
|
|
|
|
@app.route('/{projectId}/alerts/{alertId}', methods=['GET'])
|
|
def get_alert(projectId, alertId, context):
|
|
return {"data": alerts.get(alertId)}
|
|
|
|
|
|
@app.route('/{projectId}/alerts/{alertId}', methods=['POST', 'PUT'])
|
|
def update_alert(projectId, alertId, context):
|
|
data = app.current_request.json_body
|
|
return alerts.update(alertId, data)
|
|
|
|
|
|
@app.route('/{projectId}/alerts/{alertId}', methods=['DELETE'])
|
|
def delete_alert(projectId, alertId, context):
|
|
return alerts.delete(projectId, alertId)
|
|
|
|
|
|
@app.route('/alerts/notifications', methods=['POST', 'PUT'], authorizer=None)
|
|
def send_alerts_notifications():
|
|
data = app.current_request.json_body
|
|
if data.get("token", "") != "nF46JdQqAM5v9KI9lPMpcu8o9xiJGvNNWOGL7TJP":
|
|
return {"errors": ["missing token"]}
|
|
return {"data": alerts.process_notifications(data.get("notifications", []))}
|
|
|
|
|
|
@app.route('/{projectId}/funnels', methods=['POST', 'PUT'])
|
|
def add_funnel(projectId, context):
|
|
data = app.current_request.json_body
|
|
return funnels.create(project_id=projectId,
|
|
user_id=context['userId'],
|
|
name=data["name"],
|
|
filter=data["filter"],
|
|
is_public=data.get("isPublic", False))
|
|
|
|
|
|
@app.route('/{projectId}/funnels', methods=['GET'])
|
|
def get_funnels(projectId, context):
|
|
params = app.current_request.query_params
|
|
if params is None:
|
|
params = {}
|
|
|
|
return {"data": funnels.get_by_user(project_id=projectId,
|
|
user_id=context['userId'],
|
|
range_value=None,
|
|
start_date=None,
|
|
end_date=None,
|
|
details=False)}
|
|
|
|
|
|
@app.route('/{projectId}/funnels/details', methods=['GET'])
|
|
def get_funnels_with_details(projectId, context):
|
|
params = app.current_request.query_params
|
|
if params is None:
|
|
params = {}
|
|
|
|
return {"data": funnels.get_by_user(project_id=projectId,
|
|
user_id=context['userId'],
|
|
range_value=params.get("rangeValue", None),
|
|
start_date=params.get('startDate', None),
|
|
end_date=params.get('endDate', None),
|
|
details=True)}
|
|
|
|
|
|
@app.route('/{projectId}/funnels/issue_types', methods=['GET'])
|
|
def get_possible_issue_types(projectId, context):
|
|
params = app.current_request.query_params
|
|
if params is None:
|
|
params = {}
|
|
|
|
return {"data": funnels.get_possible_issue_types(project_id=projectId)}
|
|
|
|
|
|
@app.route('/{projectId}/funnels/{funnelId}/insights', methods=['GET'])
|
|
def get_funnel_insights(projectId, funnelId, context):
|
|
params = app.current_request.query_params
|
|
if params is None:
|
|
params = {}
|
|
|
|
return {"data": funnels.get_top_insights(funnel_id=funnelId, project_id=projectId,
|
|
range_value=params.get("range_value", None),
|
|
start_date=params.get('startDate', None),
|
|
end_date=params.get('endDate', None))}
|
|
|
|
|
|
@app.route('/{projectId}/funnels/{funnelId}/insights', methods=['POST', 'PUT'])
|
|
def get_funnel_insights_on_the_fly(projectId, funnelId, context):
|
|
params = app.current_request.query_params
|
|
if params is None:
|
|
params = {}
|
|
data = app.current_request.json_body
|
|
if data is None:
|
|
data = {}
|
|
|
|
return {
|
|
"data": funnels.get_top_insights_on_the_fly(funnel_id=funnelId, project_id=projectId, data={**params, **data})}
|
|
|
|
|
|
@app.route('/{projectId}/funnels/{funnelId}/issues', methods=['GET'])
|
|
def get_funnel_issues(projectId, funnelId, context):
|
|
params = app.current_request.query_params
|
|
if params is None:
|
|
params = {}
|
|
|
|
return funnels.get_issues(funnel_id=funnelId, project_id=projectId,
|
|
range_value=params.get("range_value", None),
|
|
start_date=params.get('startDate', None), end_date=params.get('endDate', None))
|
|
|
|
|
|
@app.route('/{projectId}/funnels/{funnelId}/issues', methods=['POST', 'PUT'])
|
|
def get_funnel_issues_on_the_fly(projectId, funnelId, context):
|
|
params = app.current_request.query_params
|
|
if params is None:
|
|
params = {}
|
|
data = app.current_request.json_body
|
|
if data is None:
|
|
data = {}
|
|
|
|
return {"data": funnels.get_issues_on_the_fly(funnel_id=funnelId, project_id=projectId, data={**params, **data})}
|
|
|
|
|
|
@app.route('/{projectId}/funnels/{funnelId}/sessions', methods=['GET'])
|
|
def get_funnel_sessions(projectId, funnelId, context):
|
|
params = app.current_request.query_params
|
|
if params is None:
|
|
params = {}
|
|
|
|
return {"data": funnels.get_sessions(funnel_id=funnelId, user_id=context['userId'], project_id=projectId,
|
|
range_value=params.get("range_value", None),
|
|
start_date=params.get('startDate', None),
|
|
end_date=params.get('endDate', None))}
|
|
|
|
|
|
@app.route('/{projectId}/funnels/{funnelId}/sessions', methods=['POST', 'PUT'])
|
|
def get_funnel_sessions_on_the_fly(projectId, funnelId, context):
|
|
params = app.current_request.query_params
|
|
if params is None:
|
|
params = {}
|
|
data = app.current_request.json_body
|
|
if data is None:
|
|
data = {}
|
|
return {"data": funnels.get_sessions_on_the_fly(funnel_id=funnelId, user_id=context['userId'], project_id=projectId,
|
|
data={**params, **data})}
|
|
|
|
|
|
@app.route('/{projectId}/funnels/issues/{issueId}/sessions', methods=['GET'])
|
|
def get_issue_sessions(projectId, issueId, context):
|
|
params = app.current_request.query_params
|
|
if params is None:
|
|
params = {}
|
|
|
|
issue = issues.get(project_id=projectId, issue_id=issueId)
|
|
return {
|
|
"data": {"sessions": sessions.search_by_issue(user_id=context["userId"], project_id=projectId, issue=issue,
|
|
start_date=params.get('startDate', None),
|
|
end_date=params.get('endDate', None)),
|
|
"issue": issue}}
|
|
|
|
|
|
@app.route('/{projectId}/funnels/{funnelId}/issues/{issueId}/sessions', methods=['POST', 'PUT'])
|
|
def get_funnel_issue_sessions(projectId, funnelId, issueId, context):
|
|
data = app.current_request.json_body
|
|
|
|
data = funnels.search_by_issue(project_id=projectId, user_id=context["userId"], issue_id=issueId,
|
|
funnel_id=funnelId, data=data)
|
|
if "errors" in data:
|
|
return data
|
|
if data.get("issue") is None:
|
|
data["issue"] = issues.get(project_id=projectId, issue_id=issueId)
|
|
return {
|
|
"data": data
|
|
}
|
|
|
|
|
|
@app.route('/{projectId}/funnels/{funnelId}', methods=['GET'])
|
|
def get_funnel(projectId, funnelId, context):
|
|
return {"data": funnels.get(funnel_id=funnelId,
|
|
project_id=projectId)}
|
|
|
|
|
|
@app.route('/{projectId}/funnels/{funnelId}', methods=['POST', 'PUT'])
|
|
def edit_funnel(projectId, funnelId, context):
|
|
data = app.current_request.json_body
|
|
return funnels.update(funnel_id=funnelId,
|
|
user_id=context['userId'],
|
|
name=data.get("name"),
|
|
filter=data.get("filter"),
|
|
is_public=data.get("isPublic"))
|
|
|
|
|
|
@app.route('/{projectId}/funnels/{funnelId}', methods=['DELETE'])
|
|
def delete_filter(projectId, funnelId, context):
|
|
return funnels.delete(user_id=context['userId'], funnel_id=funnelId, project_id=projectId)
|
|
|
|
|
|
@app.route('/{projectId}/sourcemaps', methods=['PUT'], authorizer=bp_authorizers.api_key_authorizer)
|
|
def sign_sourcemap_for_upload(projectId, context):
|
|
data = app.current_request.json_body
|
|
project_id = projects.get_internal_project_id(projectId)
|
|
if project_id is None:
|
|
return Response(status_code=400, body='invalid projectId')
|
|
|
|
return {"data": sourcemaps.presign_upload_urls(project_id=project_id, urls=data["URL"])}
|
|
|
|
|
|
@app.route('/config/weekly_report', methods=['GET'])
|
|
def get_weekly_report_config(context):
|
|
return {"data": weekly_report.get_config(user_id=context['userId'])}
|
|
|
|
|
|
@app.route('/config/weekly_report', methods=['POST', 'PUT'])
|
|
def get_weekly_report_config(context):
|
|
data = app.current_request.json_body
|
|
return {"data": weekly_report.edit_config(user_id=context['userId'], weekly_report=data.get("weeklyReport", True))}
|
|
|
|
|
|
@app.route('/{projectId}/issue_types', methods=['GET'])
|
|
def issue_types(projectId, context):
|
|
# return {"data": issues.get_types_by_project(project_id=projectId)}
|
|
return {"data": issues.get_all_types()}
|
|
|
|
|
|
@app.route('/issue_types', methods=['GET'])
|
|
def all_issue_types(context):
|
|
return {"data": issues.get_all_types()}
|
|
|
|
|
|
@app.route('/flows', methods=['GET', 'PUT', 'POST', 'DELETE'])
|
|
@app.route('/{projectId}/flows', methods=['GET', 'PUT', 'POST', 'DELETE'])
|
|
def removed_endpoints(projectId=None, context=None):
|
|
return Response(body={"errors": ["Endpoint no longer available"]}, status_code=410)
|