diff --git a/back/bots/admin.py b/back/bots/admin.py index fe909e9..b9cb6d9 100644 --- a/back/bots/admin.py +++ b/back/bots/admin.py @@ -37,7 +37,7 @@ def get_readonly_fields(self, request, obj=None): return ['created_at', 'modified_at', 'profile_id'] def get_list_display(self, request): - return ['profile_id', 'created_at', 'modified_at'] + list(super().get_list_display(request)) + return ['profile_id', 'name', 'user', 'oauth_email', 'created_at', 'modified_at'] + list(super().get_list_display(request)) class BotAdmin(admin.ModelAdmin): def get_readonly_fields(self, request, obj=None): diff --git a/back/bots/migrations/0034_profile_oauth_email.py b/back/bots/migrations/0034_profile_oauth_email.py new file mode 100644 index 0000000..2729dba --- /dev/null +++ b/back/bots/migrations/0034_profile_oauth_email.py @@ -0,0 +1,18 @@ +# Generated by Django 6.0.3 on 2026-04-12 02:39 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('bots', '0033_add_enable_web_search'), + ] + + operations = [ + migrations.AddField( + model_name='profile', + name='oauth_email', + field=models.EmailField(blank=True, max_length=254, null=True), + ), + ] diff --git a/back/bots/models/profile.py b/back/bots/models/profile.py index 5541505..22709b3 100644 --- a/back/bots/models/profile.py +++ b/back/bots/models/profile.py @@ -10,6 +10,7 @@ class Profile(models.Model): ) profile_id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True) name = models.CharField(max_length=255) + oauth_email = models.EmailField(max_length=254, null=True, blank=True) deleted_at = models.DateTimeField(null=True, blank=True) created_at = models.DateTimeField(auto_now_add=True) diff --git a/back/bots/views/get_jwt.py b/back/bots/views/get_jwt.py index 20a998a..0c56af6 100644 --- a/back/bots/views/get_jwt.py +++ b/back/bots/views/get_jwt.py @@ -5,14 +5,25 @@ from django.shortcuts import render import environ -# Initialize environ +from bots.models import Profile + env = environ.Env( - DEBUG=(bool, False) # Set default values and casting types + DEBUG=(bool, False) ) -# Read from .env file environ.Env.read_env('.env') +def get_delegated_tokens(user, teen_profile): + """Generate JWT tokens for the parent account (delegated login).""" + parent_user = teen_profile.user + refresh = RefreshToken.for_user(parent_user) + return { + 'access': str(refresh.access_token), + 'refresh': str(refresh), + 'active_profile_id': str(teen_profile.profile_id), + 'is_teen_delegated': True + } + @api_view(['GET']) @permission_classes([AllowAny]) def start_web_login(self): @@ -26,14 +37,17 @@ def get_jwt(request): user = request.user - refresh = RefreshToken.for_user(user) - - response_data = { - 'access': str(refresh.access_token), - 'refresh': str(refresh), - } + try: + teen_profile = Profile.objects.get(oauth_email=user.email) + response_data = get_delegated_tokens(user, teen_profile) + except Profile.DoesNotExist: + refresh = RefreshToken.for_user(user) + response_data = { + 'access': str(refresh.access_token), + 'refresh': str(refresh), + } if 'json' in request.query_params: return JsonResponse(response_data) - return render(request, 'jwt_template.html', {'app_deep_url': env('APP_DEEP_URL'), 'access': str(refresh.access_token), 'refresh': str(refresh)}) + return render(request, 'jwt_template.html', {'app_deep_url': env('APP_DEEP_URL'), 'access': response_data['access'], 'refresh': response_data['refresh']})