feat(core): add generation & exportation of pub/priv keys

master
Romain J 3 months ago
parent 531c0eb78f
commit 10a19601a1
No known key found for this signature in database
GPG Key ID: 3227578329C2A3A7
  1. 0
      .idea/sonarlint/issuestore/0/2/020b45107d0df50edcd5865afacd54bf4d6632a4
  2. 0
      .idea/sonarlint/issuestore/5/f/5f30f5d04bcb2c49cfde4a698c9a8307bbd4fa6e
  3. 0
      .idea/sonarlint/issuestore/f/8/f8550eeba98ecb491e727fb1d0f24ad5c394d099
  4. 6
      .idea/sonarlint/issuestore/index.pb
  5. 2
      chat/apps/guilds/admin.py
  6. 38
      chat/apps/guilds/features/channels/models.py
  7. 160
      chat/apps/guilds/migrations/0001_initial.py
  8. 130
      chat/apps/guilds/migrations/0002_initial.py
  9. 38
      chat/apps/guilds/migrations/0003_auto_20211114_1732.py
  10. 22
      chat/apps/guilds/migrations/0004_auto_20211114_1754.py
  11. 19
      chat/apps/guilds/migrations/0005_alter_invite_key.py
  12. 19
      chat/apps/guilds/migrations/0006_alter_channel_parent.py
  13. 160
      chat/apps/users/migrations/0001_initial.py
  14. 22
      chat/apps/users/migrations/0002_auto_20220525_1344.py
  15. 18
      chat/apps/users/migrations/0002_user_first_connect.py
  16. 18
      chat/apps/users/migrations/0003_rename_mneomonic_user_mnemonic.py
  17. 18
      chat/apps/users/migrations/0003_rename_pubkey_user_public_key.py
  18. 32
      chat/apps/users/migrations/0004_auto_20211125_1629.py
  19. 36
      chat/apps/users/migrations/0005_auto_20211125_1711.py
  20. 19
      chat/apps/users/migrations/0006_alter_user_settings.py
  21. 24
      chat/apps/users/migrations/0007_auto_20211125_1800.py
  22. 24
      chat/apps/users/migrations/0008_auto_20211126_1212.py
  23. 18
      chat/apps/users/migrations/0009_user_email.py
  24. 17
      chat/apps/users/migrations/0010_remove_user_email.py
  25. 2
      chat/apps/users/models.py
  26. 16
      chat/apps/users/views.py
  27. 2391
      chat/static/js/libs/tweetnacl/nacl-fast.js
  28. 1
      chat/static/js/libs/tweetnacl/nacl-fast.min.js
  29. 81
      chat/static/js/libs/tweetnacl/nacl-util.js
  30. 1
      chat/static/js/libs/tweetnacl/nacl-util.min.js
  31. 1178
      chat/static/js/libs/tweetnacl/nacl.js
  32. 1
      chat/static/js/libs/tweetnacl/nacl.min.js
  33. 36
      chat/templates/account/logout.html
  34. 20
      chat/templates/guild/details.html
  35. 2
      chat/templates/layouts/base.html
  36. 16
      chat/templates/users/first_connect/first.html
  37. 12
      chat/templates/users/first_connect/next.html
  38. 25
      chat/templates/users/settings.html
  39. BIN
      models.png

@ -29,16 +29,10 @@ h
8chat/apps/guilds/features/channels/consumers/__init__.py,e/2/e291cafecaedae4562004377f14184839884fd88
^
.chat/apps/guilds/features/channels/__init__.py,1/e/1ec598764d7b8851aa9d3cd178d3c844b5d132b9
]
-chat/apps/guilds/features/channels/signals.py,5/f/5f30f5d04bcb2c49cfde4a698c9a8307bbd4fa6e
[
+chat/apps/guilds/migrations/0002_initial.py,0/2/020b45107d0df50edcd5865afacd54bf4d6632a4
B
chat/pages/apps.py,b/6/b61d6a1f522283203801f2468bf9caba725507ae
H
chat/apps/users/forms.py,c/5/c590740c4ac867b1db50168e191a9f5bbca5397c
H
chat/apps/guilds/apps.py,f/8/f8550eeba98ecb491e727fb1d0f24ad5c394d099
@
.readthedocs.yml,8/1/81ccd5c4e1f93eb3ab80c73b5532455bf4f82fe9
V

@ -69,8 +69,6 @@ class ChannelAdmin(admin.ModelAdmin):
"guild",
"position",
"parent",
"last_message",
"messages_count",
]
search_fields = ["id", "name"]

