Merge pull request #121 from openreplay/dev
fix(ui) - review changes and other fixes
This commit is contained in:
commit
c65a7b9561
15 changed files with 46 additions and 57 deletions
|
|
@ -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'])
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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"}}
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ class ManageUsers extends React.PureComponent {
|
|||
</div>
|
||||
{ !account.smtp &&
|
||||
<div className={cn("mb-4 p-2", styles.smtpMessage)}>
|
||||
SMTP is not configured, <a className="link" href="https://docs.openreplay.com/configuration/configure-smtp" target="_blank">setup SMTP</a>
|
||||
SMTP is not configured. Please follow <a className="link" href="https://docs.openreplay.com/configuration/configure-smtp" target="_blank">these steps</a> to set it up.
|
||||
</div>
|
||||
}
|
||||
<div className={ styles.formGroup }>
|
||||
|
|
@ -114,6 +114,7 @@ class ManageUsers extends React.PureComponent {
|
|||
value={ member.admin }
|
||||
checked={ !!member.admin }
|
||||
onChange={ this.onChangeCheckbox }
|
||||
disabled={member.superAdmin}
|
||||
/>
|
||||
<span>{ 'Admin' }</span>
|
||||
</label>
|
||||
|
|
@ -199,14 +200,7 @@ class ManageUsers extends React.PureComponent {
|
|||
inverted
|
||||
position="top left"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
{ !account.smtp &&
|
||||
<BannerMessage>
|
||||
Inviting new users require email messaging. Please <a className="link" href="https://docs.openreplay.com/configuration/configure-smtp" target="_blank">setup SMTP</a>.
|
||||
</BannerMessage>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<NoContent
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ const Item = ({ icon, text, completed, active, onClick }) => (
|
|||
<div className={cn('flex', stl.step)}>
|
||||
<div className={
|
||||
cn(
|
||||
"h-6 w-6 mr-3 bg-white rounded-full flex items-center justify-center",
|
||||
"h-6 w-6 mr-3 rounded-full flex items-center justify-center",
|
||||
stl.iconWrapper,
|
||||
{'bg-gray-light' : !active || !completed }
|
||||
)}
|
||||
|
|
@ -31,7 +31,7 @@ const Item = ({ icon, text, completed, active, onClick }) => (
|
|||
{ completed &&
|
||||
<Icon
|
||||
name={icon}
|
||||
color={completed? 'white' : 'gray-medium' }
|
||||
color={active? 'white' : 'gray-medium' }
|
||||
size="18"
|
||||
/>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<any>
|
||||
urlOptions: Array<any>
|
||||
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);
|
||||
|
|
@ -155,7 +155,7 @@ export default class SignupForm extends React.Component {
|
|||
<div className={ stl.formFooter }>
|
||||
<Button type="submit" primary >
|
||||
{ loading ?
|
||||
<CircularLoader loading={true} /> :
|
||||
<CircularLoader loading={true} className="flex" /> :
|
||||
'Create account'
|
||||
}
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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({
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ const View = Event.extend({
|
|||
const Location = Event.extend({
|
||||
type: LOCATION,
|
||||
url: '',
|
||||
host: '',
|
||||
pageLoad: false,
|
||||
fcpTime: undefined,
|
||||
//fpTime: undefined,
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) }}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue