Compare commits

...

9 Commits

Author SHA1 Message Date
shamoon
42043b1a67 Fix 2025-03-29 09:52:53 -07:00
shamoon
ad5e33df03 More docs 2025-03-29 09:52:53 -07:00
shamoon
d150349f28 Update administration.md 2025-03-29 09:52:53 -07:00
shamoon
2ee5fd7e75 Use global_objects 2025-03-29 09:52:53 -07:00
shamoon
f656823ceb Update test_adapter.py 2025-03-29 09:52:53 -07:00
shamoon
186ceaba90 Refactor a bit, include doc count 2025-03-29 09:52:53 -07:00
shamoon
5a834a5eca Enhancement: allow signup on first setup 2025-03-29 09:52:53 -07:00
shamoon
b4b2a92225
Fix: fix unshared items display 2025-03-28 05:47:10 -07:00
shamoon
fd45e81a83
Fix: fix cf dropdown placement on mobile (#9508) 2025-03-27 14:09:51 -07:00
21 changed files with 215 additions and 162 deletions

View File

@ -25,8 +25,6 @@
# and '.env' into a folder. # and '.env' into a folder.
# - Run 'docker compose pull'. # - Run 'docker compose pull'.
# - Run 'docker compose up -d'. # - Run 'docker compose up -d'.
# - Wait until the webserver has completed startup
# - Run 'docker compose exec webserver createsuperuser' to create a user.
# #
# For more extensive installation and update instructions, refer to the # For more extensive installation and update instructions, refer to the

View File

@ -21,8 +21,6 @@
# and '.env' into a folder. # and '.env' into a folder.
# - Run 'docker compose pull'. # - Run 'docker compose pull'.
# - Run 'docker compose up -d'. # - Run 'docker compose up -d'.
# - Wait until the webserver has completed startup
# - Run 'docker compose exec webserver createsuperuser' to create a user.
# #
# For more extensive installation and update instructions, refer to the # For more extensive installation and update instructions, refer to the
# documentation. # documentation.

View File

@ -22,10 +22,6 @@
# - Upload 'docker-compose.env' by clicking on 'Load variables from .env file' # - Upload 'docker-compose.env' by clicking on 'Load variables from .env file'
# - Modify the environment variables as needed # - Modify the environment variables as needed
# - Click 'Deploy the stack' and wait for it to be deployed # - Click 'Deploy the stack' and wait for it to be deployed
# - Open the list of containers, select paperless_webserver_1
# - Click 'Console' and then 'Connect' to open the command line inside the container
# - Run 'createsuperuser' to create a user
# - Exit the console
# #
# For more extensive installation and update instructions, refer to the # For more extensive installation and update instructions, refer to the
# documentation. # documentation.

View File

@ -25,8 +25,6 @@
# and '.env' into a folder. # and '.env' into a folder.
# - Run 'docker compose pull'. # - Run 'docker compose pull'.
# - Run 'docker compose up -d'. # - Run 'docker compose up -d'.
# - Wait until the webserver has completed startup
# - Run 'docker compose exec webserver createsuperuser' to create a user.
# #
# For more extensive installation and update instructions, refer to the # For more extensive installation and update instructions, refer to the
# documentation. # documentation.

View File

@ -21,8 +21,6 @@
# and '.env' into a folder. # and '.env' into a folder.
# - Run 'docker compose pull'. # - Run 'docker compose pull'.
# - Run 'docker compose up -d'. # - Run 'docker compose up -d'.
# - Wait until the webserver has completed startup
# - Run 'docker compose exec webserver createsuperuser' to create a user.
# #
# For more extensive installation and update instructions, refer to the # For more extensive installation and update instructions, refer to the
# documentation. # documentation.

View File

@ -25,8 +25,6 @@
# and '.env' into a folder. # and '.env' into a folder.
# - Run 'docker compose pull'. # - Run 'docker compose pull'.
# - Run 'docker compose up -d'. # - Run 'docker compose up -d'.
# - Wait until the webserver has completed startup
# - Run 'docker compose exec webserver createsuperuser' to create a user.
# #
# For more extensive installation and update instructions, refer to the # For more extensive installation and update instructions, refer to the
# documentation. # documentation.

View File

@ -18,8 +18,6 @@
# and '.env' into a folder. # and '.env' into a folder.
# - Run 'docker compose pull'. # - Run 'docker compose pull'.
# - Run 'docker compose up -d'. # - Run 'docker compose up -d'.
# - Wait until the webserver has completed startup
# - Run 'docker compose exec webserver createsuperuser' to create a user.
# #
# For more extensive installation and update instructions, refer to the # For more extensive installation and update instructions, refer to the
# documentation. # documentation.

View File

@ -629,3 +629,11 @@ entries created prior to this are not removed. This command allows you to prune
```shell ```shell
prune_audit_logs prune_audit_logs
``` ```
### Create superuser {#create-superuser}
If you need to create a superuser, use the following command:
```shell
createsuperuser
```

View File

@ -84,7 +84,7 @@ first-time setup.
$ uv run pre-commit install $ uv run pre-commit install
``` ```
6. Apply migrations and create a superuser for your development instance: 6. Apply migrations and create a superuser (also can be done via the web UI) for your development instance:
```bash ```bash
# src/ # src/

View File

@ -133,30 +133,9 @@ account. The script essentially automatically performs the steps described in [D
6. Run `docker compose up -d`. This will create and start the necessary containers. 6. Run `docker compose up -d`. This will create and start the necessary containers.
7. Wait for the containers to complete their startup. You can monitor the logs using Docker, such as: 7. Congratulations! Your Paperless-ngx instance should now be accessible at `http://127.0.0.1:8000`
(or similar, depending on your configuration). When you first access the web interface, you will be
```shell-session prompted to create a superuser account.
docker logs --follow webserver
```
8. To be able to login, you will need a "superuser". To create it,
execute the following command:
```shell-session
docker compose exec webserver createsuperuser
```
or using docker exec from within the container:
```shell-session
createsuperuser
```
This will guide you through the superuser setup.
9. Congratulations! Your Paperless-ngx instance should now be accessible at `http://127.0.0.1:8000`
(or similar, depending on your configuration). Use the superuser credentials you have
created in the previous step to login.
### Build the Docker image yourself {#docker_build} ### Build the Docker image yourself {#docker_build}
@ -392,16 +371,15 @@ are released, dependency support is confirmed, etc.
dependencies for Postgres or Mariadb. You can select those extras with `--extra <EXTRA>` dependencies for Postgres or Mariadb. You can select those extras with `--extra <EXTRA>`
or all with `--all-extras` or all with `--all-extras`
9. Go to `/opt/paperless/src`, and execute the following commands: 9. Go to `/opt/paperless/src`, and execute the following command:
```bash ```bash
# This creates the database schema. # This creates the database schema.
sudo -Hu paperless python3 manage.py migrate sudo -Hu paperless python3 manage.py migrate
# This creates your first paperless user
sudo -Hu paperless python3 manage.py createsuperuser
``` ```
When you first access the web interface you will be prompted to create a superuser account.
10. Optional: Test that paperless is working by executing 10. Optional: Test that paperless is working by executing
```bash ```bash

View File

@ -2537,19 +2537,19 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">968</context> <context context-type="linenumber">965</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1328</context> <context context-type="linenumber">1325</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1367</context> <context context-type="linenumber">1364</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1408</context> <context context-type="linenumber">1405</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
@ -3157,7 +3157,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">921</context> <context context-type="linenumber">918</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
@ -3325,7 +3325,7 @@
<source>Saved field &quot;<x id="PH" equiv-text="newField.name"/>&quot;.</source> <source>Saved field &quot;<x id="PH" equiv-text="newField.name"/>&quot;.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/custom-fields-dropdown/custom-fields-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/custom-fields-dropdown/custom-fields-dropdown.component.ts</context>
<context context-type="linenumber">126</context> <context context-type="linenumber">129</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.ts</context> <context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.ts</context>
@ -3336,7 +3336,7 @@
<source>Error saving field.</source> <source>Error saving field.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/custom-fields-dropdown/custom-fields-dropdown.component.ts</context> <context context-type="sourcefile">src/app/components/common/custom-fields-dropdown/custom-fields-dropdown.component.ts</context>
<context context-type="linenumber">135</context> <context context-type="linenumber">138</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.ts</context> <context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.ts</context>
@ -3406,7 +3406,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1385</context> <context context-type="linenumber">1382</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/guards/dirty-saved-view.guard.ts</context> <context context-type="sourcefile">src/app/guards/dirty-saved-view.guard.ts</context>
@ -5461,7 +5461,11 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/pipes/object-name.pipe.ts</context> <context context-type="sourcefile">src/app/pipes/object-name.pipe.ts</context>
<context context-type="linenumber">43</context> <context context-type="linenumber">40</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/pipes/object-name.pipe.ts</context>
<context context-type="linenumber">46</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="2504502765849142619" datatype="html"> <trans-unit id="2504502765849142619" datatype="html">
@ -6908,35 +6912,35 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">839</context> <context context-type="linenumber">836</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6626387786259219838" datatype="html"> <trans-unit id="6626387786259219838" datatype="html">
<source>Error saving document &quot;<x id="PH" equiv-text="this.document.title"/>&quot;</source> <source>Error saving document &quot;<x id="PH" equiv-text="this.document.title"/>&quot;</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">845</context> <context context-type="linenumber">842</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="448882439049417053" datatype="html"> <trans-unit id="448882439049417053" datatype="html">
<source>Error saving document</source> <source>Error saving document</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">890</context> <context context-type="linenumber">887</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="8410796510716511826" datatype="html"> <trans-unit id="8410796510716511826" datatype="html">
<source>Do you really want to move the document &quot;<x id="PH" equiv-text="this.document.title"/>&quot; to the trash?</source> <source>Do you really want to move the document &quot;<x id="PH" equiv-text="this.document.title"/>&quot; to the trash?</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">922</context> <context context-type="linenumber">919</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="282586936710748252" datatype="html"> <trans-unit id="282586936710748252" datatype="html">
<source>Documents can be restored prior to permanent deletion.</source> <source>Documents can be restored prior to permanent deletion.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">923</context> <context context-type="linenumber">920</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
@ -6947,7 +6951,7 @@
<source>Move to trash</source> <source>Move to trash</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">925</context> <context context-type="linenumber">922</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
@ -6958,14 +6962,14 @@
<source>Error deleting document</source> <source>Error deleting document</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">944</context> <context context-type="linenumber">941</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="619486176823357521" datatype="html"> <trans-unit id="619486176823357521" datatype="html">
<source>Reprocess confirm</source> <source>Reprocess confirm</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">964</context> <context context-type="linenumber">961</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
@ -6976,77 +6980,77 @@
<source>This operation will permanently recreate the archive file for this document.</source> <source>This operation will permanently recreate the archive file for this document.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">965</context> <context context-type="linenumber">962</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="302054111564709516" datatype="html"> <trans-unit id="302054111564709516" datatype="html">
<source>The archive file will be re-generated with the current settings.</source> <source>The archive file will be re-generated with the current settings.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">966</context> <context context-type="linenumber">963</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="8251197608401006898" datatype="html"> <trans-unit id="8251197608401006898" datatype="html">
<source>Reprocess operation for &quot;<x id="PH" equiv-text="this.document.title"/>&quot; will begin in the background. Close and re-open or reload this document after the operation has completed to see new content.</source> <source>Reprocess operation for &quot;<x id="PH" equiv-text="this.document.title"/>&quot; will begin in the background. Close and re-open or reload this document after the operation has completed to see new content.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">976</context> <context context-type="linenumber">973</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="4409560272830824468" datatype="html"> <trans-unit id="4409560272830824468" datatype="html">
<source>Error executing operation</source> <source>Error executing operation</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">987</context> <context context-type="linenumber">984</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6030453331794586802" datatype="html"> <trans-unit id="6030453331794586802" datatype="html">
<source>Error downloading document</source> <source>Error downloading document</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1034</context> <context context-type="linenumber">1031</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="4458954481601077369" datatype="html"> <trans-unit id="4458954481601077369" datatype="html">
<source>Page Fit</source> <source>Page Fit</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1113</context> <context context-type="linenumber">1110</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1217563727923422413" datatype="html"> <trans-unit id="1217563727923422413" datatype="html">
<source>Split confirm</source> <source>Split confirm</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1326</context> <context context-type="linenumber">1323</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="2805304563009985503" datatype="html"> <trans-unit id="2805304563009985503" datatype="html">
<source>This operation will split the selected document(s) into new documents.</source> <source>This operation will split the selected document(s) into new documents.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1327</context> <context context-type="linenumber">1324</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7638681545012641321" datatype="html"> <trans-unit id="7638681545012641321" datatype="html">
<source>Split operation for &quot;<x id="PH" equiv-text="this.document.title"/>&quot; will begin in the background.</source> <source>Split operation for &quot;<x id="PH" equiv-text="this.document.title"/>&quot; will begin in the background.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1343</context> <context context-type="linenumber">1340</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="3235014591864339926" datatype="html"> <trans-unit id="3235014591864339926" datatype="html">
<source>Error executing split operation</source> <source>Error executing split operation</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1352</context> <context context-type="linenumber">1349</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6555329262222566158" datatype="html"> <trans-unit id="6555329262222566158" datatype="html">
<source>Rotate confirm</source> <source>Rotate confirm</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1365</context> <context context-type="linenumber">1362</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context> <context context-type="sourcefile">src/app/components/document-list/bulk-editor/bulk-editor.component.ts</context>
@ -7057,60 +7061,60 @@
<source>This operation will permanently rotate the original version of the current document.</source> <source>This operation will permanently rotate the original version of the current document.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1366</context> <context context-type="linenumber">1363</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="3802852336439815451" datatype="html"> <trans-unit id="3802852336439815451" datatype="html">
<source>Rotation of &quot;<x id="PH" equiv-text="this.document.title"/>&quot; will begin in the background. Close and re-open the document after the operation has completed to see the changes.</source> <source>Rotation of &quot;<x id="PH" equiv-text="this.document.title"/>&quot; will begin in the background. Close and re-open the document after the operation has completed to see the changes.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1382</context> <context context-type="linenumber">1379</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="2962674215361798818" datatype="html"> <trans-unit id="2962674215361798818" datatype="html">
<source>Error executing rotate operation</source> <source>Error executing rotate operation</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1394</context> <context context-type="linenumber">1391</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="3539261415918606512" datatype="html"> <trans-unit id="3539261415918606512" datatype="html">
<source>Delete pages confirm</source> <source>Delete pages confirm</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1406</context> <context context-type="linenumber">1403</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="5854352498125813866" datatype="html"> <trans-unit id="5854352498125813866" datatype="html">
<source>This operation will permanently delete the selected pages from the original document.</source> <source>This operation will permanently delete the selected pages from the original document.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1407</context> <context context-type="linenumber">1404</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1138505464360427037" datatype="html"> <trans-unit id="1138505464360427037" datatype="html">
<source>Delete pages operation for &quot;<x id="PH" equiv-text="this.document.title"/>&quot; will begin in the background. Close and re-open or reload this document after the operation has completed to see the changes.</source> <source>Delete pages operation for &quot;<x id="PH" equiv-text="this.document.title"/>&quot; will begin in the background. Close and re-open or reload this document after the operation has completed to see the changes.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1422</context> <context context-type="linenumber">1419</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1249139200486584973" datatype="html"> <trans-unit id="1249139200486584973" datatype="html">
<source>Error executing delete pages operation</source> <source>Error executing delete pages operation</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1431</context> <context context-type="linenumber">1428</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6085793215710522488" datatype="html"> <trans-unit id="6085793215710522488" datatype="html">
<source>An error occurred loading tiff: <x id="PH" equiv-text="err.toString()"/></source> <source>An error occurred loading tiff: <x id="PH" equiv-text="err.toString()"/></source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1491</context> <context context-type="linenumber">1488</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context> <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
<context context-type="linenumber">1495</context> <context context-type="linenumber">1492</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="4958946940233632319" datatype="html"> <trans-unit id="4958946940233632319" datatype="html">
@ -9815,7 +9819,7 @@
<source>You can restart the tour from the settings page.</source> <source>You can restart the tour from the settings page.</source>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/services/settings.service.ts</context> <context context-type="sourcefile">src/app/services/settings.service.ts</context>
<context context-type="linenumber">667</context> <context context-type="linenumber">664</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="3852289441366561594" datatype="html"> <trans-unit id="3852289441366561594" datatype="html">

View File

@ -1,4 +1,4 @@
<div ngbDropdown #fieldDropdown="ngbDropdown" (openChange)="onOpenClose($event)"> <div ngbDropdown #fieldDropdown="ngbDropdown" (openChange)="onOpenClose($event)" [popperOptions]="popperOptions" placement="bottom-end">
<button class="btn btn-sm btn-outline-primary" id="customFieldsDropdown" [disabled]="disabled" ngbDropdownToggle> <button class="btn btn-sm btn-outline-primary" id="customFieldsDropdown" [disabled]="disabled" ngbDropdownToggle>
<i-bs name="ui-radios"></i-bs> <i-bs name="ui-radios"></i-bs>
<div class="d-none d-sm-inline">&nbsp;<ng-container i18n>Custom Fields</ng-container></div> <div class="d-none d-sm-inline">&nbsp;<ng-container i18n>Custom Fields</ng-container></div>

View File

@ -21,6 +21,7 @@ import {
} from 'src/app/services/permissions.service' } from 'src/app/services/permissions.service'
import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service' import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
import { ToastService } from 'src/app/services/toast.service' import { ToastService } from 'src/app/services/toast.service'
import { pngxPopperOptions } from 'src/app/utils/popper-options'
import { LoadingComponentWithPermissions } from '../../loading-component/loading.component' import { LoadingComponentWithPermissions } from '../../loading-component/loading.component'
import { CustomFieldEditDialogComponent } from '../edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component' import { CustomFieldEditDialogComponent } from '../edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component'
@ -36,6 +37,8 @@ import { CustomFieldEditDialogComponent } from '../edit-dialog/custom-field-edit
], ],
}) })
export class CustomFieldsDropdownComponent extends LoadingComponentWithPermissions { export class CustomFieldsDropdownComponent extends LoadingComponentWithPermissions {
public popperOptions = pngxPopperOptions
@Input() @Input()
documentId: number documentId: number

View File

@ -50,7 +50,7 @@ describe('ObjectNamePipe', () => {
}) })
}) })
it('should return empty string if object not found', (done) => { it('should return Private string if object not found', (done) => {
const mockObjects = { const mockObjects = {
results: [{ id: 2, name: 'Object 2' }], results: [{ id: 2, name: 'Object 2' }],
count: 1, count: 1,
@ -60,7 +60,7 @@ describe('ObjectNamePipe', () => {
jest.spyOn(objectService, 'listAll').mockReturnValue(of(mockObjects)) jest.spyOn(objectService, 'listAll').mockReturnValue(of(mockObjects))
pipe.transform(1).subscribe((result) => { pipe.transform(1).subscribe((result) => {
expect(result).toBe('') expect(result).toBe('Private')
done() done()
}) })
}) })

View File

@ -35,7 +35,10 @@ export abstract class ObjectNamePipe implements PipeTransform {
return this.objectService.listAll().pipe( return this.objectService.listAll().pipe(
map((objects) => { map((objects) => {
this.objects = objects.results this.objects = objects.results
return this.objects.find((o) => o.id === obejctId)?.name || '' return (
this.objects.find((o) => o.id === obejctId)?.name ||
$localize`Private`
)
}), }),
catchError(() => of('')) catchError(() => of(''))
) )

View File

@ -1,5 +1,7 @@
from django.conf import settings as django_settings from django.conf import settings as django_settings
from django.contrib.auth.models import User
from documents.models import Document
from paperless.config import GeneralConfig from paperless.config import GeneralConfig
@ -25,4 +27,9 @@ def settings(request):
"domain": getattr(django_settings, "PAPERLESS_URL", request.get_host()), "domain": getattr(django_settings, "PAPERLESS_URL", request.get_host()),
"APP_TITLE": app_title, "APP_TITLE": app_title,
"APP_LOGO": app_logo, "APP_LOGO": app_logo,
"FIRST_INSTALL": User.objects.exclude(
username__in=["consumer", "AnonymousUser"],
).count()
== 0
and Document.global_objects.count() == 0,
} }

View File

@ -15,6 +15,12 @@
{% endblock form_top_content %} {% endblock form_top_content %}
{% block form_content %} {% block form_content %}
{% if FIRST_INSTALL %}
<script type="text/javascript">
// forward to the signup page if no users exist
window.location.href = "{{ signup_url }}";
</script>
{% endif %}
{% if not DISABLE_REGULAR_LOGIN %} {% if not DISABLE_REGULAR_LOGIN %}
{% translate "Username" as i18n_username %} {% translate "Username" as i18n_username %}
{% translate "Password" as i18n_password %} {% translate "Password" as i18n_password %}

View File

@ -6,12 +6,19 @@
{% endblock head_title %} {% endblock head_title %}
{% block form_top_content %} {% block form_top_content %}
<p> {% if not FIRST_INSTALL %}
{% blocktrans %}Already have an account? <a href="{{ login_url }}">Sign in</a>{% endblocktrans %} <p>
</p> {% blocktrans %}Already have an account? <a href="{{ login_url }}">Sign in</a>{% endblocktrans %}
</p>
{% endif %}
{% endblock form_top_content %} {% endblock form_top_content %}
{% block form_content %} {% block form_content %}
{% if FIRST_INSTALL %}
<p>
{% blocktrans %}Note: This is the first user account for this installation and will be granted superuser privileges.{% endblocktrans %}
</p>
{% endif %}
{% translate "Username" as i18n_username %} {% translate "Username" as i18n_username %}
{% translate "Email (optional)" as i18n_email %} {% translate "Email (optional)" as i18n_email %}
{% translate "Password" as i18n_password1 %} {% translate "Password" as i18n_password1 %}
@ -42,29 +49,31 @@
{% endblock form_content %} {% endblock form_content %}
{% block after_form_content %} {% block after_form_content %}
{% load allauth socialaccount %} {% if not FIRST_INSTALL %}
{% get_providers as socialaccount_providers %} {% load allauth socialaccount %}
{% if socialaccount_providers %} {% get_providers as socialaccount_providers %}
{% if not DISABLE_REGULAR_LOGIN %} {% if socialaccount_providers %}
<p class="mt-3">{% translate "or sign in via" %}</p> {% if not DISABLE_REGULAR_LOGIN %}
{% endif %} <p class="mt-3">{% translate "or sign in via" %}</p>
<ul class="m-0 p-0"> {% endif %}
{% for provider in socialaccount_providers %} <ul class="m-0 p-0">
{% if provider.id == "openid" %} {% for provider in socialaccount_providers %}
{% for brand in provider.get_brands %} {% if provider.id == "openid" %}
{% provider_login_url provider openid=brand.openid_url process=process as href %} {% for brand in provider.get_brands %}
<li class="d-grid mt-3"><a class="btn btn-secondary" href="{{ href }}">{{ brand.name }}</a></li> {% provider_login_url provider openid=brand.openid_url process=process as href %}
{% endfor %} <li class="d-grid mt-3"><a class="btn btn-secondary" href="{{ href }}">{{ brand.name }}</a></li>
{% else %} {% endfor %}
{% provider_login_url provider process=process scope=scope auth_params=auth_params as href %} {% else %}
<li class="d-grid mt-3"> {% provider_login_url provider process=process scope=scope auth_params=auth_params as href %}
<form class="d-grid" method="POST" action="{{ href }}"> <li class="d-grid mt-3">
{% csrf_token %} <form class="d-grid" method="POST" action="{{ href }}">
<button type="submit" class="btn btn-secondary">{{ provider.name }}</button> {% csrf_token %}
</form> <button type="submit" class="btn btn-secondary">{{ provider.name }}</button>
</li> </form>
{% endif %} </li>
{% endfor %} {% endif %}
</ul> {% endfor %}
{% endif %} </ul>
{% endif %}
{% endif %}
{% endblock after_form_content %} {% endblock after_form_content %}

View File

@ -2,7 +2,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: paperless-ngx\n" "Project-Id-Version: paperless-ngx\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-03-11 13:33-0700\n" "POT-Creation-Date: 2025-03-26 21:04-0700\n"
"PO-Revision-Date: 2022-02-17 04:17\n" "PO-Revision-Date: 2022-02-17 04:17\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: English\n" "Language-Team: English\n"
@ -1235,28 +1235,28 @@ msgstr ""
msgid "Don't have an account yet? <a href=\"%(signup_url)s\">Sign up</a>" msgid "Don't have an account yet? <a href=\"%(signup_url)s\">Sign up</a>"
msgstr "" msgstr ""
#: documents/templates/account/login.html:19 #: documents/templates/account/login.html:25
#: documents/templates/account/signup.html:15 #: documents/templates/account/signup.html:22
#: documents/templates/socialaccount/signup.html:13 #: documents/templates/socialaccount/signup.html:13
msgid "Username" msgid "Username"
msgstr "" msgstr ""
#: documents/templates/account/login.html:20 #: documents/templates/account/login.html:26
#: documents/templates/account/signup.html:17 #: documents/templates/account/signup.html:24
msgid "Password" msgid "Password"
msgstr "" msgstr ""
#: documents/templates/account/login.html:30 #: documents/templates/account/login.html:36
#: documents/templates/mfa/authenticate.html:23 #: documents/templates/mfa/authenticate.html:23
msgid "Sign in" msgid "Sign in"
msgstr "" msgstr ""
#: documents/templates/account/login.html:34 #: documents/templates/account/login.html:40
msgid "Forgot your password?" msgid "Forgot your password?"
msgstr "" msgstr ""
#: documents/templates/account/login.html:45 #: documents/templates/account/login.html:51
#: documents/templates/account/signup.html:49 #: documents/templates/account/signup.html:57
msgid "or sign in via" msgid "or sign in via"
msgstr "" msgstr ""
@ -1335,21 +1335,27 @@ msgstr ""
msgid "Paperless-ngx sign up" msgid "Paperless-ngx sign up"
msgstr "" msgstr ""
#: documents/templates/account/signup.html:10 #: documents/templates/account/signup.html:11
#, python-format #, python-format
msgid "Already have an account? <a href=\"%(login_url)s\">Sign in</a>" msgid "Already have an account? <a href=\"%(login_url)s\">Sign in</a>"
msgstr "" msgstr ""
#: documents/templates/account/signup.html:16 #: documents/templates/account/signup.html:19
msgid ""
"Note: This is the first user account for this installation and will be "
"granted superuser privileges."
msgstr ""
#: documents/templates/account/signup.html:23
#: documents/templates/socialaccount/signup.html:14 #: documents/templates/socialaccount/signup.html:14
msgid "Email (optional)" msgid "Email (optional)"
msgstr "" msgstr ""
#: documents/templates/account/signup.html:18 #: documents/templates/account/signup.html:25
msgid "Password (again)" msgid "Password (again)"
msgstr "" msgstr ""
#: documents/templates/account/signup.html:36 #: documents/templates/account/signup.html:43
#: documents/templates/socialaccount/signup.html:27 #: documents/templates/socialaccount/signup.html:27
msgid "Sign up" msgid "Sign up"
msgstr "" msgstr ""
@ -1578,139 +1584,139 @@ msgstr ""
msgid "paperless application settings" msgid "paperless application settings"
msgstr "" msgstr ""
#: paperless/settings.py:723 #: paperless/settings.py:722
msgid "English (US)" msgid "English (US)"
msgstr "" msgstr ""
#: paperless/settings.py:724 #: paperless/settings.py:723
msgid "Arabic" msgid "Arabic"
msgstr "" msgstr ""
#: paperless/settings.py:725 #: paperless/settings.py:724
msgid "Afrikaans" msgid "Afrikaans"
msgstr "" msgstr ""
#: paperless/settings.py:726 #: paperless/settings.py:725
msgid "Belarusian" msgid "Belarusian"
msgstr "" msgstr ""
#: paperless/settings.py:727 #: paperless/settings.py:726
msgid "Bulgarian" msgid "Bulgarian"
msgstr "" msgstr ""
#: paperless/settings.py:728 #: paperless/settings.py:727
msgid "Catalan" msgid "Catalan"
msgstr "" msgstr ""
#: paperless/settings.py:729 #: paperless/settings.py:728
msgid "Czech" msgid "Czech"
msgstr "" msgstr ""
#: paperless/settings.py:730 #: paperless/settings.py:729
msgid "Danish" msgid "Danish"
msgstr "" msgstr ""
#: paperless/settings.py:731 #: paperless/settings.py:730
msgid "German" msgid "German"
msgstr "" msgstr ""
#: paperless/settings.py:732 #: paperless/settings.py:731
msgid "Greek" msgid "Greek"
msgstr "" msgstr ""
#: paperless/settings.py:733 #: paperless/settings.py:732
msgid "English (GB)" msgid "English (GB)"
msgstr "" msgstr ""
#: paperless/settings.py:734 #: paperless/settings.py:733
msgid "Spanish" msgid "Spanish"
msgstr "" msgstr ""
#: paperless/settings.py:735 #: paperless/settings.py:734
msgid "Finnish" msgid "Finnish"
msgstr "" msgstr ""
#: paperless/settings.py:736 #: paperless/settings.py:735
msgid "French" msgid "French"
msgstr "" msgstr ""
#: paperless/settings.py:737 #: paperless/settings.py:736
msgid "Hungarian" msgid "Hungarian"
msgstr "" msgstr ""
#: paperless/settings.py:738 #: paperless/settings.py:737
msgid "Italian" msgid "Italian"
msgstr "" msgstr ""
#: paperless/settings.py:739 #: paperless/settings.py:738
msgid "Japanese" msgid "Japanese"
msgstr "" msgstr ""
#: paperless/settings.py:740 #: paperless/settings.py:739
msgid "Korean" msgid "Korean"
msgstr "" msgstr ""
#: paperless/settings.py:741 #: paperless/settings.py:740
msgid "Luxembourgish" msgid "Luxembourgish"
msgstr "" msgstr ""
#: paperless/settings.py:742 #: paperless/settings.py:741
msgid "Norwegian" msgid "Norwegian"
msgstr "" msgstr ""
#: paperless/settings.py:743 #: paperless/settings.py:742
msgid "Dutch" msgid "Dutch"
msgstr "" msgstr ""
#: paperless/settings.py:744 #: paperless/settings.py:743
msgid "Polish" msgid "Polish"
msgstr "" msgstr ""
#: paperless/settings.py:745 #: paperless/settings.py:744
msgid "Portuguese (Brazil)" msgid "Portuguese (Brazil)"
msgstr "" msgstr ""
#: paperless/settings.py:746 #: paperless/settings.py:745
msgid "Portuguese" msgid "Portuguese"
msgstr "" msgstr ""
#: paperless/settings.py:747 #: paperless/settings.py:746
msgid "Romanian" msgid "Romanian"
msgstr "" msgstr ""
#: paperless/settings.py:748 #: paperless/settings.py:747
msgid "Russian" msgid "Russian"
msgstr "" msgstr ""
#: paperless/settings.py:749 #: paperless/settings.py:748
msgid "Slovak" msgid "Slovak"
msgstr "" msgstr ""
#: paperless/settings.py:750 #: paperless/settings.py:749
msgid "Slovenian" msgid "Slovenian"
msgstr "" msgstr ""
#: paperless/settings.py:751 #: paperless/settings.py:750
msgid "Serbian" msgid "Serbian"
msgstr "" msgstr ""
#: paperless/settings.py:752 #: paperless/settings.py:751
msgid "Swedish" msgid "Swedish"
msgstr "" msgstr ""
#: paperless/settings.py:753 #: paperless/settings.py:752
msgid "Turkish" msgid "Turkish"
msgstr "" msgstr ""
#: paperless/settings.py:754 #: paperless/settings.py:753
msgid "Ukrainian" msgid "Ukrainian"
msgstr "" msgstr ""
#: paperless/settings.py:755 #: paperless/settings.py:754
msgid "Chinese Simplified" msgid "Chinese Simplified"
msgstr "" msgstr ""
#: paperless/settings.py:756 #: paperless/settings.py:755
msgid "Chinese Traditional" msgid "Chinese Traditional"
msgstr "" msgstr ""

View File

@ -10,6 +10,7 @@ from django.contrib.auth.models import User
from django.forms import ValidationError from django.forms import ValidationError
from django.urls import reverse from django.urls import reverse
from documents.models import Document
from paperless.signals import handle_social_account_updated from paperless.signals import handle_social_account_updated
logger = logging.getLogger("paperless.auth") logger = logging.getLogger("paperless.auth")
@ -21,6 +22,13 @@ class CustomAccountAdapter(DefaultAccountAdapter):
Check whether the site is open for signups, which can be Check whether the site is open for signups, which can be
disabled via the ACCOUNT_ALLOW_SIGNUPS setting. disabled via the ACCOUNT_ALLOW_SIGNUPS setting.
""" """
if (
User.objects.exclude(username__in=["consumer", "AnonymousUser"]).count()
== 0
and Document.global_objects.count() == 0
):
# I.e. a fresh install, allow signups
return True
allow_signups = super().is_open_for_signup(request) allow_signups = super().is_open_for_signup(request)
# Override with setting, otherwise default to super. # Override with setting, otherwise default to super.
return getattr(settings, "ACCOUNT_ALLOW_SIGNUPS", allow_signups) return getattr(settings, "ACCOUNT_ALLOW_SIGNUPS", allow_signups)
@ -73,6 +81,17 @@ class CustomAccountAdapter(DefaultAccountAdapter):
Save the user instance. Default groups are assigned to the user, if Save the user instance. Default groups are assigned to the user, if
specified in the settings. specified in the settings.
""" """
if (
User.objects.exclude(username__in=["consumer", "AnonymousUser"]).count()
== 0
and Document.global_objects.count() == 0
):
# I.e. a fresh install, make the user a superuser
logger.debug(f"Creating initial superuser `{user}`")
user.is_superuser = True
user.is_staff = True
user: User = super().save_user(request, user, form, commit) user: User = super().save_user(request, user, form, commit)
group_names: list[str] = settings.ACCOUNT_DEFAULT_GROUPS group_names: list[str] = settings.ACCOUNT_DEFAULT_GROUPS
if len(group_names) > 0: if len(group_names) > 0:

View File

@ -17,6 +17,11 @@ class TestCustomAccountAdapter(TestCase):
def test_is_open_for_signup(self): def test_is_open_for_signup(self):
adapter = get_adapter() adapter = get_adapter()
# With no accounts, signups should be allowed
self.assertTrue(adapter.is_open_for_signup(None))
User.objects.create_user("testuser")
# Test when ACCOUNT_ALLOW_SIGNUPS is True # Test when ACCOUNT_ALLOW_SIGNUPS is True
settings.ACCOUNT_ALLOW_SIGNUPS = True settings.ACCOUNT_ALLOW_SIGNUPS = True
self.assertTrue(adapter.is_open_for_signup(None)) self.assertTrue(adapter.is_open_for_signup(None))
@ -101,6 +106,27 @@ class TestCustomAccountAdapter(TestCase):
self.assertTrue(user.groups.filter(name="group1").exists()) self.assertTrue(user.groups.filter(name="group1").exists())
self.assertFalse(user.groups.filter(name="group2").exists()) self.assertFalse(user.groups.filter(name="group2").exists())
def test_fresh_install_save_creates_superuser(self):
adapter = get_adapter()
form = mock.Mock(
cleaned_data={
"username": "testuser",
"email": "user@paperless-ngx.com",
},
)
user = adapter.save_user(HttpRequest(), User(), form, commit=True)
self.assertTrue(user.is_superuser)
# Next time, it should not create a superuser
form = mock.Mock(
cleaned_data={
"username": "testuser2",
"email": "user2@paperless-ngx.com",
},
)
user2 = adapter.save_user(HttpRequest(), User(), form, commit=True)
self.assertFalse(user2.is_superuser)
class TestCustomSocialAccountAdapter(TestCase): class TestCustomSocialAccountAdapter(TestCase):
def test_is_open_for_signup(self): def test_is_open_for_signup(self):