@ -59,21 +59,13 @@ class Channel(models.Model):
name = models.TextField(max_length=100)
topic = models.TextField(max_length=1024, blank=True, null=True)
last_message = models.ForeignKey(
"Message",
on_delete=models.SET_NULL,
related_name="last_message",
blank=True,
null=True,
)
# =========================================================================
def get_messages(self):
def get_messages(self, recipient: User):
return Message.objects.filter(channel=self)
def messages_count(self):
return len(self.get_messages().all())
# def messages_count(self):
# return len(self.get_messages().all())
# =========================================================================
@ -99,26 +91,11 @@ class Message(models.Model):
author = models.ForeignKey(
User, on_delete=models.CASCADE, related_name="author"
)
attachments = models.ManyToManyField("Attachment", blank=True)
previous = models.OneToOneField(
"self",
null=True,
blank=True,
related_name="previous_message",
on_delete=models.SET_NULL,
recipient = models.ForeignKey(
User, on_delete=models.CASCADE, related_name="recipient"
)
same_previous_author = models.BooleanField(blank=True, null=True)
next = models.OneToOneField(
"self",
null=True,
blank=True,
related_name="next_message",
on_delete=models.SET_NULL,
)
same_next_author = models.BooleanField(blank=True, null=True)
attachments = models.ManyToManyField("Attachment", blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
@ -131,9 +108,8 @@ class Message(models.Model):
def __str__(self):
return (
f"from: {self.author}, "
f"to: {self.recipient}, "
f"id: {self.id}, "
f"same_previous_author: {self.same_previous_author}, "
f"same_next_author: {self.same_next_author}"
)

@ -1,7 +1,8 @@
# Generated by Django 3.2.8 on 2021-11-10 21:18
# Generated by Django 3.2.8 on 2022-05-25 12:33
import chat.utils.functions
from django.db import migrations, models
import django_extensions.db.fields
import uuid
@ -9,147 +10,66 @@ class Migration(migrations.Migration):
initial = True
dependencies = []
dependencies = [
]
operations = [
migrations.CreateModel(
name="Attachment",
name='Attachment',
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
),
),
(
"filename",
models.TextField(blank=True, default=None, null=True),
),
(
"file",
models.FileField(
upload_to=chat.utils.functions.PathAndRename(
"guilds/attachments"
)
),
),
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('filename', models.TextField(blank=True, default=None, null=True)),
('file', models.FileField(upload_to=chat.utils.functions.PathAndRename('guilds/attachments'))),
],
),
migrations.CreateModel(
name="Channel",
name='Category',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('position', models.IntegerField(default=1)),
('name', models.TextField(max_length=100)),
],
options={
'verbose_name_plural': 'Categories',
},
),
migrations.CreateModel(
name='Channel',
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
),
),
(
"type",
models.CharField(
choices=[
("DM", "Direct Message"),
("GROUP_DM", "Group Direct Message"),
("TEXT", "Text"),
("CATEGORY", "Category"),
("NEWS", "News"),
],
max_length=10,
),
),
("position", models.IntegerField()),
("name", models.TextField(max_length=100)),
(
"topic",
models.TextField(blank=True, max_length=1024, null=True),
),
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('position', models.IntegerField(default=1)),
('name', models.TextField(max_length=100)),
('topic', models.TextField(blank=True, max_length=1024, null=True)),
],
),
migrations.CreateModel(
name="Guild",
name='Guild',
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
),
),
(
"name",
models.CharField(
max_length=200, verbose_name="Guild Name"
),
),
(
"avatar",
models.ImageField(
upload_to=chat.utils.functions.PathAndRename(
"guilds/avatar"
),
verbose_name="Guild Icon",
),
),
(
"description",
models.TextField(blank=True, max_length=1024, null=True),
),
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('name', models.CharField(max_length=200, verbose_name='Guild Name')),
('avatar', models.ImageField(upload_to=chat.utils.functions.PathAndRename('guilds/avatar'), verbose_name='Guild Icon')),
('description', models.TextField(blank=True, max_length=1024, null=True)),
],
),
migrations.CreateModel(
name="Invite",
name='Invite',
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
),
),
("key", models.CharField(max_length=10)),
("uses", models.IntegerField(default=0)),
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('key', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=10, unique=True)),
('uses', models.IntegerField(default=0)),
],
),
migrations.CreateModel(
name="Message",
name='Message',
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
),
),
("content", models.TextField()),
(
"same_previous_author",
models.BooleanField(blank=True, null=True),
),
(
"same_next_author",
models.BooleanField(blank=True, null=True),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
(
"attachments",
models.ManyToManyField(blank=True, to="guilds.Attachment"),
),
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('content', models.TextField()),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('attachments', models.ManyToManyField(blank=True, to='guilds.Attachment')),
],
options={
"ordering": ["created_at"],
'ordering': ['created_at'],
},
),
]

