feat(db): removed user's appearance
feat(db): removed generated_password feat(api): merged account&client feat(api): cleaned account response feat(api): removed user's appearance feat(api): removed generated_password feat(api): limits endpoint feat(api): notifications/count endpoint
This commit is contained in:
parent
a6c75d3cdd
commit
cbe78cc58e
16 changed files with 153 additions and 307 deletions
|
|
@ -3,19 +3,10 @@ from chalicelib.utils import pg_client
|
|||
|
||||
def get_status(tenant_id=None):
|
||||
with pg_client.PostgresClient() as cur:
|
||||
cur.execute("SELECT * FROM public.tenants;")
|
||||
# cur.execute("SELECT * FROM public.tenants;")
|
||||
cur.execute("SELECT edition FROM public.tenants;")
|
||||
r = cur.fetchone()
|
||||
return {
|
||||
"hasActivePlan": True,
|
||||
"current": {
|
||||
"edition": r.get("edition", "").upper(),
|
||||
"versionNumber": r.get("version_number", ""),
|
||||
"license": "",
|
||||
"expirationDate": -1
|
||||
},
|
||||
"count": {
|
||||
"teamMember": r.get("t_users"),
|
||||
"projects": r.get("t_projects"),
|
||||
"capturedSessions": r.get("t_sessions")
|
||||
}
|
||||
"edition": r.get("edition", "").upper()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,24 @@ def get_all(tenant_id, user_id):
|
|||
return rows
|
||||
|
||||
|
||||
def get_all_count(tenant_id, user_id):
|
||||
with pg_client.PostgresClient() as cur:
|
||||
cur.execute(
|
||||
cur.mogrify("""\
|
||||
SELECT COUNT(notifications.*) AS count
|
||||
FROM public.notifications
|
||||
LEFT JOIN (SELECT notification_id
|
||||
FROM public.user_viewed_notifications
|
||||
WHERE user_viewed_notifications.user_id = %(user_id)s) AS user_viewed_notifications USING (notification_id)
|
||||
WHERE (notifications.user_id IS NULL OR notifications.user_id =%(user_id)s) AND user_viewed_notifications.notification_id IS NULL
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 100;""",
|
||||
{"user_id": user_id})
|
||||
)
|
||||
row = cur.fetchone()
|
||||
return row
|
||||
|
||||
|
||||
def view_notification(user_id, notification_ids=[], tenant_id=None, startTimestamp=None, endTimestamp=None):
|
||||
if (notification_ids is None or len(notification_ids) == 0) and endTimestamp is None:
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -77,8 +77,8 @@ def create_step1(data: schemas.UserSignupSchema):
|
|||
RETURNING user_id,email,role,name
|
||||
),
|
||||
au AS (INSERT
|
||||
INTO public.basic_authentication (user_id, password, generated_password)
|
||||
VALUES ((SELECT user_id FROM u), crypt(%(password)s, gen_salt('bf', 12)), FALSE)
|
||||
INTO public.basic_authentication (user_id, password)
|
||||
VALUES ((SELECT user_id FROM u), crypt(%(password)s, gen_salt('bf', 12)))
|
||||
)
|
||||
INSERT INTO public.projects (name, active)
|
||||
VALUES (%(projectName)s, TRUE)
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ def create_new_member(email, invitation_token, admin, name, owner=False):
|
|||
query = cur.mogrify(f"""\
|
||||
WITH u AS (INSERT INTO public.users (email, role, name, data)
|
||||
VALUES (%(email)s, %(role)s, %(name)s, %(data)s)
|
||||
RETURNING user_id,email,role,name,appearance
|
||||
RETURNING user_id,email,role,name
|
||||
),
|
||||
au AS (INSERT INTO public.basic_authentication (user_id, generated_password, invitation_token, invited_at)
|
||||
VALUES ((SELECT user_id FROM u), TRUE, %(invitation_token)s, timezone('utc'::text, now()))
|
||||
au AS (INSERT INTO public.basic_authentication (user_id, invitation_token, invited_at)
|
||||
VALUES ((SELECT user_id FROM u), %(invitation_token)s, timezone('utc'::text, now()))
|
||||
RETURNING invitation_token
|
||||
)
|
||||
SELECT u.user_id,
|
||||
|
|
@ -32,7 +32,6 @@ def create_new_member(email, invitation_token, admin, name, owner=False):
|
|||
u.email,
|
||||
u.role,
|
||||
u.name,
|
||||
TRUE AS change_password,
|
||||
(CASE WHEN u.role = 'owner' THEN TRUE ELSE FALSE END) AS super_admin,
|
||||
(CASE WHEN u.role = 'admin' THEN TRUE ELSE FALSE END) AS admin,
|
||||
(CASE WHEN u.role = 'member' THEN TRUE ELSE FALSE END) AS member,
|
||||
|
|
@ -61,7 +60,6 @@ def restore_member(user_id, email, invitation_token, admin, name, owner=False):
|
|||
email,
|
||||
role,
|
||||
name,
|
||||
TRUE AS change_password,
|
||||
(CASE WHEN role = 'owner' THEN TRUE ELSE FALSE END) AS super_admin,
|
||||
(CASE WHEN role = 'admin' THEN TRUE ELSE FALSE END) AS admin,
|
||||
(CASE WHEN role = 'member' THEN TRUE ELSE FALSE END) AS member;""",
|
||||
|
|
@ -73,8 +71,7 @@ def restore_member(user_id, email, invitation_token, admin, name, owner=False):
|
|||
result = cur.fetchone()
|
||||
query = cur.mogrify("""\
|
||||
UPDATE public.basic_authentication
|
||||
SET generated_password = TRUE,
|
||||
invitation_token = %(invitation_token)s,
|
||||
SET invitation_token = %(invitation_token)s,
|
||||
invited_at = timezone('utc'::text, now()),
|
||||
change_pwd_expire_at = NULL,
|
||||
change_pwd_token = NULL
|
||||
|
|
@ -132,11 +129,7 @@ def update(tenant_id, user_id, changes):
|
|||
else:
|
||||
sub_query_bauth.append(f"{helper.key_to_snake_case(key)} = %({key})s")
|
||||
else:
|
||||
if key == "appearance":
|
||||
sub_query_users.append(f"appearance = %(appearance)s::jsonb")
|
||||
changes["appearance"] = json.dumps(changes[key])
|
||||
else:
|
||||
sub_query_users.append(f"{helper.key_to_snake_case(key)} = %({key})s")
|
||||
sub_query_users.append(f"{helper.key_to_snake_case(key)} = %({key})s")
|
||||
|
||||
with pg_client.PostgresClient() as cur:
|
||||
if len(sub_query_users) > 0:
|
||||
|
|
@ -151,11 +144,9 @@ def update(tenant_id, user_id, changes):
|
|||
users.email,
|
||||
users.role,
|
||||
users.name,
|
||||
basic_authentication.generated_password AS change_password,
|
||||
(CASE WHEN users.role = 'owner' THEN TRUE ELSE FALSE END) AS super_admin,
|
||||
(CASE WHEN users.role = 'admin' THEN TRUE ELSE FALSE END) AS admin,
|
||||
(CASE WHEN users.role = 'member' THEN TRUE ELSE FALSE END) AS member,
|
||||
users.appearance;""",
|
||||
(CASE WHEN users.role = 'member' THEN TRUE ELSE FALSE END) AS member;""",
|
||||
{"user_id": user_id, **changes})
|
||||
)
|
||||
if len(sub_query_bauth) > 0:
|
||||
|
|
@ -170,11 +161,9 @@ def update(tenant_id, user_id, changes):
|
|||
users.email,
|
||||
users.role,
|
||||
users.name,
|
||||
basic_authentication.generated_password AS change_password,
|
||||
(CASE WHEN users.role = 'owner' THEN TRUE ELSE FALSE END) AS super_admin,
|
||||
(CASE WHEN users.role = 'admin' THEN TRUE ELSE FALSE END) AS admin,
|
||||
(CASE WHEN users.role = 'member' THEN TRUE ELSE FALSE END) AS member,
|
||||
users.appearance;""",
|
||||
(CASE WHEN users.role = 'member' THEN TRUE ELSE FALSE END) AS member;""",
|
||||
{"user_id": user_id, **changes})
|
||||
)
|
||||
|
||||
|
|
@ -244,15 +233,13 @@ def get(user_id, tenant_id):
|
|||
cur.execute(
|
||||
cur.mogrify(
|
||||
f"""SELECT
|
||||
users.user_id AS id,
|
||||
users.user_id,
|
||||
email,
|
||||
role,
|
||||
name,
|
||||
basic_authentication.generated_password,
|
||||
name,
|
||||
(CASE WHEN role = 'owner' THEN TRUE ELSE FALSE END) AS super_admin,
|
||||
(CASE WHEN role = 'admin' THEN TRUE ELSE FALSE END) AS admin,
|
||||
(CASE WHEN role = 'member' THEN TRUE ELSE FALSE END) AS member,
|
||||
appearance,
|
||||
api_key
|
||||
FROM public.users LEFT JOIN public.basic_authentication ON users.user_id=basic_authentication.user_id
|
||||
WHERE
|
||||
|
|
@ -262,7 +249,7 @@ def get(user_id, tenant_id):
|
|||
{"userId": user_id})
|
||||
)
|
||||
r = cur.fetchone()
|
||||
return helper.dict_to_camel_case(r, ignore_keys=["appearance"])
|
||||
return helper.dict_to_camel_case(r)
|
||||
|
||||
|
||||
def generate_new_api_key(user_id):
|
||||
|
|
@ -282,7 +269,7 @@ def generate_new_api_key(user_id):
|
|||
|
||||
|
||||
def edit(user_id_to_update, tenant_id, changes, editor_id):
|
||||
ALLOW_EDIT = ["name", "email", "admin", "appearance"]
|
||||
ALLOW_EDIT = ["name", "email", "admin"]
|
||||
user = get(user_id=user_id_to_update, tenant_id=tenant_id)
|
||||
if editor_id != user_id_to_update or "admin" in changes and changes["admin"] != user["admin"]:
|
||||
admin = get(tenant_id=tenant_id, user_id=editor_id)
|
||||
|
|
@ -315,11 +302,6 @@ def edit(user_id_to_update, tenant_id, changes, editor_id):
|
|||
return {"data": user}
|
||||
|
||||
|
||||
def edit_appearance(user_id, tenant_id, changes):
|
||||
updated_user = update(tenant_id=tenant_id, user_id=user_id, changes=changes)
|
||||
return {"data": updated_user}
|
||||
|
||||
|
||||
def get_by_email_only(email):
|
||||
with pg_client.PostgresClient() as cur:
|
||||
cur.execute(
|
||||
|
|
@ -329,8 +311,7 @@ def get_by_email_only(email):
|
|||
1 AS tenant_id,
|
||||
users.email,
|
||||
users.role,
|
||||
users.name,
|
||||
basic_authentication.generated_password,
|
||||
users.name,
|
||||
(CASE WHEN users.role = 'owner' THEN TRUE ELSE FALSE END) AS super_admin,
|
||||
(CASE WHEN users.role = 'admin' THEN TRUE ELSE FALSE END) AS admin,
|
||||
(CASE WHEN users.role = 'member' THEN TRUE ELSE FALSE END) AS member
|
||||
|
|
@ -353,8 +334,7 @@ def get_by_email_reset(email, reset_token):
|
|||
1 AS tenant_id,
|
||||
users.email,
|
||||
users.role,
|
||||
users.name,
|
||||
basic_authentication.generated_password,
|
||||
users.name,
|
||||
(CASE WHEN users.role = 'owner' THEN TRUE ELSE FALSE END) AS super_admin,
|
||||
(CASE WHEN users.role = 'admin' THEN TRUE ELSE FALSE END) AS admin,
|
||||
(CASE WHEN users.role = 'member' THEN TRUE ELSE FALSE END) AS member
|
||||
|
|
@ -377,8 +357,7 @@ def get_members(tenant_id):
|
|||
users.email,
|
||||
users.role,
|
||||
users.name,
|
||||
users.created_at,
|
||||
basic_authentication.generated_password,
|
||||
users.created_at,
|
||||
(CASE WHEN users.role = 'owner' THEN TRUE ELSE FALSE END) AS super_admin,
|
||||
(CASE WHEN users.role = 'admin' THEN TRUE ELSE FALSE END) AS admin,
|
||||
(CASE WHEN users.role = 'member' THEN TRUE ELSE FALSE END) AS member,
|
||||
|
|
@ -581,11 +560,9 @@ def authenticate(email, password, for_change_password=False, for_plugin=False):
|
|||
1 AS tenant_id,
|
||||
users.role,
|
||||
users.name,
|
||||
basic_authentication.generated_password AS change_password,
|
||||
(CASE WHEN users.role = 'owner' THEN TRUE ELSE FALSE END) AS super_admin,
|
||||
(CASE WHEN users.role = 'admin' THEN TRUE ELSE FALSE END) AS admin,
|
||||
(CASE WHEN users.role = 'member' THEN TRUE ELSE FALSE END) AS member,
|
||||
users.appearance
|
||||
(CASE WHEN users.role = 'member' THEN TRUE ELSE FALSE END) AS member
|
||||
FROM public.users INNER JOIN public.basic_authentication USING(user_id)
|
||||
WHERE users.email = %(email)s
|
||||
AND basic_authentication.password = crypt(%(password)s, basic_authentication.password)
|
||||
|
|
@ -599,7 +576,7 @@ def authenticate(email, password, for_change_password=False, for_plugin=False):
|
|||
if r is not None:
|
||||
if for_change_password:
|
||||
return True
|
||||
r = helper.dict_to_camel_case(r, ignore_keys=["appearance"])
|
||||
r = helper.dict_to_camel_case(r)
|
||||
query = cur.mogrify(
|
||||
f"""UPDATE public.users
|
||||
SET jwt_iat = timezone('utc'::text, now())
|
||||
|
|
|
|||
|
|
@ -966,6 +966,11 @@ def get_notifications(context: schemas.CurrentContext = Depends(OR_context)):
|
|||
return {"data": notifications.get_all(tenant_id=context.tenant_id, user_id=context.user_id)}
|
||||
|
||||
|
||||
@app.get('/notifications/count', tags=['notifications'])
|
||||
def get_notifications_count(context: schemas.CurrentContext = Depends(OR_context)):
|
||||
return {"data": notifications.get_all_count(tenant_id=context.tenant_id, user_id=context.user_id)}
|
||||
|
||||
|
||||
@app.get('/notifications/{notificationId}/view', tags=['notifications'])
|
||||
def view_notifications(notificationId: int, context: schemas.CurrentContext = Depends(OR_context)):
|
||||
return {"data": notifications.view_notification(notification_ids=[notificationId], user_id=context.user_id)}
|
||||
|
|
@ -1075,13 +1080,6 @@ def edit_account(data: schemas.EditUserSchema = Body(...),
|
|||
editor_id=context.user_id)
|
||||
|
||||
|
||||
@app.post('/account/appearance', tags=["account"])
|
||||
@app.put('/account/appearance', tags=["account"])
|
||||
def edit_account_appearance(data: schemas.EditUserAppearanceSchema = Body(...),
|
||||
context: schemas.CurrentContext = Depends(OR_context)):
|
||||
return users.edit_appearance(tenant_id=context.tenant_id, user_id=context.user_id, changes=data.dict())
|
||||
|
||||
|
||||
@app.post('/account/password', tags=["account"])
|
||||
@app.put('/account/password', tags=["account"])
|
||||
def change_client_password(data: schemas.EditUserPasswordSchema = Body(...),
|
||||
|
|
|
|||
|
|
@ -67,17 +67,17 @@ def login(data: schemas.UserLoginSchema = Body(...)):
|
|||
@app.get('/account', tags=['accounts'])
|
||||
def get_account(context: schemas.CurrentContext = Depends(OR_context)):
|
||||
r = users.get(tenant_id=context.tenant_id, user_id=context.user_id)
|
||||
t = tenants.get_by_tenant_id(context.tenant_id)
|
||||
if t is not None:
|
||||
t.pop("createdAt")
|
||||
t["tenantName"] = t.pop("name")
|
||||
return {
|
||||
'data': {
|
||||
**r,
|
||||
"limits": {
|
||||
"teamMember": -1,
|
||||
"projects": -1,
|
||||
"metadata": metadata.get_remaining_metadata_with_count(context.tenant_id)
|
||||
},
|
||||
**t,
|
||||
**license.get_status(context.tenant_id),
|
||||
"smtp": helper.has_smtp(),
|
||||
"iceServers": assist.get_ice_servers()
|
||||
# "iceServers": assist.get_ice_servers()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -199,29 +199,25 @@ def search_sessions_by_metadata(key: str, value: str, projectId: Optional[int] =
|
|||
m_key=key, project_id=projectId)}
|
||||
|
||||
|
||||
@app.get('/plans', tags=["plan"])
|
||||
def get_current_plan(context: schemas.CurrentContext = Depends(OR_context)):
|
||||
return {
|
||||
"data": license.get_status(context.tenant_id)
|
||||
}
|
||||
|
||||
|
||||
@public_app.get('/general_stats', tags=["private"], include_in_schema=False)
|
||||
def get_general_stats():
|
||||
return {"data": {"sessions:": sessions.count_all()}}
|
||||
|
||||
|
||||
@app.get('/client', tags=['projects'])
|
||||
def get_client(context: schemas.CurrentContext = Depends(OR_context)):
|
||||
r = tenants.get_by_tenant_id(context.tenant_id)
|
||||
if r is not None:
|
||||
r.pop("createdAt")
|
||||
return {
|
||||
'data': r
|
||||
}
|
||||
|
||||
|
||||
@app.get('/projects', tags=['projects'])
|
||||
def get_projects(context: schemas.CurrentContext = Depends(OR_context)):
|
||||
return {"data": projects.get_projects(tenant_id=context.tenant_id, recording_state=True, gdpr=True, recorded=True,
|
||||
stack_integrations=True)}
|
||||
|
||||
|
||||
@app.get('/limits', tags=['accounts'])
|
||||
def get_limits(context: schemas.CurrentContext = Depends(OR_context)):
|
||||
return {
|
||||
'data': {
|
||||
"limits": {
|
||||
"teamMember": -1,
|
||||
"projects": -1,
|
||||
"metadata": metadata.get_remaining_metadata_with_count(context.tenant_id)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,15 +38,10 @@ class EditUserSchema(BaseModel):
|
|||
name: Optional[str] = Field(None)
|
||||
email: Optional[EmailStr] = Field(None)
|
||||
admin: Optional[bool] = Field(False)
|
||||
appearance: Optional[dict] = Field({})
|
||||
|
||||
_transform_email = validator('email', pre=True, allow_reuse=True)(transform_email)
|
||||
|
||||
|
||||
class EditUserAppearanceSchema(BaseModel):
|
||||
appearance: dict = Field(...)
|
||||
|
||||
|
||||
class ForgetPasswordPayloadSchema(_Grecaptcha):
|
||||
email: EmailStr = Field(...)
|
||||
|
||||
|
|
|
|||
|
|
@ -7,21 +7,11 @@ from chalicelib.utils import pg_client
|
|||
def get_status(tenant_id):
|
||||
with pg_client.PostgresClient() as cur:
|
||||
cur.execute(
|
||||
cur.mogrify("SELECT * FROM public.tenants WHERE tenant_id=%(tenant_id)s;", {"tenant_id": tenant_id}))
|
||||
# cur.mogrify("SELECT * FROM public.tenants WHERE tenant_id=%(tenant_id)s;", {"tenant_id": tenant_id}))
|
||||
cur.mogrify("SELECT edition FROM public.tenants WHERE tenant_id=%(tenant_id)s;", {"tenant_id": tenant_id}))
|
||||
r = cur.fetchone()
|
||||
license = unlock.get_license()
|
||||
return {
|
||||
"hasActivePlan": unlock.is_valid(),
|
||||
"current": {
|
||||
"edition": r.get("edition", "").lower(),
|
||||
"versionNumber": r.get("version_number", ""),
|
||||
"license": license[0:2] + "*" * (len(license) - 4) + license[-2:],
|
||||
"expirationDate": unlock.get_expiration_date(),
|
||||
"teamMember": config("numberOfSeats", cast=int, default=0)
|
||||
},
|
||||
"count": {
|
||||
"teamMember": r.get("t_users"),
|
||||
"projects": r.get("t_projects"),
|
||||
"capturedSessions": r.get("t_sessions")
|
||||
}
|
||||
"edition": r.get("edition", "").lower(),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,27 @@ def get_all(tenant_id, user_id):
|
|||
return rows
|
||||
|
||||
|
||||
def get_all_count(tenant_id, user_id):
|
||||
with pg_client.PostgresClient() as cur:
|
||||
cur.execute(
|
||||
cur.mogrify("""\
|
||||
SELECT COUNT(notifications.*)
|
||||
FROM public.notifications
|
||||
LEFT JOIN (SELECT notification_id
|
||||
FROM public.user_viewed_notifications
|
||||
WHERE user_viewed_notifications.user_id = %(user_id)s) AS user_viewed_notifications USING (notification_id)
|
||||
WHERE (notifications.tenant_id =%(tenant_id)s
|
||||
OR notifications.user_id =%(user_id)s) AND user_viewed_notifications.notification_id IS NULL
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 100;""",
|
||||
{"tenant_id": tenant_id, "user_id": user_id})
|
||||
)
|
||||
rows = helper.list_to_camel_case(cur.fetchall())
|
||||
for r in rows:
|
||||
r["createdAt"] = TimeUTC.datetime_to_timestamp(r["createdAt"])
|
||||
return rows
|
||||
|
||||
|
||||
def view_notification(user_id, notification_ids=[], tenant_id=None, startTimestamp=None, endTimestamp=None):
|
||||
if (notification_ids is None or len(notification_ids) == 0) and endTimestamp is None:
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -80,8 +80,8 @@ def create_step1(data: schemas.UserSignupSchema):
|
|||
RETURNING user_id,email,role,name,role_id
|
||||
),
|
||||
au AS (
|
||||
INSERT INTO public.basic_authentication (user_id, password, generated_password)
|
||||
VALUES ((SELECT user_id FROM u), crypt(%(password)s, gen_salt('bf', 12)), FALSE)
|
||||
INSERT INTO public.basic_authentication (user_id, password)
|
||||
VALUES ((SELECT user_id FROM u), crypt(%(password)s, gen_salt('bf', 12)))
|
||||
)
|
||||
INSERT INTO public.projects (tenant_id, name, active)
|
||||
VALUES ((SELECT t.tenant_id FROM t), %(projectName)s, TRUE)
|
||||
|
|
|
|||
|
|
@ -25,10 +25,10 @@ def create_new_member(tenant_id, email, invitation_token, admin, name, owner=Fal
|
|||
(SELECT COALESCE((SELECT role_id FROM roles WHERE tenant_id = %(tenant_id)s AND role_id = %(role_id)s),
|
||||
(SELECT role_id FROM roles WHERE tenant_id = %(tenant_id)s AND name = 'Member' LIMIT 1),
|
||||
(SELECT role_id FROM roles WHERE tenant_id = %(tenant_id)s AND name != 'Owner' LIMIT 1))))
|
||||
RETURNING tenant_id,user_id,email,role,name,appearance, role_id
|
||||
RETURNING tenant_id,user_id,email,role,name, role_id
|
||||
),
|
||||
au AS (INSERT INTO public.basic_authentication (user_id, generated_password, invitation_token, invited_at)
|
||||
VALUES ((SELECT user_id FROM u), TRUE, %(invitation_token)s, timezone('utc'::text, now()))
|
||||
au AS (INSERT INTO public.basic_authentication (user_id, invitation_token, invited_at)
|
||||
VALUES ((SELECT user_id FROM u), %(invitation_token)s, timezone('utc'::text, now()))
|
||||
RETURNING invitation_token
|
||||
)
|
||||
SELECT u.user_id AS id,
|
||||
|
|
@ -36,7 +36,6 @@ def create_new_member(tenant_id, email, invitation_token, admin, name, owner=Fal
|
|||
u.email,
|
||||
u.role,
|
||||
u.name,
|
||||
TRUE AS change_password,
|
||||
(CASE WHEN u.role = 'owner' THEN TRUE ELSE FALSE END) AS super_admin,
|
||||
(CASE WHEN u.role = 'admin' THEN TRUE ELSE FALSE END) AS admin,
|
||||
(CASE WHEN u.role = 'member' THEN TRUE ELSE FALSE END) AS member,
|
||||
|
|
@ -74,7 +73,6 @@ def restore_member(tenant_id, user_id, email, invitation_token, admin, name, own
|
|||
email,
|
||||
role,
|
||||
name,
|
||||
TRUE AS change_password,
|
||||
(CASE WHEN role = 'owner' THEN TRUE ELSE FALSE END) AS super_admin,
|
||||
(CASE WHEN role = 'admin' THEN TRUE ELSE FALSE END) AS admin,
|
||||
(CASE WHEN role = 'member' THEN TRUE ELSE FALSE END) AS member,
|
||||
|
|
@ -88,8 +86,7 @@ def restore_member(tenant_id, user_id, email, invitation_token, admin, name, own
|
|||
result = cur.fetchone()
|
||||
query = cur.mogrify("""\
|
||||
UPDATE public.basic_authentication
|
||||
SET generated_password = TRUE,
|
||||
invitation_token = %(invitation_token)s,
|
||||
SET invitation_token = %(invitation_token)s,
|
||||
invited_at = timezone('utc'::text, now()),
|
||||
change_pwd_expire_at = NULL,
|
||||
change_pwd_token = NULL
|
||||
|
|
@ -147,10 +144,7 @@ def update(tenant_id, user_id, changes):
|
|||
else:
|
||||
sub_query_bauth.append(f"{helper.key_to_snake_case(key)} = %({key})s")
|
||||
else:
|
||||
if key == "appearance":
|
||||
sub_query_users.append(f"appearance = %(appearance)s::jsonb")
|
||||
changes["appearance"] = json.dumps(changes[key])
|
||||
elif helper.key_to_snake_case(key) == "role_id":
|
||||
if helper.key_to_snake_case(key) == "role_id":
|
||||
sub_query_users.append("""role_id=(SELECT COALESCE((SELECT role_id FROM roles WHERE tenant_id = %(tenant_id)s AND role_id = %(role_id)s),
|
||||
(SELECT role_id FROM roles WHERE tenant_id = %(tenant_id)s AND name = 'Member' LIMIT 1),
|
||||
(SELECT role_id FROM roles WHERE tenant_id = %(tenant_id)s AND name != 'Owner' LIMIT 1)))""")
|
||||
|
|
@ -171,11 +165,9 @@ def update(tenant_id, user_id, changes):
|
|||
users.email,
|
||||
users.role,
|
||||
users.name,
|
||||
basic_authentication.generated_password AS change_password,
|
||||
(CASE WHEN users.role = 'owner' THEN TRUE ELSE FALSE END) AS super_admin,
|
||||
(CASE WHEN users.role = 'admin' THEN TRUE ELSE FALSE END) AS admin,
|
||||
(CASE WHEN users.role = 'member' THEN TRUE ELSE FALSE END) AS member,
|
||||
users.appearance,
|
||||
users.role_id;""",
|
||||
{"tenant_id": tenant_id, "user_id": user_id, **changes})
|
||||
)
|
||||
|
|
@ -192,11 +184,9 @@ def update(tenant_id, user_id, changes):
|
|||
users.email,
|
||||
users.role,
|
||||
users.name,
|
||||
basic_authentication.generated_password AS change_password,
|
||||
(CASE WHEN users.role = 'owner' THEN TRUE ELSE FALSE END) AS super_admin,
|
||||
(CASE WHEN users.role = 'admin' THEN TRUE ELSE FALSE END) AS admin,
|
||||
(CASE WHEN users.role = 'member' THEN TRUE ELSE FALSE END) AS member,
|
||||
users.appearance,
|
||||
users.role_id;""",
|
||||
{"tenant_id": tenant_id, "user_id": user_id, **changes})
|
||||
)
|
||||
|
|
@ -272,12 +262,10 @@ def get(user_id, tenant_id):
|
|||
users.user_id AS id,
|
||||
email,
|
||||
role,
|
||||
users.name,
|
||||
basic_authentication.generated_password,
|
||||
users.name,
|
||||
(CASE WHEN role = 'owner' THEN TRUE ELSE FALSE END) AS super_admin,
|
||||
(CASE WHEN role = 'admin' THEN TRUE ELSE FALSE END) AS admin,
|
||||
(CASE WHEN role = 'member' THEN TRUE ELSE FALSE END) AS member,
|
||||
appearance,
|
||||
api_key,
|
||||
origin,
|
||||
role_id,
|
||||
|
|
@ -296,7 +284,7 @@ def get(user_id, tenant_id):
|
|||
{"userId": user_id, "tenant_id": tenant_id})
|
||||
)
|
||||
r = cur.fetchone()
|
||||
return helper.dict_to_camel_case(r, ignore_keys=["appearance"])
|
||||
return helper.dict_to_camel_case(r)
|
||||
|
||||
|
||||
def generate_new_api_key(user_id):
|
||||
|
|
@ -316,7 +304,7 @@ def generate_new_api_key(user_id):
|
|||
|
||||
|
||||
def edit(user_id_to_update, tenant_id, changes, editor_id):
|
||||
ALLOW_EDIT = ["name", "email", "admin", "appearance", "roleId"]
|
||||
ALLOW_EDIT = ["name", "email", "admin", "roleId"]
|
||||
user = get(user_id=user_id_to_update, tenant_id=tenant_id)
|
||||
if editor_id != user_id_to_update or "admin" in changes and changes["admin"] != user["admin"]:
|
||||
admin = get(tenant_id=tenant_id, user_id=editor_id)
|
||||
|
|
@ -349,11 +337,6 @@ def edit(user_id_to_update, tenant_id, changes, editor_id):
|
|||
return {"data": user}
|
||||
|
||||
|
||||
def edit_appearance(user_id, tenant_id, changes):
|
||||
updated_user = update(tenant_id=tenant_id, user_id=user_id, changes=changes)
|
||||
return {"data": updated_user}
|
||||
|
||||
|
||||
def get_by_email_only(email):
|
||||
with pg_client.PostgresClient() as cur:
|
||||
cur.execute(
|
||||
|
|
@ -363,8 +346,7 @@ def get_by_email_only(email):
|
|||
users.tenant_id,
|
||||
users.email,
|
||||
users.role,
|
||||
users.name,
|
||||
basic_authentication.generated_password,
|
||||
users.name,
|
||||
(CASE WHEN users.role = 'owner' THEN TRUE ELSE FALSE END) AS super_admin,
|
||||
(CASE WHEN users.role = 'admin' THEN TRUE ELSE FALSE END) AS admin,
|
||||
(CASE WHEN users.role = 'member' THEN TRUE ELSE FALSE END) AS member,
|
||||
|
|
@ -389,8 +371,7 @@ def get_by_email_reset(email, reset_token):
|
|||
users.tenant_id,
|
||||
users.email,
|
||||
users.role,
|
||||
users.name,
|
||||
basic_authentication.generated_password,
|
||||
users.name,
|
||||
(CASE WHEN users.role = 'owner' THEN TRUE ELSE FALSE END) AS super_admin,
|
||||
(CASE WHEN users.role = 'admin' THEN TRUE ELSE FALSE END) AS admin,
|
||||
(CASE WHEN users.role = 'member' THEN TRUE ELSE FALSE END) AS member
|
||||
|
|
@ -414,8 +395,7 @@ def get_members(tenant_id):
|
|||
users.email,
|
||||
users.role,
|
||||
users.name,
|
||||
users.created_at,
|
||||
basic_authentication.generated_password,
|
||||
users.created_at,
|
||||
(CASE WHEN users.role = 'owner' THEN TRUE ELSE FALSE END) AS super_admin,
|
||||
(CASE WHEN users.role = 'admin' THEN TRUE ELSE FALSE END) AS admin,
|
||||
(CASE WHEN users.role = 'member' THEN TRUE ELSE FALSE END) AS member,
|
||||
|
|
@ -642,11 +622,9 @@ def authenticate(email, password, for_change_password=False, for_plugin=False):
|
|||
users.tenant_id,
|
||||
users.role,
|
||||
users.name,
|
||||
basic_authentication.generated_password AS change_password,
|
||||
(CASE WHEN users.role = 'owner' THEN TRUE ELSE FALSE END) AS super_admin,
|
||||
(CASE WHEN users.role = 'admin' THEN TRUE ELSE FALSE END) AS admin,
|
||||
(CASE WHEN users.role = 'member' THEN TRUE ELSE FALSE END) AS member,
|
||||
users.appearance,
|
||||
users.origin,
|
||||
users.role_id,
|
||||
roles.name AS role_name,
|
||||
|
|
@ -678,7 +656,7 @@ def authenticate(email, password, for_change_password=False, for_plugin=False):
|
|||
if r is not None:
|
||||
if for_change_password:
|
||||
return True
|
||||
r = helper.dict_to_camel_case(r, ignore_keys=["appearance"])
|
||||
r = helper.dict_to_camel_case(r)
|
||||
jwt_iat = change_jwt_iat(r['id'])
|
||||
return {
|
||||
"jwt": authorizers.generate_jwt(r['id'], r['tenantId'],
|
||||
|
|
@ -698,11 +676,9 @@ def authenticate_sso(email, internal_id, exp=None):
|
|||
users.tenant_id,
|
||||
users.role,
|
||||
users.name,
|
||||
False AS change_password,
|
||||
(CASE WHEN users.role = 'owner' THEN TRUE ELSE FALSE END) AS super_admin,
|
||||
(CASE WHEN users.role = 'admin' THEN TRUE ELSE FALSE END) AS admin,
|
||||
(CASE WHEN users.role = 'member' THEN TRUE ELSE FALSE END) AS member,
|
||||
users.appearance,
|
||||
origin,
|
||||
role_id
|
||||
FROM public.users AS users
|
||||
|
|
@ -713,7 +689,7 @@ def authenticate_sso(email, internal_id, exp=None):
|
|||
r = cur.fetchone()
|
||||
|
||||
if r is not None:
|
||||
r = helper.dict_to_camel_case(r, ignore_keys=["appearance"])
|
||||
r = helper.dict_to_camel_case(r)
|
||||
jwt_iat = TimeUTC.datetime_to_timestamp(change_jwt_iat(r['id']))
|
||||
return authorizers.generate_jwt(r['id'], r['tenantId'],
|
||||
jwt_iat, aud=f"front:{helper.get_stage_name()}",
|
||||
|
|
@ -740,11 +716,9 @@ def create_sso_user(tenant_id, email, admin, name, origin, role_id, internal_id=
|
|||
u.email,
|
||||
u.role,
|
||||
u.name,
|
||||
TRUE AS change_password,
|
||||
(CASE WHEN u.role = 'owner' THEN TRUE ELSE FALSE END) AS super_admin,
|
||||
(CASE WHEN u.role = 'admin' THEN TRUE ELSE FALSE END) AS admin,
|
||||
(CASE WHEN u.role = 'member' THEN TRUE ELSE FALSE END) AS member,
|
||||
u.appearance,
|
||||
origin
|
||||
FROM u;""",
|
||||
{"tenant_id": tenant_id, "email": email, "internal_id": internal_id,
|
||||
|
|
@ -774,7 +748,6 @@ def restore_sso_user(user_id, tenant_id, email, admin, name, origin, role_id, in
|
|||
created_at= default,
|
||||
api_key= default,
|
||||
jwt_iat= NULL,
|
||||
appearance= default,
|
||||
weekly_report= default
|
||||
WHERE user_id = %(user_id)s
|
||||
RETURNING *
|
||||
|
|
@ -782,7 +755,6 @@ def restore_sso_user(user_id, tenant_id, email, admin, name, origin, role_id, in
|
|||
au AS (
|
||||
UPDATE public.basic_authentication
|
||||
SET password= default,
|
||||
generated_password= default,
|
||||
invitation_token= default,
|
||||
invited_at= default,
|
||||
change_pwd_token= default,
|
||||
|
|
@ -795,11 +767,9 @@ def restore_sso_user(user_id, tenant_id, email, admin, name, origin, role_id, in
|
|||
u.email,
|
||||
u.role,
|
||||
u.name,
|
||||
TRUE AS change_password,
|
||||
(CASE WHEN u.role = 'owner' THEN TRUE ELSE FALSE END) AS super_admin,
|
||||
(CASE WHEN u.role = 'admin' THEN TRUE ELSE FALSE END) AS admin,
|
||||
(CASE WHEN u.role = 'member' THEN TRUE ELSE FALSE END) AS member,
|
||||
u.appearance,
|
||||
origin
|
||||
FROM u;""",
|
||||
{"tenant_id": tenant_id, "email": email, "internal_id": internal_id,
|
||||
|
|
|
|||
|
|
@ -72,18 +72,18 @@ def login(data: schemas.UserLoginSchema = Body(...)):
|
|||
@app.get('/account', tags=['accounts'])
|
||||
def get_account(context: schemas.CurrentContext = Depends(OR_context)):
|
||||
r = users.get(tenant_id=context.tenant_id, user_id=context.user_id)
|
||||
t = tenants.get_by_tenant_id(context.tenant_id)
|
||||
if t is not None:
|
||||
t.pop("createdAt")
|
||||
t["tenantName"] = t.pop("name")
|
||||
return {
|
||||
'data': {
|
||||
**r,
|
||||
"limits": {
|
||||
"teamMember": -1,
|
||||
"projects": -1,
|
||||
"metadata": metadata.get_remaining_metadata_with_count(context.tenant_id)
|
||||
},
|
||||
**t,
|
||||
**license.get_status(context.tenant_id),
|
||||
"smtp": helper.has_smtp(),
|
||||
"saml2": SAML2_helper.is_saml2_available(),
|
||||
"iceServers": assist.get_ice_servers()
|
||||
# "iceServers": assist.get_ice_servers()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -209,30 +209,25 @@ def search_sessions_by_metadata(key: str, value: str, projectId: Optional[int] =
|
|||
m_key=key, project_id=projectId)}
|
||||
|
||||
|
||||
@app.get('/plans', tags=["plan"])
|
||||
def get_current_plan(context: schemas.CurrentContext = Depends(OR_context)):
|
||||
return {
|
||||
"data": license.get_status(context.tenant_id)
|
||||
}
|
||||
|
||||
|
||||
@public_app.get('/general_stats', tags=["private"], include_in_schema=False)
|
||||
def get_general_stats():
|
||||
return {"data": {"sessions:": sessions.count_all()}}
|
||||
|
||||
|
||||
@app.get('/client', tags=['projects'])
|
||||
def get_client(context: schemas.CurrentContext = Depends(OR_context)):
|
||||
r = tenants.get_by_tenant_id(context.tenant_id)
|
||||
if r is not None:
|
||||
r.pop("createdAt")
|
||||
|
||||
return {
|
||||
'data': r
|
||||
}
|
||||
|
||||
|
||||
@app.get('/projects', tags=['projects'])
|
||||
def get_projects(context: schemas.CurrentContext = Depends(OR_context)):
|
||||
return {"data": projects.get_projects(tenant_id=context.tenant_id, recording_state=True, gdpr=True, recorded=True,
|
||||
stack_integrations=True, user_id=context.user_id)}
|
||||
|
||||
|
||||
@app.get('/limits', tags=['accounts'])
|
||||
def get_limits(context: schemas.CurrentContext = Depends(OR_context)):
|
||||
return {
|
||||
'data': {
|
||||
"limits": {
|
||||
"teamMember": -1,
|
||||
"projects": -1,
|
||||
"metadata": metadata.get_remaining_metadata_with_count(context.tenant_id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,25 @@
|
|||
BEGIN;
|
||||
CREATE OR REPLACE FUNCTION openreplay_version()
|
||||
CREATE OR REPLACE
|
||||
FUNCTION openreplay_version()
|
||||
RETURNS text AS
|
||||
$$
|
||||
SELECT 'v1.6.1-ee'
|
||||
$$ LANGUAGE sql IMMUTABLE;
|
||||
SELECT 'v1.6.1-ee' $$ LANGUAGE sql IMMUTABLE;
|
||||
|
||||
|
||||
ALTER TABLE IF EXISTS dashboards
|
||||
ADD COLUMN IF NOT EXISTS description text NOT NULL DEFAULT '';
|
||||
ADD COLUMN IF NOT
|
||||
EXISTS description text NOT NULL DEFAULT '';
|
||||
|
||||
|
||||
CREATE INDEX IF NOT EXISTS traces_created_at_idx ON traces (created_at);
|
||||
CREATE INDEX IF NOT EXISTS traces_action_idx ON traces (action);
|
||||
CREATE INDEX IF NOT EXISTS users_name_gin_idx ON users USING GIN (name gin_trgm_ops);
|
||||
CREATE
|
||||
INDEX IF NOT
|
||||
EXISTS traces_created_at_idx ON traces (created_at);
|
||||
CREATE
|
||||
INDEX IF NOT
|
||||
EXISTS traces_action_idx ON traces (action);
|
||||
CREATE
|
||||
INDEX IF NOT
|
||||
EXISTS users_name_gin_idx ON users USING GIN (name gin_trgm_ops);
|
||||
|
||||
INSERT INTO metrics (name, category, default_config, is_predefined, is_template, is_public, predefined_key, metric_type,
|
||||
view_type)
|
||||
|
|
@ -115,9 +122,9 @@ VALUES ('Captured sessions', 'web vitals', '{
|
|||
"col": 1,
|
||||
"row": 1,
|
||||
"position": 0
|
||||
}', true, true, true, 'avg_fps', 'predefined', 'overview')
|
||||
ON CONFLICT (predefined_key) DO UPDATE
|
||||
SET name=excluded.name,
|
||||
}', true, true, true, 'avg_fps', 'predefined', 'overview') ON CONFLICT (predefined_key) DO
|
||||
UPDATE
|
||||
SET name =excluded.name,
|
||||
category=excluded.category,
|
||||
default_config=excluded.default_config,
|
||||
is_predefined=excluded.is_predefined,
|
||||
|
|
@ -126,4 +133,10 @@ ON CONFLICT (predefined_key) DO UPDATE
|
|||
metric_type=excluded.metric_type,
|
||||
view_type=excluded.view_type;
|
||||
|
||||
ALTER TABLE users
|
||||
DROP COLUMN appearance;
|
||||
|
||||
ALTER TABLE basic_authentication
|
||||
DROP COLUMN generated_password;
|
||||
|
||||
COMMIT;
|
||||
|
|
@ -7,7 +7,7 @@ CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
|||
CREATE OR REPLACE FUNCTION openreplay_version()
|
||||
RETURNS text AS
|
||||
$$
|
||||
SELECT 'v1.6.0-ee'
|
||||
SELECT 'v1.7.0-ee'
|
||||
$$ LANGUAGE sql IMMUTABLE;
|
||||
|
||||
|
||||
|
|
@ -187,67 +187,6 @@ $$
|
|||
name text NOT NULL,
|
||||
created_at timestamp without time zone NOT NULL default (now() at time zone 'utc'),
|
||||
deleted_at timestamp without time zone NULL DEFAULT NULL,
|
||||
appearance jsonb NOT NULL default '{
|
||||
"role": "dev",
|
||||
"dashboard": {
|
||||
"cpu": true,
|
||||
"fps": false,
|
||||
"avgCpu": true,
|
||||
"avgFps": true,
|
||||
"errors": true,
|
||||
"crashes": true,
|
||||
"overview": true,
|
||||
"sessions": true,
|
||||
"topMetrics": true,
|
||||
"callsErrors": true,
|
||||
"pageMetrics": true,
|
||||
"performance": true,
|
||||
"timeToRender": false,
|
||||
"userActivity": false,
|
||||
"avgFirstPaint": false,
|
||||
"countSessions": true,
|
||||
"errorsPerType": true,
|
||||
"slowestImages": true,
|
||||
"speedLocation": true,
|
||||
"slowestDomains": true,
|
||||
"avgPageLoadTime": true,
|
||||
"avgTillFirstBit": false,
|
||||
"avgTimeToRender": true,
|
||||
"avgVisitedPages": false,
|
||||
"avgImageLoadTime": true,
|
||||
"busiestTimeOfDay": true,
|
||||
"errorsPerDomains": true,
|
||||
"missingResources": true,
|
||||
"resourcesByParty": true,
|
||||
"sessionsFeedback": false,
|
||||
"slowestResources": true,
|
||||
"avgUsedJsHeapSize": true,
|
||||
"domainsErrors_4xx": true,
|
||||
"domainsErrors_5xx": true,
|
||||
"memoryConsumption": true,
|
||||
"pagesDomBuildtime": false,
|
||||
"pagesResponseTime": true,
|
||||
"avgRequestLoadTime": true,
|
||||
"avgSessionDuration": false,
|
||||
"sessionsPerBrowser": false,
|
||||
"applicationActivity": true,
|
||||
"sessionsFrustration": false,
|
||||
"avgPagesDomBuildtime": true,
|
||||
"avgPagesResponseTime": false,
|
||||
"avgTimeToInteractive": true,
|
||||
"resourcesCountByType": true,
|
||||
"resourcesLoadingTime": true,
|
||||
"avgDomContentLoadStart": true,
|
||||
"avgFirstContentfulPixel": false,
|
||||
"resourceTypeVsResponseEnd": true,
|
||||
"impactedSessionsByJsErrors": true,
|
||||
"impactedSessionsBySlowPages": true,
|
||||
"resourcesVsVisuallyComplete": true,
|
||||
"pagesResponseTimeDistribution": true
|
||||
},
|
||||
"sessionsLive": false,
|
||||
"sessionsDevtools": true
|
||||
}'::jsonb,
|
||||
api_key text UNIQUE default generate_api_key(20) not null,
|
||||
jwt_iat timestamp without time zone NULL DEFAULT NULL,
|
||||
data jsonb NOT NULL DEFAULT'{}'::jsonb,
|
||||
|
|
@ -264,7 +203,6 @@ $$
|
|||
(
|
||||
user_id integer NOT NULL REFERENCES users (user_id) ON DELETE CASCADE,
|
||||
password text DEFAULT NULL,
|
||||
generated_password boolean NOT NULL DEFAULT false,
|
||||
invitation_token text NULL DEFAULT NULL,
|
||||
invited_at timestamp without time zone NULL DEFAULT NULL,
|
||||
change_pwd_token text NULL DEFAULT NULL,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ BEGIN;
|
|||
CREATE OR REPLACE FUNCTION openreplay_version()
|
||||
RETURNS text AS
|
||||
$$
|
||||
SELECT 'v1.6.1'
|
||||
SELECT 'v1.7.0'
|
||||
$$ LANGUAGE sql IMMUTABLE;
|
||||
|
||||
|
||||
|
|
@ -121,4 +121,10 @@ ON CONFLICT (predefined_key) DO UPDATE
|
|||
metric_type=excluded.metric_type,
|
||||
view_type=excluded.view_type;
|
||||
|
||||
ALTER TABLE users
|
||||
DROP COLUMN appearance;
|
||||
|
||||
ALTER TABLE basic_authentication
|
||||
DROP COLUMN generated_password;
|
||||
|
||||
COMMIT;
|
||||
|
|
@ -6,7 +6,7 @@ CREATE SCHEMA IF NOT EXISTS events;
|
|||
CREATE OR REPLACE FUNCTION openreplay_version()
|
||||
RETURNS text AS
|
||||
$$
|
||||
SELECT 'v1.6.0'
|
||||
SELECT 'v1.7.0'
|
||||
$$ LANGUAGE sql IMMUTABLE;
|
||||
|
||||
-- --- accounts.sql ---
|
||||
|
|
@ -142,67 +142,6 @@ $$
|
|||
name text NOT NULL,
|
||||
created_at timestamp without time zone NOT NULL default (now() at time zone 'utc'),
|
||||
deleted_at timestamp without time zone NULL DEFAULT NULL,
|
||||
appearance jsonb NOT NULL default '{
|
||||
"role": "dev",
|
||||
"dashboard": {
|
||||
"cpu": true,
|
||||
"fps": false,
|
||||
"avgCpu": true,
|
||||
"avgFps": true,
|
||||
"errors": true,
|
||||
"crashes": true,
|
||||
"overview": true,
|
||||
"sessions": true,
|
||||
"topMetrics": true,
|
||||
"callsErrors": true,
|
||||
"pageMetrics": true,
|
||||
"performance": true,
|
||||
"timeToRender": false,
|
||||
"userActivity": false,
|
||||
"avgFirstPaint": false,
|
||||
"countSessions": true,
|
||||
"errorsPerType": true,
|
||||
"slowestImages": true,
|
||||
"speedLocation": true,
|
||||
"slowestDomains": true,
|
||||
"avgPageLoadTime": true,
|
||||
"avgTillFirstBit": false,
|
||||
"avgTimeToRender": true,
|
||||
"avgVisitedPages": false,
|
||||
"avgImageLoadTime": true,
|
||||
"busiestTimeOfDay": true,
|
||||
"errorsPerDomains": true,
|
||||
"missingResources": true,
|
||||
"resourcesByParty": true,
|
||||
"sessionsFeedback": false,
|
||||
"slowestResources": true,
|
||||
"avgUsedJsHeapSize": true,
|
||||
"domainsErrors_4xx": true,
|
||||
"domainsErrors_5xx": true,
|
||||
"memoryConsumption": true,
|
||||
"pagesDomBuildtime": false,
|
||||
"pagesResponseTime": true,
|
||||
"avgRequestLoadTime": true,
|
||||
"avgSessionDuration": false,
|
||||
"sessionsPerBrowser": false,
|
||||
"applicationActivity": true,
|
||||
"sessionsFrustration": false,
|
||||
"avgPagesDomBuildtime": true,
|
||||
"avgPagesResponseTime": false,
|
||||
"avgTimeToInteractive": true,
|
||||
"resourcesCountByType": true,
|
||||
"resourcesLoadingTime": true,
|
||||
"avgDomContentLoadStart": true,
|
||||
"avgFirstContentfulPixel": false,
|
||||
"resourceTypeVsResponseEnd": true,
|
||||
"impactedSessionsByJsErrors": true,
|
||||
"impactedSessionsBySlowPages": true,
|
||||
"resourcesVsVisuallyComplete": true,
|
||||
"pagesResponseTimeDistribution": true
|
||||
},
|
||||
"sessionsLive": false,
|
||||
"sessionsDevtools": true
|
||||
}'::jsonb,
|
||||
api_key text UNIQUE default generate_api_key(20) not null,
|
||||
jwt_iat timestamp without time zone NULL DEFAULT NULL,
|
||||
data jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
|
|
@ -213,7 +152,6 @@ $$
|
|||
(
|
||||
user_id integer NOT NULL REFERENCES users (user_id) ON DELETE CASCADE,
|
||||
password text DEFAULT NULL,
|
||||
generated_password boolean NOT NULL DEFAULT false,
|
||||
invitation_token text NULL DEFAULT NULL,
|
||||
invited_at timestamp without time zone NULL DEFAULT NULL,
|
||||
change_pwd_token text NULL DEFAULT NULL,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue