Frontend API preflight support (#359)
* add webapp submodule * add http OPTIONS support * add cors headers Co-authored-by: Henri Dickson <90480431+alphatownsman@users.noreply.github.com>
This commit is contained in:
parent
0c5f1aa395
commit
38cf2376b1
10 changed files with 95 additions and 33 deletions
4
.gitmodules
vendored
4
.gitmodules
vendored
|
@ -1,3 +1,7 @@
|
||||||
|
[submodule "webapp"]
|
||||||
|
path = webapp
|
||||||
|
url = https://github.com/neodb-social/webapp.git
|
||||||
|
branch = main
|
||||||
[submodule "neodb-takahe"]
|
[submodule "neodb-takahe"]
|
||||||
path = neodb-takahe
|
path = neodb-takahe
|
||||||
url = https://github.com/neodb-social/neodb-takahe.git
|
url = https://github.com/neodb-social/neodb-takahe.git
|
||||||
|
|
|
@ -249,6 +249,7 @@ INSTALLED_APPS = [
|
||||||
"polymorphic",
|
"polymorphic",
|
||||||
"easy_thumbnails",
|
"easy_thumbnails",
|
||||||
"user_messages",
|
"user_messages",
|
||||||
|
"corsheaders",
|
||||||
"anymail",
|
"anymail",
|
||||||
# "silk",
|
# "silk",
|
||||||
]
|
]
|
||||||
|
@ -274,6 +275,7 @@ MIDDLEWARE = [
|
||||||
"django.middleware.security.SecurityMiddleware",
|
"django.middleware.security.SecurityMiddleware",
|
||||||
# "silk.middleware.SilkyMiddleware",
|
# "silk.middleware.SilkyMiddleware",
|
||||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||||
|
"corsheaders.middleware.CorsMiddleware",
|
||||||
"django.middleware.common.CommonMiddleware",
|
"django.middleware.common.CommonMiddleware",
|
||||||
"django.middleware.csrf.CsrfViewMiddleware",
|
"django.middleware.csrf.CsrfViewMiddleware",
|
||||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||||
|
@ -484,4 +486,17 @@ OAUTH2_PROVIDER_APPLICATION_MODEL = "developer.Application"
|
||||||
|
|
||||||
DEVELOPER_CONSOLE_APPLICATION_CLIENT_ID = "NEODB_DEVELOPER_CONSOLE"
|
DEVELOPER_CONSOLE_APPLICATION_CLIENT_ID = "NEODB_DEVELOPER_CONSOLE"
|
||||||
|
|
||||||
|
# https://github.com/adamchainz/django-cors-headers#configuration
|
||||||
|
# CORS_ALLOWED_ORIGINS = []
|
||||||
|
# CORS_ALLOWED_ORIGIN_REGEXES = []
|
||||||
|
CORS_ALLOW_ALL_ORIGINS = True
|
||||||
|
CORS_URLS_REGEX = r"^/api/.*$"
|
||||||
|
CORS_ALLOW_METHODS = (
|
||||||
|
"DELETE",
|
||||||
|
"GET",
|
||||||
|
"OPTIONS",
|
||||||
|
# "PATCH",
|
||||||
|
"POST",
|
||||||
|
# "PUT",
|
||||||
|
)
|
||||||
DEFAULT_RELAY_SERVER = "https://relay.neodb.net/actor"
|
DEFAULT_RELAY_SERVER = "https://relay.neodb.net/actor"
|
||||||
|
|
|
@ -25,7 +25,8 @@ class SearchResult(Schema):
|
||||||
count: int
|
count: int
|
||||||
|
|
||||||
|
|
||||||
@api.get(
|
@api.api_operation(
|
||||||
|
["GET", "OPTIONS"],
|
||||||
"/catalog/search",
|
"/catalog/search",
|
||||||
response={200: SearchResult, 400: Result},
|
response={200: SearchResult, 400: Result},
|
||||||
summary="Search items in catalog",
|
summary="Search items in catalog",
|
||||||
|
@ -54,7 +55,8 @@ def search_item(
|
||||||
return 200, {"data": items, "pages": num_pages, "count": count}
|
return 200, {"data": items, "pages": num_pages, "count": count}
|
||||||
|
|
||||||
|
|
||||||
@api.get(
|
@api.api_operation(
|
||||||
|
["GET", "OPTIONS"],
|
||||||
"/catalog/fetch",
|
"/catalog/fetch",
|
||||||
response={200: ItemSchema, 202: Result, 404: Result},
|
response={200: ItemSchema, 202: Result, 404: Result},
|
||||||
summary="Fetch item from URL of a supported site",
|
summary="Fetch item from URL of a supported site",
|
||||||
|
@ -94,7 +96,8 @@ def _get_item(cls, uuid, response):
|
||||||
return item
|
return item
|
||||||
|
|
||||||
|
|
||||||
@api.get(
|
@api.api_operation(
|
||||||
|
["GET", "OPTIONS"],
|
||||||
"/book/{uuid}",
|
"/book/{uuid}",
|
||||||
response={200: EditionSchema, 302: RedirectedResult, 404: Result},
|
response={200: EditionSchema, 302: RedirectedResult, 404: Result},
|
||||||
auth=None,
|
auth=None,
|
||||||
|
@ -103,7 +106,8 @@ def get_book(request, uuid: str, response: HttpResponse):
|
||||||
return _get_item(Edition, uuid, response)
|
return _get_item(Edition, uuid, response)
|
||||||
|
|
||||||
|
|
||||||
@api.get(
|
@api.api_operation(
|
||||||
|
["GET", "OPTIONS"],
|
||||||
"/movie/{uuid}",
|
"/movie/{uuid}",
|
||||||
response={200: MovieSchema, 302: RedirectedResult, 404: Result},
|
response={200: MovieSchema, 302: RedirectedResult, 404: Result},
|
||||||
auth=None,
|
auth=None,
|
||||||
|
@ -112,7 +116,8 @@ def get_movie(request, uuid: str, response: HttpResponse):
|
||||||
return _get_item(Movie, uuid, response)
|
return _get_item(Movie, uuid, response)
|
||||||
|
|
||||||
|
|
||||||
@api.get(
|
@api.api_operation(
|
||||||
|
["GET", "OPTIONS"],
|
||||||
"/tv/{uuid}",
|
"/tv/{uuid}",
|
||||||
response={200: TVShowSchema, 302: RedirectedResult, 404: Result},
|
response={200: TVShowSchema, 302: RedirectedResult, 404: Result},
|
||||||
auth=None,
|
auth=None,
|
||||||
|
@ -121,7 +126,8 @@ def get_tv_show(request, uuid: str, response: HttpResponse):
|
||||||
return _get_item(TVShow, uuid, response)
|
return _get_item(TVShow, uuid, response)
|
||||||
|
|
||||||
|
|
||||||
@api.get(
|
@api.api_operation(
|
||||||
|
["GET", "OPTIONS"],
|
||||||
"/tv/season/{uuid}",
|
"/tv/season/{uuid}",
|
||||||
response={200: TVSeasonSchema, 302: RedirectedResult, 404: Result},
|
response={200: TVSeasonSchema, 302: RedirectedResult, 404: Result},
|
||||||
auth=None,
|
auth=None,
|
||||||
|
@ -130,7 +136,8 @@ def get_tv_season(request, uuid: str, response: HttpResponse):
|
||||||
return _get_item(TVSeason, uuid, response)
|
return _get_item(TVSeason, uuid, response)
|
||||||
|
|
||||||
|
|
||||||
@api.get(
|
@api.api_operation(
|
||||||
|
["GET", "OPTIONS"],
|
||||||
"/tv/episode/{uuid}",
|
"/tv/episode/{uuid}",
|
||||||
response={200: TVEpisodeSchema, 302: RedirectedResult, 404: Result},
|
response={200: TVEpisodeSchema, 302: RedirectedResult, 404: Result},
|
||||||
auth=None,
|
auth=None,
|
||||||
|
@ -139,7 +146,8 @@ def get_tv_episode(request, uuid: str, response: HttpResponse):
|
||||||
return _get_item(TVEpisode, uuid, response)
|
return _get_item(TVEpisode, uuid, response)
|
||||||
|
|
||||||
|
|
||||||
@api.get(
|
@api.api_operation(
|
||||||
|
["GET", "OPTIONS"],
|
||||||
"/podcast/{uuid}",
|
"/podcast/{uuid}",
|
||||||
response={200: PodcastSchema, 302: RedirectedResult, 404: Result},
|
response={200: PodcastSchema, 302: RedirectedResult, 404: Result},
|
||||||
auth=None,
|
auth=None,
|
||||||
|
@ -148,7 +156,8 @@ def get_podcast(request, uuid: str, response: HttpResponse):
|
||||||
return _get_item(Podcast, uuid, response)
|
return _get_item(Podcast, uuid, response)
|
||||||
|
|
||||||
|
|
||||||
@api.get(
|
@api.api_operation(
|
||||||
|
["GET", "OPTIONS"],
|
||||||
"/album/{uuid}",
|
"/album/{uuid}",
|
||||||
response={200: AlbumSchema, 302: RedirectedResult, 404: Result},
|
response={200: AlbumSchema, 302: RedirectedResult, 404: Result},
|
||||||
auth=None,
|
auth=None,
|
||||||
|
@ -157,7 +166,8 @@ def get_album(request, uuid: str, response: HttpResponse):
|
||||||
return _get_item(Album, uuid, response)
|
return _get_item(Album, uuid, response)
|
||||||
|
|
||||||
|
|
||||||
@api.get(
|
@api.api_operation(
|
||||||
|
["GET", "OPTIONS"],
|
||||||
"/game/{uuid}",
|
"/game/{uuid}",
|
||||||
response={200: GameSchema, 302: RedirectedResult, 404: Result},
|
response={200: GameSchema, 302: RedirectedResult, 404: Result},
|
||||||
auth=None,
|
auth=None,
|
||||||
|
@ -166,7 +176,8 @@ def get_game(request, uuid: str, response: HttpResponse):
|
||||||
return _get_item(Game, uuid, response)
|
return _get_item(Game, uuid, response)
|
||||||
|
|
||||||
|
|
||||||
@api.get(
|
@api.api_operation(
|
||||||
|
["GET", "OPTIONS"],
|
||||||
"/performance/{uuid}",
|
"/performance/{uuid}",
|
||||||
response={200: PerformanceSchema, 302: RedirectedResult, 404: Result},
|
response={200: PerformanceSchema, 302: RedirectedResult, 404: Result},
|
||||||
auth=None,
|
auth=None,
|
||||||
|
@ -175,7 +186,8 @@ def get_performance(request, uuid: str, response: HttpResponse):
|
||||||
return _get_item(Performance, uuid, response)
|
return _get_item(Performance, uuid, response)
|
||||||
|
|
||||||
|
|
||||||
@api.get(
|
@api.api_operation(
|
||||||
|
["GET", "OPTIONS"],
|
||||||
"/performance/production/{uuid}",
|
"/performance/production/{uuid}",
|
||||||
response={200: PerformanceProductionSchema, 302: RedirectedResult, 404: Result},
|
response={200: PerformanceProductionSchema, 302: RedirectedResult, 404: Result},
|
||||||
auth=None,
|
auth=None,
|
||||||
|
@ -192,7 +204,8 @@ class SearchResultLegacy(Schema):
|
||||||
pages: int
|
pages: int
|
||||||
|
|
||||||
|
|
||||||
@api.post(
|
@api.api_operation(
|
||||||
|
["POST", "OPTIONS"],
|
||||||
"/catalog/search",
|
"/catalog/search",
|
||||||
response={200: SearchResult, 400: Result},
|
response={200: SearchResult, 400: Result},
|
||||||
summary="This method is deprecated, will be removed by Aug 1 2023; use GET instead",
|
summary="This method is deprecated, will be removed by Aug 1 2023; use GET instead",
|
||||||
|
@ -209,7 +222,8 @@ def search_item_legacy(
|
||||||
return 200, {"items": result.items}
|
return 200, {"items": result.items}
|
||||||
|
|
||||||
|
|
||||||
@api.post(
|
@api.api_operation(
|
||||||
|
["POST", "OPTIONS"],
|
||||||
"/catalog/fetch",
|
"/catalog/fetch",
|
||||||
response={200: ItemSchema, 202: Result},
|
response={200: ItemSchema, 202: Result},
|
||||||
summary="This method is deprecated, will be removed by Aug 1 2023; use GET instead",
|
summary="This method is deprecated, will be removed by Aug 1 2023; use GET instead",
|
||||||
|
@ -227,7 +241,8 @@ def fetch_item_legacy(request, url: str):
|
||||||
return 202, {"message": "Fetch in progress"}
|
return 202, {"message": "Fetch in progress"}
|
||||||
|
|
||||||
|
|
||||||
@api.get(
|
@api.api_operation(
|
||||||
|
["GET", "OPTIONS"],
|
||||||
"/movie/{uuid}/",
|
"/movie/{uuid}/",
|
||||||
response={200: MovieSchema, 302: RedirectedResult, 404: Result},
|
response={200: MovieSchema, 302: RedirectedResult, 404: Result},
|
||||||
summary="This method is deprecated, will be removed by Aug 1 2023",
|
summary="This method is deprecated, will be removed by Aug 1 2023",
|
||||||
|
@ -238,7 +253,8 @@ def get_movie_legacy(request, uuid: str, response: HttpResponse):
|
||||||
return _get_item(Movie, uuid, response)
|
return _get_item(Movie, uuid, response)
|
||||||
|
|
||||||
|
|
||||||
@api.get(
|
@api.api_operation(
|
||||||
|
["GET", "OPTIONS"],
|
||||||
"/tv/{uuid}/",
|
"/tv/{uuid}/",
|
||||||
response={200: TVShowSchema, 302: RedirectedResult, 404: Result},
|
response={200: TVShowSchema, 302: RedirectedResult, 404: Result},
|
||||||
summary="This method is deprecated, will be removed by Aug 1 2023",
|
summary="This method is deprecated, will be removed by Aug 1 2023",
|
||||||
|
@ -249,7 +265,8 @@ def get_tv_show_legacy(request, uuid: str, response: HttpResponse):
|
||||||
return _get_item(TVShow, uuid, response)
|
return _get_item(TVShow, uuid, response)
|
||||||
|
|
||||||
|
|
||||||
@api.get(
|
@api.api_operation(
|
||||||
|
["GET", "OPTIONS"],
|
||||||
"/tvseason/{uuid}/",
|
"/tvseason/{uuid}/",
|
||||||
response={200: TVSeasonSchema, 302: RedirectedResult, 404: Result},
|
response={200: TVSeasonSchema, 302: RedirectedResult, 404: Result},
|
||||||
summary="This method is deprecated, will be removed by Aug 1 2023",
|
summary="This method is deprecated, will be removed by Aug 1 2023",
|
||||||
|
@ -260,7 +277,8 @@ def get_tv_season_legacy(request, uuid: str, response: HttpResponse):
|
||||||
return _get_item(TVSeason, uuid, response)
|
return _get_item(TVSeason, uuid, response)
|
||||||
|
|
||||||
|
|
||||||
@api.get(
|
@api.api_operation(
|
||||||
|
["GET", "OPTIONS"],
|
||||||
"/podcast/{uuid}/",
|
"/podcast/{uuid}/",
|
||||||
response={200: PodcastSchema, 302: RedirectedResult, 404: Result},
|
response={200: PodcastSchema, 302: RedirectedResult, 404: Result},
|
||||||
summary="This method is deprecated, will be removed by Aug 1 2023",
|
summary="This method is deprecated, will be removed by Aug 1 2023",
|
||||||
|
@ -271,7 +289,8 @@ def get_podcast_legacy(request, uuid: str, response: HttpResponse):
|
||||||
return _get_item(Podcast, uuid, response)
|
return _get_item(Podcast, uuid, response)
|
||||||
|
|
||||||
|
|
||||||
@api.get(
|
@api.api_operation(
|
||||||
|
["GET", "OPTIONS"],
|
||||||
"/album/{uuid}/",
|
"/album/{uuid}/",
|
||||||
response={200: AlbumSchema, 302: RedirectedResult, 404: Result},
|
response={200: AlbumSchema, 302: RedirectedResult, 404: Result},
|
||||||
summary="This method is deprecated, will be removed by Aug 1 2023",
|
summary="This method is deprecated, will be removed by Aug 1 2023",
|
||||||
|
@ -282,7 +301,8 @@ def get_album_legacy(request, uuid: str, response: HttpResponse):
|
||||||
return _get_item(Album, uuid, response)
|
return _get_item(Album, uuid, response)
|
||||||
|
|
||||||
|
|
||||||
@api.get(
|
@api.api_operation(
|
||||||
|
["GET", "OPTIONS"],
|
||||||
"/game/{uuid}/",
|
"/game/{uuid}/",
|
||||||
response={200: GameSchema, 302: RedirectedResult, 404: Result},
|
response={200: GameSchema, 302: RedirectedResult, 404: Result},
|
||||||
summary="This method is deprecated, will be removed by Aug 1 2023",
|
summary="This method is deprecated, will be removed by Aug 1 2023",
|
||||||
|
|
|
@ -13,16 +13,23 @@ from oauthlib.oauth2 import Server
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
PERMITTED_WRITE_METHODS = ["PUT", "POST", "DELETE", "PATCH"]
|
||||||
|
PERMITTED_READ_METHODS = ["GET", "HEAD", "OPTIONS"]
|
||||||
|
|
||||||
|
|
||||||
class OAuthAccessTokenAuth(HttpBearer):
|
class OAuthAccessTokenAuth(HttpBearer):
|
||||||
def authenticate(self, request, token):
|
def authenticate(self, request, token) -> bool:
|
||||||
if not token or not request.user.is_authenticated:
|
if not token or not request.user.is_authenticated:
|
||||||
_logger.debug("API auth: no access token or user not authenticated")
|
_logger.debug("API auth: no access token or user not authenticated")
|
||||||
return False
|
return False
|
||||||
request_scopes = []
|
request_scopes = []
|
||||||
if request.method in ["GET", "HEAD", "OPTIONS"]:
|
request_method = request.method
|
||||||
|
if request_method in PERMITTED_READ_METHODS:
|
||||||
request_scopes = ["read"]
|
request_scopes = ["read"]
|
||||||
else:
|
elif request_method in PERMITTED_WRITE_METHODS:
|
||||||
request_scopes = ["write"]
|
request_scopes = ["write"]
|
||||||
|
else:
|
||||||
|
return False
|
||||||
validator = OAuth2Validator()
|
validator = OAuth2Validator()
|
||||||
core = OAuthLibCore(Server(validator))
|
core = OAuthLibCore(Server(validator))
|
||||||
valid, oauthlib_req = core.verify_request(request, scopes=request_scopes)
|
valid, oauthlib_req = core.verify_request(request, scopes=request_scopes)
|
||||||
|
|
|
@ -35,7 +35,11 @@ class MarkInSchema(Schema):
|
||||||
post_to_fediverse: bool = False
|
post_to_fediverse: bool = False
|
||||||
|
|
||||||
|
|
||||||
@api.get("/me/shelf/{type}", response={200: List[MarkSchema], 401: Result, 403: Result})
|
@api.api_operation(
|
||||||
|
["GET", "OPTIONS"],
|
||||||
|
"/me/shelf/{type}",
|
||||||
|
response={200: List[MarkSchema], 401: Result, 403: Result},
|
||||||
|
)
|
||||||
@paginate(PageNumberPagination)
|
@paginate(PageNumberPagination)
|
||||||
def list_marks_on_shelf(
|
def list_marks_on_shelf(
|
||||||
request, type: ShelfType, category: AvailableItemCategory | None = None
|
request, type: ShelfType, category: AvailableItemCategory | None = None
|
||||||
|
@ -52,7 +56,8 @@ def list_marks_on_shelf(
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
@api.get(
|
@api.api_operation(
|
||||||
|
["GET", "OPTIONS"],
|
||||||
"/me/shelf/item/{item_uuid}",
|
"/me/shelf/item/{item_uuid}",
|
||||||
response={200: MarkSchema, 401: Result, 403: Result, 404: Result},
|
response={200: MarkSchema, 401: Result, 403: Result, 404: Result},
|
||||||
)
|
)
|
||||||
|
@ -69,7 +74,8 @@ def get_mark_by_item(request, item_uuid: str):
|
||||||
return shelfmember
|
return shelfmember
|
||||||
|
|
||||||
|
|
||||||
@api.post(
|
@api.api_operation(
|
||||||
|
["POST", "OPTIONS"],
|
||||||
"/me/shelf/item/{item_uuid}",
|
"/me/shelf/item/{item_uuid}",
|
||||||
response={200: Result, 401: Result, 403: Result, 404: Result},
|
response={200: Result, 401: Result, 403: Result, 404: Result},
|
||||||
)
|
)
|
||||||
|
@ -101,7 +107,8 @@ def mark_item(request, item_uuid: str, mark: MarkInSchema):
|
||||||
return 200, {"message": "OK"}
|
return 200, {"message": "OK"}
|
||||||
|
|
||||||
|
|
||||||
@api.delete(
|
@api.api_operation(
|
||||||
|
["DELETE", "OPTIONS"],
|
||||||
"/me/shelf/item/{item_uuid}",
|
"/me/shelf/item/{item_uuid}",
|
||||||
response={200: Result, 401: Result, 403: Result, 404: Result},
|
response={200: Result, 401: Result, 403: Result, 404: Result},
|
||||||
)
|
)
|
||||||
|
@ -137,7 +144,11 @@ class ReviewInSchema(Schema):
|
||||||
post_to_fediverse: bool = False
|
post_to_fediverse: bool = False
|
||||||
|
|
||||||
|
|
||||||
@api.get("/me/review/", response={200: List[ReviewSchema], 401: Result, 403: Result})
|
@api.api_operation(
|
||||||
|
["GET", "OPTIONS"],
|
||||||
|
"/me/review/",
|
||||||
|
response={200: List[ReviewSchema], 401: Result, 403: Result},
|
||||||
|
)
|
||||||
@paginate(PageNumberPagination)
|
@paginate(PageNumberPagination)
|
||||||
def list_reviews(request, category: AvailableItemCategory | None = None):
|
def list_reviews(request, category: AvailableItemCategory | None = None):
|
||||||
"""
|
"""
|
||||||
|
@ -151,7 +162,8 @@ def list_reviews(request, category: AvailableItemCategory | None = None):
|
||||||
return queryset.prefetch_related("item")
|
return queryset.prefetch_related("item")
|
||||||
|
|
||||||
|
|
||||||
@api.get(
|
@api.api_operation(
|
||||||
|
["GET", "OPTIONS"],
|
||||||
"/me/review/item/{item_uuid}",
|
"/me/review/item/{item_uuid}",
|
||||||
response={200: ReviewSchema, 401: Result, 403: Result, 404: Result},
|
response={200: ReviewSchema, 401: Result, 403: Result, 404: Result},
|
||||||
)
|
)
|
||||||
|
@ -197,7 +209,8 @@ def review_item(request, item_uuid: str, review: ReviewInSchema):
|
||||||
return 200, {"message": "OK"}
|
return 200, {"message": "OK"}
|
||||||
|
|
||||||
|
|
||||||
@api.delete(
|
@api.api_operation(
|
||||||
|
["DELETE", "OPTIONS"],
|
||||||
"/me/review/item/{item_uuid}",
|
"/me/review/item/{item_uuid}",
|
||||||
response={200: Result, 401: Result, 403: Result, 404: Result},
|
response={200: Result, 401: Result, 403: Result, 404: Result},
|
||||||
)
|
)
|
||||||
|
|
|
@ -269,7 +269,7 @@ def detect_server_info(login_domain):
|
||||||
return domain, api_domain, server_version
|
return domain, api_domain, server_version
|
||||||
|
|
||||||
|
|
||||||
def get_mastodon_application(login_domain):
|
def get_or_create_fediverse_application(login_domain):
|
||||||
domain = login_domain
|
domain = login_domain
|
||||||
app = MastodonApplication.objects.filter(domain_name__iexact=domain).first()
|
app = MastodonApplication.objects.filter(domain_name__iexact=domain).first()
|
||||||
if not app:
|
if not app:
|
||||||
|
|
|
@ -6,6 +6,7 @@ django-anymail
|
||||||
django-auditlog>=3.0.0-beta.2
|
django-auditlog>=3.0.0-beta.2
|
||||||
django-bleach
|
django-bleach
|
||||||
django-compressor
|
django-compressor
|
||||||
|
django-cors-headers
|
||||||
django-environ
|
django-environ
|
||||||
django-hijack
|
django-hijack
|
||||||
django-jsonform
|
django-jsonform
|
||||||
|
|
|
@ -117,7 +117,7 @@ def connect(request):
|
||||||
login_domain.strip().lower().split("//")[-1].split("/")[0].split("@")[-1]
|
login_domain.strip().lower().split("//")[-1].split("/")[0].split("@")[-1]
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
app = get_mastodon_application(login_domain)
|
app = get_or_create_fediverse_application(login_domain)
|
||||||
if app.api_domain and app.api_domain != app.domain_name:
|
if app.api_domain and app.api_domain != app.domain_name:
|
||||||
login_domain = app.api_domain
|
login_domain = app.api_domain
|
||||||
login_url = get_mastodon_login_url(app, login_domain, request)
|
login_url = get_mastodon_login_url(app, login_domain, request)
|
||||||
|
|
|
@ -12,7 +12,8 @@ class UserSchema(Schema):
|
||||||
avatar: str
|
avatar: str
|
||||||
|
|
||||||
|
|
||||||
@api.get(
|
@api.api_operation(
|
||||||
|
["GET", "OPTIONS"],
|
||||||
"/me",
|
"/me",
|
||||||
response={200: UserSchema, 401: Result},
|
response={200: UserSchema, 401: Result},
|
||||||
summary="Get current user's basic info",
|
summary="Get current user's basic info",
|
||||||
|
|
1
webapp
Submodule
1
webapp
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit bea95c1f82bbc762e9933e22f520243feba8074a
|
Loading…
Add table
Reference in a new issue