@ -1,4 +1,4 @@
# Generated by Django 3.2.8 on 2021-11-10 21:18
# Generated by Django 3.2.8 on 2022-05-25 12:33
from django.conf import settings
from django.db import migrations, models
@ -11,123 +11,73 @@ class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
("guilds", "0001_initial"),
('guilds', '0001_initial'),
]
operations = [
migrations.AddField(
model_name="message",
name="author",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="author",
to=settings.AUTH_USER_MODEL,
),
model_name='message',
name='author',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='author', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name="message",
name="channel",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
to="guilds.channel",
),
model_name='message',
name='channel',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='guilds.channel'),
),
migrations.AddField(
model_name="message",
name="next",
field=models.OneToOneField(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="next_message",
to="guilds.message",
),
model_name='message',
name='recipient',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='recipient', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name="message",
name="previous",
field=models.OneToOneField(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="previous_message",
to="guilds.message",
),
model_name='invite',
name='author',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name="invite",
name="author",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL,
),
model_name='invite',
name='guild',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='guilds.guild'),
),
migrations.AddField(
model_name="invite",
name="guild",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="guilds.guild"
),
model_name='guild',
name='bans',
field=models.ManyToManyField(related_name='bans', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name="guild",
name="bans",
field=models.ManyToManyField(
related_name="bans", to=settings.AUTH_USER_MODEL
),
model_name='guild',
name='categories',
field=models.ManyToManyField(blank=True, related_name='categories', to='guilds.Category'),
),
migrations.AddField(
model_name="guild",
name="channels",
field=models.ManyToManyField(
blank=True, related_name="channels", to="guilds.Channel"
),
model_name='guild',
name='channels',
field=models.ManyToManyField(blank=True, related_name='channels', to='guilds.Channel'),
),
migrations.AddField(
model_name="guild",
name="members",
model_name='guild',
name='members',
field=models.ManyToManyField(to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name="guild",
name="owner",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="owner",
to=settings.AUTH_USER_MODEL,
),
model_name='guild',
name='owner',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='owner', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name="channel",
name="guild",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
to="guilds.guild",
),
model_name='channel',
name='guild',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='guilds.guild'),
),
migrations.AddField(
model_name="channel",
name="last_message",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="last_message",
to="guilds.message",
),
model_name='channel',
name='parent',
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='guilds.category'),
),
migrations.AddField(
model_name="channel",
name="parent",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to="guilds.channel",
),
model_name='category',
name='guild',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='guilds.guild'),
),
]

@ -1,38 +0,0 @@
# Generated by Django 3.2.8 on 2021-11-14 17:32
from django.db import migrations, models
import django.db.models.deletion
import uuid
class Migration(migrations.Migration):
dependencies = [
('guilds', '0002_initial'),
]
operations = [
migrations.RemoveField(
model_name='channel',
name='type',
),
migrations.AlterField(
model_name='channel',
name='position',
field=models.IntegerField(default=1),
),
migrations.CreateModel(
name='Category',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('position', models.IntegerField(default=1)),
('name', models.TextField(max_length=100)),
('guild', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='guilds.guild')),
],
),
migrations.AlterField(
model_name='channel',
name='parent',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='guilds.category'),
),
]

