Merge branch 'dev' into feature-config-from-frontend

This commit is contained in:
shamoon 2023-12-27 21:38:30 -08:00
commit 8ea6bb770b
9 changed files with 41 additions and 18 deletions

View File

@ -8,20 +8,22 @@ most of the available filters and ordering fields.
The API provides the following main endpoints:
- `/api/consumption_templates/`: Full CRUD support.
- `/api/correspondents/`: Full CRUD support.
- `/api/custom_fields/`: Full CRUD support.
- `/api/documents/`: Full CRUD support, except POSTing new documents.
See below.
- `/api/correspondents/`: Full CRUD support.
- `/api/document_types/`: Full CRUD support.
- `/api/groups/`: Full CRUD support.
- `/api/logs/`: Read-Only.
- `/api/tags/`: Full CRUD support.
- `/api/tasks/`: Read-only.
- `/api/mail_accounts/`: Full CRUD support.
- `/api/mail_rules/`: Full CRUD support.
- `/api/users/`: Full CRUD support.
- `/api/groups/`: Full CRUD support.
- `/api/share_links/`: Full CRUD support.
- `/api/custom_fields/`: Full CRUD support.
- `/api/profile/`: GET, PATCH
- `/api/share_links/`: Full CRUD support.
- `/api/storage_paths/`: Full CRUD support.
- `/api/tags/`: Full CRUD support.
- `/api/tasks/`: Read-only.
- `/api/users/`: Full CRUD support.
All of these endpoints except for the logging endpoint allow you to
fetch (and edit and delete where appropriate) individual objects by

View File

@ -54,6 +54,7 @@ export class LogsComponent implements OnInit, AfterViewChecked, OnDestroy {
ngOnDestroy(): void {
this.unsubscribeNotifier.next(true)
this.unsubscribeNotifier.complete()
clearInterval(this.autoRefreshInterval)
}
reloadLogs() {

View File

@ -46,6 +46,7 @@ export class TasksComponent
ngOnDestroy() {
this.tasksService.cancelPending()
clearInterval(this.autoRefreshInterval)
}
dismissTask(task: PaperlessTask) {

View File

@ -34,6 +34,9 @@
(focus)="clearLastSearchTerm()"
(clear)="clearLastSearchTerm()"
(blur)="onBlur()">
<ng-template ng-option-tmp let-item="item">
<span [title]="item.name">{{item.name}}</span>
</ng-template>
</ng-select>
@if (allowCreateNew) {
<button class="btn btn-outline-secondary" type="button" (click)="addItem()" [disabled]="disabled">

View File

@ -105,7 +105,7 @@ class BarcodeReader:
asn_text = asn_text[len(settings.CONSUMER_ASN_BARCODE_PREFIX) :].strip()
# remove non-numeric parts of the remaining string
asn_text = re.sub("[^0-9]", "", asn_text)
asn_text = re.sub(r"\D", "", asn_text)
# now, try parsing the ASN number
try:

View File

@ -2,12 +2,16 @@ from django.conf import settings
from django.contrib import auth
from django.contrib.auth.middleware import PersistentRemoteUserMiddleware
from django.contrib.auth.models import User
from django.http import HttpRequest
from django.utils.deprecation import MiddlewareMixin
from rest_framework import authentication
class AutoLoginMiddleware(MiddlewareMixin):
def process_request(self, request):
def process_request(self, request: HttpRequest):
# Dont use auto-login with token request
if request.path.startswith("/api/token/") and request.method == "POST":
return None
try:
request.user = User.objects.get(username=settings.AUTO_LOGIN_USERNAME)
auth.login(

View File

@ -315,8 +315,8 @@ if DEBUG:
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework.authentication.BasicAuthentication",
"rest_framework.authentication.SessionAuthentication",
"rest_framework.authentication.TokenAuthentication",
"rest_framework.authentication.SessionAuthentication",
],
"DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.AcceptHeaderVersioning",
"DEFAULT_VERSION": "1",

View File

@ -6,6 +6,7 @@ from django.urls import path
from django.urls import re_path
from django.utils.translation import gettext_lazy as _
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.generic import RedirectView
from rest_framework.authtoken import views
from rest_framework.routers import DefaultRouter
@ -180,7 +181,11 @@ urlpatterns = [
# login, logout
path("accounts/", include("django.contrib.auth.urls")),
# Root of the Frontend
re_path(r".*", login_required(IndexView.as_view()), name="base"),
re_path(
r".*",
login_required(ensure_csrf_cookie(IndexView.as_view())),
name="base",
),
]

View File

@ -703,6 +703,12 @@ class MailAccountHandler(LoggingMixin):
mime_type = magic.from_buffer(att.payload, mime=True)
if is_mime_type_supported(mime_type):
self.log.info(
f"Rule {rule}: "
f"Consuming attachment {att.filename} from mail "
f"{message.subject} from {message.from_}",
)
os.makedirs(settings.SCRATCH_DIR, exist_ok=True)
temp_dir = Path(
@ -711,14 +717,15 @@ class MailAccountHandler(LoggingMixin):
dir=settings.SCRATCH_DIR,
),
)
temp_filename = temp_dir / pathvalidate.sanitize_filename(att.filename)
temp_filename.write_bytes(att.payload)
self.log.info(
f"Rule {rule}: "
f"Consuming attachment {att.filename} from mail "
f"{message.subject} from {message.from_}",
)
attachment_name = pathvalidate.sanitize_filename(att.filename)
if attachment_name:
temp_filename = temp_dir / attachment_name
else: # pragma: no cover
# Some cases may have no name (generally inline)
temp_filename = temp_dir / "no-name-attachment"
temp_filename.write_bytes(att.payload)
input_doc = ConsumableDocument(
source=DocumentSource.MailFetch,