diff --git a/api/chalicelib/blueprints/bp_core.py b/api/chalicelib/blueprints/bp_core.py
index 62b4ec114..14110f383 100644
--- a/api/chalicelib/blueprints/bp_core.py
+++ b/api/chalicelib/blueprints/bp_core.py
@@ -502,15 +502,12 @@ def edit_gdpr(projectId, context):
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):
+@app.route('/password/reset-link', methods=['PUT', 'POST'], authorizer=None)
+def reset_password_handler():
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)
+ if "email" not in data or len(data["email"]) < 5:
+ return {"errors": ["please provide a valid email address"]}
+ return reset_password.reset(data)
@app.route('/{projectId}/metadata', methods=['GET'])
diff --git a/api/chalicelib/blueprints/bp_core_dynamic.py b/api/chalicelib/blueprints/bp_core_dynamic.py
index 23141a4e1..0e1a7d8db 100644
--- a/api/chalicelib/blueprints/bp_core_dynamic.py
+++ b/api/chalicelib/blueprints/bp_core_dynamic.py
@@ -375,7 +375,7 @@ def process_invitation_link():
'Content-Type': 'text/plain'})
-@app.route('/users/invitation/password', methods=['POST', 'PUT'], authorizer=None)
+@app.route('/password/reset', methods=['POST', 'PUT'], authorizer=None)
def change_password_by_invitation():
data = app.current_request.json_body
if data is None or len(data.get("invitation", "")) < 64 or len(data.get("pass", "")) < 8:
diff --git a/api/chalicelib/core/reset_password.py b/api/chalicelib/core/reset_password.py
index 0b677c8e6..0b7302d5d 100644
--- a/api/chalicelib/core/reset_password.py
+++ b/api/chalicelib/core/reset_password.py
@@ -1,13 +1,9 @@
-import chalicelib.utils.TimeUTC
from chalicelib.utils import email_helper, captcha, helper
-import secrets
-from chalicelib.utils import pg_client
-
from chalicelib.core import users
-def step1(data):
- print("====================== reset password 1 ===============")
+def reset(data):
+ print("====================== reset password ===============")
print(data)
if helper.allow_captcha() and not captcha.is_valid(data["g-recaptcha-response"]):
print("error: Invalid captcha.")
@@ -21,20 +17,9 @@ def step1(data):
return {"errors": ["multiple users, please contact our support"]}
elif len(a_users) == 1:
a_users = a_users[0]
- invitation_link=users.generate_new_invitation(user_id=a_users["id"])
+ invitation_link = users.generate_new_invitation(user_id=a_users["id"])
email_helper.send_forgot_password(recipient=data["email"], invitation_link=invitation_link)
else:
print(f"invalid email address [{data['email']}]")
return {"errors": ["invalid email address"]}
return {"data": {"state": "success"}}
-
-
-# def step2(data):
-# print("====================== change password 2 ===============")
-# user = users.get_by_email_reset(data["email"], data["code"])
-# if not user:
-# print("error: wrong email or reset code")
-# return {"errors": ["wrong email or reset code"]}
-# users.update(tenant_id=user["tenantId"], user_id=user["id"],
-# changes={"token": None, "password": data["password"], "generatedPassword": False})
-# return {"data": {"state": "success"}}
diff --git a/api/chalicelib/core/users.py b/api/chalicelib/core/users.py
index 87e87813d..a571607e8 100644
--- a/api/chalicelib/core/users.py
+++ b/api/chalicelib/core/users.py
@@ -107,7 +107,6 @@ def generate_new_invitation(user_id):
return __get_invitation_link(cur.fetchone().pop("invitation_token"))
-
def reset_member(tenant_id, editor_id, user_id_to_update):
admin = get(tenant_id=tenant_id, user_id=editor_id)
if not admin["admin"] and not admin["superAdmin"]:
@@ -282,6 +281,8 @@ def edit(user_id_to_update, tenant_id, changes, editor_id):
admin = get(tenant_id=tenant_id, user_id=editor_id)
if not admin["superAdmin"] and not admin["admin"]:
return {"errors": ["unauthorized"]}
+ if user["superAdmin"]:
+ changes.pop("admin")
keys = list(changes.keys())
for k in keys:
diff --git a/ee/api/chalicelib/core/users.py b/ee/api/chalicelib/core/users.py
index 7735ddca8..8bb64e26b 100644
--- a/ee/api/chalicelib/core/users.py
+++ b/ee/api/chalicelib/core/users.py
@@ -107,7 +107,6 @@ def generate_new_invitation(user_id):
)
return __get_invitation_link(cur.fetchone().pop("invitation_token"))
-
def reset_member(tenant_id, editor_id, user_id_to_update):
admin = get(tenant_id=tenant_id, user_id=editor_id)
@@ -287,6 +286,8 @@ def edit(user_id_to_update, tenant_id, changes, editor_id):
admin = get(tenant_id=tenant_id, user_id=editor_id)
if not admin["superAdmin"] and not admin["admin"]:
return {"errors": ["unauthorized"]}
+ if user["superAdmin"] and "admin" in changes:
+ changes.pop("admin")
keys = list(changes.keys())
for k in keys:
diff --git a/frontend/app/components/Client/ManageUsers/ManageUsers.js b/frontend/app/components/Client/ManageUsers/ManageUsers.js
index 3e1182f41..b0dfd32e9 100644
--- a/frontend/app/components/Client/ManageUsers/ManageUsers.js
+++ b/frontend/app/components/Client/ManageUsers/ManageUsers.js
@@ -103,7 +103,7 @@ class ManageUsers extends React.PureComponent {
{ !account.smtp &&
}
@@ -114,6 +114,7 @@ class ManageUsers extends React.PureComponent {
value={ member.admin }
checked={ !!member.admin }
onChange={ this.onChangeCheckbox }
+ disabled={member.superAdmin}
/>
{ 'Admin' }
@@ -199,14 +200,7 @@ class ManageUsers extends React.PureComponent {
inverted
position="top left"
/>
-
-
- { !account.smtp &&
-
- Inviting new users require email messaging. Please setup SMTP.
-
- }
-
+
(
(
{ completed &&
}
diff --git a/frontend/app/components/Session_/PageInsightsPanel/PageInsightsPanel.tsx b/frontend/app/components/Session_/PageInsightsPanel/PageInsightsPanel.tsx
index dea0a6345..ed213d472 100644
--- a/frontend/app/components/Session_/PageInsightsPanel/PageInsightsPanel.tsx
+++ b/frontend/app/components/Session_/PageInsightsPanel/PageInsightsPanel.tsx
@@ -1,5 +1,5 @@
-import React, { useEffect, useState } from 'react'
-import { Dropdown, Loader } from 'UI'
+import React, { useEffect, useState } from 'react';
+import { Dropdown, Loader } from 'UI';
import DateRange from 'Shared/DateRange';
import { connect } from 'react-redux';
import { fetchInsights } from 'Duck/sessions';
@@ -15,10 +15,14 @@ interface Props {
events: Array
urlOptions: Array
loading: boolean
+ host: string
}
-function PageInsightsPanel({ filters, fetchInsights, events = [], insights, urlOptions, loading = true }: Props) {
+function PageInsightsPanel({
+ filters, fetchInsights, events = [], insights, urlOptions, host, loading = true
+}: Props) {
const [insightsFilters, setInsightsFilters] = useState(filters)
+ console.log('host', host)
const onDateChange = (e) => {
const { startDate, endDate, rangeValue } = e;
@@ -33,7 +37,7 @@ function PageInsightsPanel({ filters, fetchInsights, events = [], insights, urlO
}, [insights])
useEffect(() => {
- const url = insightsFilters.url ? insightsFilters.url : urlOptions[0].value;
+ const url = insightsFilters.url ? insightsFilters.url : host + '/' + urlOptions[0].value;
Player.pause();
fetchInsights({ ...insightsFilters, url })
}, [insightsFilters])
@@ -41,7 +45,7 @@ function PageInsightsPanel({ filters, fetchInsights, events = [], insights, urlO
const onPageSelect = (e, { name, value }) => {
const event = events.find(item => item.url === value)
Player.jump(event.time + JUMP_OFFSET)
- setInsightsFilters({ ...insightsFilters, url: value })
+ setInsightsFilters({ ...insightsFilters, url: host + '/' + value })
markTargets([])
};
@@ -83,9 +87,10 @@ export default connect(state => {
const events = state.getIn([ 'sessions', 'visitedEvents' ])
return {
filters: state.getIn(['sessions', 'insightFilters']),
+ host: state.getIn([ 'sessions', 'host' ]),
insights: state.getIn([ 'sessions', 'insights' ]),
events: events,
- urlOptions: events.map(({ url }) => ({ text: url, value: url})),
+ urlOptions: events.map(({ url, host }) => ({ text: url, value: url, host })),
loading: state.getIn([ 'sessions', 'fetchInsightsRequest', 'loading' ]),
}
}, { fetchInsights })(PageInsightsPanel);
\ No newline at end of file
diff --git a/frontend/app/components/Signup/SignupForm/SignupForm.js b/frontend/app/components/Signup/SignupForm/SignupForm.js
index 0a5de9507..7df2822ee 100644
--- a/frontend/app/components/Signup/SignupForm/SignupForm.js
+++ b/frontend/app/components/Signup/SignupForm/SignupForm.js
@@ -155,7 +155,7 @@ export default class SignupForm extends React.Component {
diff --git a/frontend/app/duck/sessions.js b/frontend/app/duck/sessions.js
index 6fe968d47..d54506ddc 100644
--- a/frontend/app/duck/sessions.js
+++ b/frontend/app/duck/sessions.js
@@ -53,7 +53,8 @@ const initialState = Map({
liveSessions: List(),
visitedEvents: List(),
insights: List(),
- insightFilters: defaultDateFilters
+ insightFilters: defaultDateFilters,
+ host: ''
});
const reducer = (state = initialState, action = {}) => {
@@ -146,7 +147,7 @@ const reducer = (state = initialState, action = {}) => {
// TODO: more common.. or TEMP
const events = action.filter.events;
// const filters = action.filter.filters;
- const current = state.get('list').find(({ sessionId }) => sessionId === action.data.sessionId) || Session();
+ const current = state.get('list').find(({ sessionId }) => sessionId === action.data.sessionId) || Session();
const session = Session(action.data);
const matching = [];
@@ -158,7 +159,7 @@ const reducer = (state = initialState, action = {}) => {
tmpMap[event.url] = event.url
visitedEvents.push(event)
}
- })
+ })
events.forEach(({ key, operator, value }) => {
session.events.forEach((e, index) => {
@@ -172,10 +173,12 @@ const reducer = (state = initialState, action = {}) => {
}
}
})
- })
+ })
+ console.log('visitedEvents', visitedEvents)
return state.set('current', current.merge(session))
.set('eventsIndex', matching)
- .set('visitedEvents', visitedEvents);
+ .set('visitedEvents', visitedEvents)
+ .set('host', visitedEvents[0].host);
}
case FETCH_FAVORITE_LIST.SUCCESS:
return state
@@ -227,7 +230,7 @@ const reducer = (state = initialState, action = {}) => {
.set('sessionIds', allList.map(({ sessionId }) => sessionId ).toJS())
case SET_TIMEZONE:
return state.set('timezone', action.timezone)
- case TOGGLE_CHAT_WINDOW:
+ case TOGGLE_CHAT_WINDOW:
return state.set('showChatWindow', action.state)
case FETCH_INSIGHTS.SUCCESS:
return state.set('insights', List(action.data).sort((a, b) => b.count - a.count));
diff --git a/frontend/app/duck/user.js b/frontend/app/duck/user.js
index 5395792c3..fc9fdcabf 100644
--- a/frontend/app/duck/user.js
+++ b/frontend/app/duck/user.js
@@ -113,12 +113,12 @@ export const signup = params => dispatch => dispatch({
export const resetPassword = params => dispatch => dispatch({
types: RESET_PASSWORD.toArray(),
- call: client => client.post('/password/reset/2', params),
+ call: client => client.post('/password/reset', params)
});
export const requestResetPassword = params => dispatch => dispatch({
types: REQUEST_RESET_PASSWORD.toArray(),
- call: client => client.post('/password/reset/1', params),
+ call: client => client.post('/password/reset-link', params),
});
export const updatePassword = params => dispatch => dispatch({
diff --git a/frontend/app/types/session/event.js b/frontend/app/types/session/event.js
index b64744bcb..537de1724 100644
--- a/frontend/app/types/session/event.js
+++ b/frontend/app/types/session/event.js
@@ -56,6 +56,7 @@ const View = Event.extend({
const Location = Event.extend({
type: LOCATION,
url: '',
+ host: '',
pageLoad: false,
fcpTime: undefined,
//fpTime: undefined,
diff --git a/frontend/env.js b/frontend/env.js
index c31287c4b..20b435e21 100644
--- a/frontend/env.js
+++ b/frontend/env.js
@@ -13,14 +13,14 @@ const oss = {
ORIGIN: () => 'window.location.origin',
API_EDP: () => 'window.location.origin + "/api"',
ASSETS_HOST: () => 'window.location.origin + "/assets"',
- VERSION: '1.2.0',
+ VERSION: '1.3.0',
SOURCEMAP: true,
MINIO_ENDPOINT: process.env.MINIO_ENDPOINT,
MINIO_PORT: process.env.MINIO_PORT,
MINIO_USE_SSL: process.env.MINIO_USE_SSL,
MINIO_ACCESS_KEY: process.env.MINIO_ACCESS_KEY,
MINIO_SECRET_KEY: process.env.MINIO_SECRET_KEY,
- TRACKER_VERSION: '3.1.0', // trackerInfo.version,
+ TRACKER_VERSION: '3.2.0', // trackerInfo.version,
}
module.exports = {
diff --git a/scripts/helm/app/http.yaml b/scripts/helm/app/http.yaml
index f594df201..b34105a6c 100644
--- a/scripts/helm/app/http.yaml
+++ b/scripts/helm/app/http.yaml
@@ -29,6 +29,7 @@ env:
AWS_SECRET_ACCESS_KEY: "m1n10s3CretK3yPassw0rd"
AWS_REGION: us-east-1
POSTGRES_STRING: postgres://postgres:asayerPostgres@postgresql.db.svc.cluster.local:5432
+ CACHE_ASSETS: true
#
REDIS_STRING: redis-master.db.svc.cluster.local:6379
KAFKA_SERVERS: kafka.db.svc.cluster.local:9092
diff --git a/scripts/helm/roles/openreplay/templates/chalice.yaml b/scripts/helm/roles/openreplay/templates/chalice.yaml
index 0d1ce88db..3ab238e72 100644
--- a/scripts/helm/roles/openreplay/templates/chalice.yaml
+++ b/scripts/helm/roles/openreplay/templates/chalice.yaml
@@ -13,6 +13,7 @@ env:
sourcemaps_bucket_key: "{{ minio_access_key }}"
sourcemaps_bucket_secret: "{{ minio_secret_key }}"
S3_HOST: "https://{{ domain_name }}"
+ SITE_URL: "https://{{ domain_name }}"
jwt_secret: "{{ jwt_secret_key }}"
{% if env is defined and env.chalice is defined and env.chalice%}
{{ env.chalice | to_nice_yaml | trim | indent(2) }}