@ -1,22 +0,0 @@
# Generated by Django 3.2.8 on 2021-11-14 17:54
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('guilds', '0003_auto_20211114_1732'),
]
operations = [
migrations.AlterModelOptions(
name='category',
options={'verbose_name_plural': 'Categories'},
),
migrations.AddField(
model_name='guild',
name='categories',
field=models.ManyToManyField(blank=True, related_name='categories', to='guilds.Category'),
),
]

@ -1,19 +0,0 @@
# Generated by Django 3.2.8 on 2022-02-15 17:07
from django.db import migrations
import django_extensions.db.fields
class Migration(migrations.Migration):
dependencies = [
('guilds', '0004_auto_20211114_1754'),
]
operations = [
migrations.AlterField(
model_name='invite',
name='key',
field=django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=10, unique=True),
),
]

@ -1,19 +0,0 @@
# Generated by Django 3.2.8 on 2022-05-21 22:01
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('guilds', '0005_alter_invite_key'),
]
operations = [
migrations.AlterField(
model_name='channel',
name='parent',
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='guilds.category'),
),
]

@ -1,9 +1,10 @@
# Generated by Django 3.2.8 on 2021-11-10 21:18
# Generated by Django 3.2.8 on 2022-05-25 12:33
import chat.utils.functions
import django.contrib.auth.models
import django.contrib.auth.validators
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import uuid
@ -13,137 +14,50 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
("auth", "0012_alter_user_first_name_max_length"),
('guilds', '0001_initial'),
('auth', '0012_alter_user_first_name_max_length'),
]
operations = [
migrations.CreateModel(
name="User",
name='UserSettings',
fields=[
(
"password",
models.CharField(max_length=128, verbose_name="password"),
),
(
"last_login",
models.DateTimeField(
blank=True, null=True, verbose_name="last login"
),
),
(
"is_superuser",
models.BooleanField(
default=False,
help_text="Designates that this user has all permissions without explicitly assigning them.",
verbose_name="superuser status",
),
),
(
"username",
models.CharField(
error_messages={
"unique": "A user with that username already exists."
},
help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.",
max_length=150,
unique=True,
validators=[
django.contrib.auth.validators.UnicodeUsernameValidator()
],
verbose_name="username",
),
),
(
"is_staff",
models.BooleanField(
default=False,
help_text="Designates whether the user can log into this admin site.",
verbose_name="staff status",
),
),
(
"is_active",
models.BooleanField(
default=True,
help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.",
verbose_name="active",
),
),
(
"date_joined",
models.DateTimeField(
default=django.utils.timezone.now,
verbose_name="date joined",
),
),
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
),
),
(
"avatar",
models.ImageField(
blank=True,
null=True,
upload_to=chat.utils.functions.PathAndRename(
"users/avatar"
),
),
),
(
"bio",
models.TextField(blank=True, max_length=1000, null=True),
),
(
"language",
models.CharField(
choices=[
("fr-FR", "Français (beta)"),
("en-US", "English"),
],
default="en-us",
max_length=10,
),
),
(
"mneomonic",
models.CharField(blank=True, max_length=255, null=True),
),
(
"groups",
models.ManyToManyField(
blank=True,
help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.",
related_name="user_set",
related_query_name="user",
to="auth.Group",
verbose_name="groups",
),
),
(
"user_permissions",
models.ManyToManyField(
blank=True,
help_text="Specific permissions for this user.",
related_name="user_set",
related_query_name="user",
to="auth.Permission",
verbose_name="user permissions",
),
),
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('language', models.CharField(choices=[('fr-fr', 'Français (beta)'), ('en-us', 'English')], default='en-us', max_length=10)),
('theme', models.CharField(choices=[('DK', 'Dark'), ('LT', 'Light')], default='DK', max_length=2)),
('avatar', models.ImageField(blank=True, null=True, upload_to=chat.utils.functions.PathAndRename('users/avatar'))),
('bio', models.TextField(blank=True, max_length=1000, null=True)),
('pubkey', models.TextField(blank=True, default=None, null=True)),
('collapsed_categories', models.ManyToManyField(blank=True, default=None, to='guilds.Category')),
],
options={
"verbose_name": "user",
"verbose_name_plural": "users",
"abstract": False,
'verbose_name_plural': 'User Settings',
},
),
migrations.CreateModel(
name='User',
fields=[
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('first_connect', models.BooleanField(default=True)),
('mnemonic', models.CharField(blank=True, max_length=255, null=True)),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
('settings', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='user_settings', to='users.usersettings')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
],
options={
'verbose_name': 'user',
'verbose_name_plural': 'users',
'abstract': False,
},
managers=[
("objects", django.contrib.auth.models.UserManager()),
('objects', django.contrib.auth.models.UserManager()),
],
),
]

