diff --git a/engine/core/signals.py b/engine/core/signals.py
index 43fe5e65..6e71c485 100644
--- a/engine/core/signals.py
+++ b/engine/core/signals.py
@@ -70,14 +70,15 @@ def create_wishlist_on_user_creation_signal(
def create_promocode_on_user_referring(
instance: User, created: bool, **kwargs: dict[Any, Any]
) -> None:
- try:
- if type(instance.attributes) is not dict:
- instance.attributes = {}
- instance.save()
+ if not created:
+ return
- if created and instance.attributes.get("referrer", ""):
+ try:
+ attrs = instance.attributes if isinstance(instance.attributes, dict) else {}
+
+ if attrs.get("referrer", ""):
referrer_uuid = urlsafe_base64_decode(
- instance.attributes.get("referrer", "")
+ attrs.get("referrer", "")
).decode()
referrer = User.objects.get(uuid=referrer_uuid)
code = f"WELCOME-{get_random_string(6)}"
diff --git a/engine/core/templates/admin/core/change_form_with_storefront_link.html b/engine/core/templates/admin/core/change_form_with_storefront_link.html
index c89434e6..71995314 100644
--- a/engine/core/templates/admin/core/change_form_with_storefront_link.html
+++ b/engine/core/templates/admin/core/change_form_with_storefront_link.html
@@ -1,18 +1,5 @@
{% extends "admin/change_form.html" %}
-{% load i18n admin_modify %}
{% block submit_buttons_bottom %}
- {% submit_row %}
-
- {% if original and storefront_url %}
-
- {% endif %}
+ {% include "admin/core/submit_line_with_storefront_link.html" %}
{% endblock %}
diff --git a/engine/core/templates/admin/core/submit_line_with_storefront_link.html b/engine/core/templates/admin/core/submit_line_with_storefront_link.html
new file mode 100644
index 00000000..b9918324
--- /dev/null
+++ b/engine/core/templates/admin/core/submit_line_with_storefront_link.html
@@ -0,0 +1,79 @@
+{% load i18n admin_urls unfold %}
+
+
diff --git a/engine/vibes_auth/graphene/mutations.py b/engine/vibes_auth/graphene/mutations.py
index 6ab3841a..b51e42ef 100644
--- a/engine/vibes_auth/graphene/mutations.py
+++ b/engine/vibes_auth/graphene/mutations.py
@@ -153,19 +153,25 @@ class UpdateUser(Mutation):
user.set_password(password)
user.save()
- attribute_pairs = kwargs.pop("attributes", "")
+ new_attributes = kwargs.pop("attributes", None)
- if attribute_pairs:
+ if new_attributes is not None:
if not isinstance(user.attributes, dict):
user.attributes = {}
- for attribute_pair in attribute_pairs.split(";"):
- if "-" in attribute_pair:
- attr, value = attribute_pair.split("-", 1)
- user.attributes[attr] = value
- else:
- raise BadRequest(
- _(f"Invalid attribute format: {attribute_pair}")
- )
+
+ if isinstance(new_attributes, dict):
+ user.attributes.update(new_attributes)
+ elif isinstance(new_attributes, str) and new_attributes:
+ for attribute_pair in new_attributes.split(";"):
+ if "-" in attribute_pair:
+ attr, value = attribute_pair.split("-", 1)
+ user.attributes[attr] = value
+ else:
+ raise BadRequest(
+ _(f"Invalid attribute format: {attribute_pair}")
+ )
+ else:
+ raise BadRequest(_("attributes must be a dict or a string"))
for attr, value in kwargs.items():
if attr == "password" or attr == "confirm_password":
diff --git a/schon/fields.py b/schon/fields.py
index 33dfa3cd..c98e9d2d 100644
--- a/schon/fields.py
+++ b/schon/fields.py
@@ -1,5 +1,6 @@
import orjson
from cryptography.fernet import InvalidToken
+from django import forms
from encrypted_fields.fields import EncryptedTextField
@@ -16,6 +17,9 @@ class EncryptedJSONTextField(EncryptedTextField):
def get_internal_type(self) -> str:
return "TextField"
+ def formfield(self, **kwargs):
+ return super().formfield(**{"form_class": forms.JSONField, **kwargs})
+
def get_prep_value(self, value):
if value is not None and not isinstance(value, str):
value = orjson.dumps(value, default=str).decode("utf-8")