@ -0,0 +1,22 @@
# Generated by Django 3.2.8 on 2022-05-25 13:44
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='usersettings',
name='pubkey',
),
migrations.AddField(
model_name='user',
name='pubkey',
field=models.CharField(blank=True, max_length=255, null=True),
),
]

@ -1,18 +0,0 @@
# Generated by Django 3.2.8 on 2021-11-11 18:24
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("users", "0001_initial"),
]
operations = [
migrations.AddField(
model_name="user",
name="first_connect",
field=models.BooleanField(default=True),
),
]

@ -1,18 +0,0 @@
# Generated by Django 3.2.8 on 2021-11-11 22:46
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("users", "0002_user_first_connect"),
]
operations = [
migrations.RenameField(
model_name="user",
old_name="mneomonic",
new_name="mnemonic",
),
]

@ -0,0 +1,18 @@
# Generated by Django 3.2.8 on 2022-05-25 13:46
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('users', '0002_auto_20220525_1344'),
]
operations = [
migrations.RenameField(
model_name='user',
old_name='pubkey',
new_name='public_key',
),
]

@ -1,32 +0,0 @@
# Generated by Django 3.2.8 on 2021-11-25 16:29
from django.db import migrations, models
import django.db.models.deletion
import uuid
class Migration(migrations.Migration):
dependencies = [
('users', '0003_rename_mneomonic_user_mnemonic'),
]
operations = [
migrations.CreateModel(
name='UserSettings',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('language', models.CharField(choices=[('fr-FR', 'Français (beta)'), ('en-US', 'English')], default='en-us', max_length=10)),
('theme', models.CharField(choices=[('DK', 'Dark'), ('LT', 'Light')], default='DK', max_length=2)),
],
),
migrations.RemoveField(
model_name='user',
name='language',
),
migrations.AddField(
model_name='user',
name='settings',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='settings', to='users.usersettings'),
),
]

@ -1,36 +0,0 @@
# Generated by Django 3.2.8 on 2021-11-25 17:11
import chat.utils.functions
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0004_auto_20211125_1629'),
]
operations = [
migrations.AlterModelOptions(
name='usersettings',
options={'verbose_name_plural': 'User Settings'},
),
migrations.RemoveField(
model_name='user',
name='avatar',
),
migrations.RemoveField(
model_name='user',
name='bio',
),
migrations.AddField(
model_name='usersettings',
name='avatar',
field=models.ImageField(blank=True, null=True, upload_to=chat.utils.functions.PathAndRename('users/avatar')),
),
migrations.AddField(
model_name='usersettings',
name='bio',
field=models.TextField(blank=True, max_length=1000, null=True),
),
]

@ -1,19 +0,0 @@
# Generated by Django 3.2.8 on 2021-11-25 17:36
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('users', '0005_auto_20211125_1711'),
]
operations = [
migrations.AlterField(
model_name='user',
name='settings',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='settings', to='users.usersettings'),
),
]

@ -1,24 +0,0 @@
# Generated by Django 3.2.8 on 2021-11-25 18:00
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('users', '0006_alter_user_settings'),
]
operations = [
migrations.AlterField(
model_name='user',
name='settings',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='user_settings', to='users.usersettings'),
),
migrations.AlterField(
model_name='usersettings',
name='language',
field=models.CharField(choices=[('fr', 'Français (beta)'), ('en', 'English')], default='en-us', max_length=10),
),
]

@ -1,24 +0,0 @@
# Generated by Django 3.2.8 on 2021-11-26 12:12
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('guilds', '0004_auto_20211114_1754'),
('users', '0007_auto_20211125_1800'),
]
operations = [
migrations.AddField(
model_name='usersettings',
name='collapsed_categories',
field=models.ManyToManyField(blank=True, default=None, to='guilds.Category'),
),
migrations.AlterField(
model_name='usersettings',
name='language',
field=models.CharField(choices=[('fr-fr', 'Français (beta)'), ('en-us', 'English')], default='en-us', max_length=10),
),
]

@ -1,18 +0,0 @@
# Generated by Django 3.2.8 on 2022-05-16 13:51
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0008_auto_20211126_1212'),
]
operations = [
migrations.AddField(
model_name='user',
name='email',
field=models.EmailField(blank=True, max_length=254, null=True, unique=True),
),
]

@ -1,17 +0,0 @@
# Generated by Django 3.2.8 on 2022-05-21 22:01
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('users', '0009_user_email'),
]
operations = [
migrations.RemoveField(
model_name='user',
name='email',
),
]

@ -81,7 +81,9 @@ class User(AbstractUser):
# email = models.EmailField(unique=True, blank=True, null=True) # None # type: ignore
first_connect = models.BooleanField(default=True)
mnemonic = models.CharField(max_length=255, blank=True, null=True)
public_key = models.CharField(max_length=255, blank=True, null=True)
# =========================================================================

@ -127,6 +127,9 @@ class UserFistConnectView(BaseUsersView, View):
template_name = template_path + "first_connect"
def get(self, request: ASGIRequest, page: str = "first") -> HttpResponse:
if (user_settings := User.objects.get(id=request.user.id)) and not user_settings.first_connect:
return redirect("users:redirect")
if page == "first":
return render(request, self.template_name + "/first.html")
@ -151,6 +154,7 @@ class UserFistConnectView(BaseUsersView, View):
return redirect("users:first_connect")
mnemonic = request.POST.get("mnemonic")
public_key = request.POST.get("public_key")
mnemonics = request.session["mnemonics"]
if mnemonic not in mnemonics.values():
@ -164,11 +168,23 @@ class UserFistConnectView(BaseUsersView, View):
self.template_name + "/next.html",
{"mnemonics": mnemonics},
)
if not public_key:
messages.add_message(
request,
messages.WARNING,
_("Please do not edit autofilled inputs"),
)
return render(
request,
self.template_name + "/next.html",
{"mnemonics": mnemonics},
)
del request.session["mnemonics"]
user = User.objects.get(id=request.user.id)
user.mnemonic = make_password(mnemonic)
user.public_key = public_key
user.first_connect = False
user.save()

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -0,0 +1,81 @@
// Written in 2014-2016 by Dmitry Chestnykh and Devi Mandiri.
// Public domain.
(function(root, f) {
'use strict';
if (typeof module !== 'undefined' && module.exports) module.exports = f();
else if (root.nacl) root.nacl.util = f();
else {
root.nacl = {};
root.nacl.util = f();
}
}(this, function() {
'use strict';
var util = {};
function validateBase64(s) {
if (!(/^(?:[A-Za-z0-9+\/]{2}[A-Za-z0-9+\/]{2})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/.test(s))) {
throw new TypeError('invalid encoding');
}
}
util.decodeUTF8 = function(s) {
if (typeof s !== 'string') throw new TypeError('expected string');
var i, d = unescape(encodeURIComponent(s)), b = new Uint8Array(d.length);
for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i);
return b;
};
util.encodeUTF8 = function(arr) {
var i, s = [];
for (i = 0; i < arr.length; i++) s.push(String.fromCharCode(arr[i]));
return decodeURIComponent(escape(s.join('')));
};
if (typeof atob === 'undefined') {
// Node.js
if (typeof Buffer.from !== 'undefined') {
// Node v6 and later
util.encodeBase64 = function (arr) { // v6 and later
return Buffer.from(arr).toString('base64');
};
util.decodeBase64 = function (s) {
validateBase64(s);
return new Uint8Array(Array.prototype.slice.call(Buffer.from(s, 'base64'), 0));
};
} else {
// Node earlier than v6
util.encodeBase64 = function (arr) { // v6 and later
return (new Buffer(arr)).toString('base64');
};
util.decodeBase64 = function(s) {
validateBase64(s);
return new Uint8Array(Array.prototype.slice.call(new Buffer(s, 'base64'), 0));
};
}
} else {
// Browsers
util.encodeBase64 = function(arr) {
var i, s = [], len = arr.length;
for (i = 0; i < len; i++) s.push(String.fromCharCode(arr[i]));
return btoa(s.join(''));
};
util.decodeBase64 = function(s) {
validateBase64(s);
var i, d = atob(s), b = new Uint8Array(d.length);
for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i);
return b;
};
}
return util;
}));

@ -0,0 +1 @@
!function(e,n){"use strict";"undefined"!=typeof module&&module.exports?module.exports=n():(e.nacl||(e.nacl={}),e.nacl.util=n())}(this,function(){"use strict";var e={};function o(e){if(!/^(?:[A-Za-z0-9+\/]{2}[A-Za-z0-9+\/]{2})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/.test(e))throw new TypeError("invalid encoding")}return e.decodeUTF8=function(e){if("string"!=typeof e)throw new TypeError("expected string");var n,r=unescape(encodeURIComponent(e)),t=new Uint8Array(r.length);for(n=0;n<r.length;n++)t[n]=r.charCodeAt(n);return t},e.encodeUTF8=function(e){var n,r=[];for(n=0;n<e.length;n++)r.push(String.fromCharCode(e[n]));return decodeURIComponent(escape(r.join("")))},"undefined"==typeof atob?void 0!==Buffer.from?(e.encodeBase64=function(e){return Buffer.from(e).toString("base64")},e.decodeBase64=function(e){return o(e),new Uint8Array(Array.prototype.slice.call(Buffer.from(e,"base64"),0))}):(e.encodeBase64=function(e){return new Buffer(e).toString("base64")},e.decodeBase64=function(e){return o(e),new Uint8Array(Array.prototype.slice.call(new Buffer(e,"base64"),0))}):(e.encodeBase64=function(e){var n,r=[],t=e.length;for(n=0;n<t;n++)r.push(String.fromCharCode(e[n]));return btoa(r.join(""))},e.decodeBase64=function(e){o(e);var n,r=atob(e),t=new Uint8Array(r.length);for(n=0;n<r.length;n++)t[n]=r.charCodeAt(n);return t}),e});

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -12,9 +12,9 @@
<div class="uk-margin uk-margin-auto uk-card-body">
<h1 class="uk-card-title uk-text-center">{% translate "Sign Out" %}</h1>
{# <div class="uk-alert uk-alert-primary">#}
{# <p>{% trans "Don't forget to export your key ;)" %}</p>#}
{# </div>#}
<div class="uk-alert uk-alert-primary">
<p>{% trans "Don't forget to export your key ;)" %}</p>
</div>
{% if form.non_field_errors %}
<div class="uk-alert uk-alert-danger">
@ -31,15 +31,15 @@
value="{{ redirect_field_value }}"/>
{% endif %}
{# <div class="uk-margin">#}
{# <label class="uk-inline uk-width-1-1" for="secret_key">#}
{# {% trans "Secret key" %}#}
{# <textarea class="uk-textarea uk-resize-vertical" id="secret_key" cols="30" rows="10"></textarea>#}
{# </label>#}
{# <div class="uk-width-1-1">#}
{# <a id="secret_key_export">{% trans "Download" %}</a>#}
{# </div>#}
{# </div>#}
<div class="uk-margin">
<label class="uk-inline uk-width-1-1" for="private_key">
{% trans "Private key" %}
<textarea class="uk-textarea uk-resize-vertical" id="private_key" cols="30" rows="10"></textarea>
</label>
<div class="uk-width-1-1">
<a id="private_key_export">{% trans "Download" %}</a>
</div>
</div>
<div class="uk-margin">
<button class="uk-button uk-button-primary uk-button-large uk-width-1-1">
@ -56,12 +56,16 @@
{% block inline_javascript %}
<script>
const textarea = document.getElementById("secret_key");
const anchor = document.getElementById("secret_key_export");
const secret_key = atob(sessionStorage.getItem("secret_key"));
if (window.keyPair === undefined) {
window.keyPair = window.sessionStorage.getItem("keySet").split("|");
}
const textarea = document.getElementById("private_key");
const anchor = document.getElementById("private_key_export");
const secret_key = keyPair[1];