March 17 2026: Mobile app phase 1 - fix error
This commit is contained in:
+14
-5
@@ -3,15 +3,17 @@ from flask_sqlalchemy import SQLAlchemy
|
||||
from flask_login import LoginManager
|
||||
from flask_migrate import Migrate
|
||||
from flask_mail import Mail
|
||||
from flask_wtf.csrf import CSRFProtect
|
||||
from config import config
|
||||
import os
|
||||
import logging
|
||||
from logging.handlers import RotatingFileHandler
|
||||
|
||||
db = SQLAlchemy()
|
||||
db = SQLAlchemy()
|
||||
login_manager = LoginManager()
|
||||
migrate = Migrate()
|
||||
mail = Mail()
|
||||
migrate = Migrate()
|
||||
mail = Mail()
|
||||
csrf = CSRFProtect() # initialized here; .init_app() called in create_app()
|
||||
|
||||
|
||||
def create_app(config_name='default'):
|
||||
@@ -22,6 +24,7 @@ def create_app(config_name='default'):
|
||||
login_manager.init_app(app)
|
||||
migrate.init_app(app, db)
|
||||
mail.init_app(app)
|
||||
csrf.init_app(app) # enables CSRF protection for all web routes
|
||||
|
||||
login_manager.login_view = 'auth.login'
|
||||
login_manager.login_message = 'Please log in to access this page.'
|
||||
@@ -69,6 +72,8 @@ def create_app(config_name='default'):
|
||||
|
||||
# Register csrf_token() as an app-wide Jinja2 global so templates that
|
||||
# render manual forms (no WTForms object) can still inject the CSRF token.
|
||||
# CSRFProtect (initialized above) is the authoritative guard for web routes;
|
||||
# the /api/v1 blueprint is exempted below via csrf.exempt().
|
||||
from flask_wtf.csrf import generate_csrf
|
||||
app.jinja_env.globals['csrf_token'] = generate_csrf
|
||||
app.jinja_env.globals['enumerate'] = enumerate
|
||||
@@ -131,8 +136,12 @@ def create_app(config_name='default'):
|
||||
app.register_blueprint(customers.bp)
|
||||
app.register_blueprint(scheduled_reports.bp)
|
||||
|
||||
# ── Mobile API ─────────────────────────────────────────────
|
||||
from app.api import register_api
|
||||
# ── Mobile API (Phase 7) ─────────────────────────────────────────────────
|
||||
# The /api/v1 blueprint uses JWT Bearer tokens — no CSRF cookies needed.
|
||||
# Exempt it from CSRFProtect before registering so POST /api/v1/* routes
|
||||
# are never rejected for a missing CSRF token.
|
||||
from app.api import register_api, api_bp
|
||||
csrf.exempt(api_bp)
|
||||
register_api(app)
|
||||
|
||||
# ── Error handler: 413 Request Entity Too Large ───────────────────────
|
||||
|
||||
+1
-1
@@ -57,4 +57,4 @@ def register_api(app):
|
||||
# api_bp.register_blueprint(notifications_bp)
|
||||
# api_bp.register_blueprint(photos_bp)
|
||||
|
||||
app.register_blueprint(api_bp)
|
||||
app.register_blueprint(api_bp)
|
||||
+1
-7
@@ -31,8 +31,6 @@ GET /api/v1/auth/me
|
||||
import logging
|
||||
|
||||
from flask import Blueprint, request, g
|
||||
from flask_wtf.csrf import csrf_exempt
|
||||
|
||||
from app import db
|
||||
from app.models.user import User
|
||||
from app.models.api_token import RefreshToken, DeviceToken
|
||||
@@ -61,7 +59,6 @@ def _user_payload(user: User) -> dict:
|
||||
# ── Login ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
@bp.route('/auth/login', methods=['POST'])
|
||||
@csrf_exempt
|
||||
def login():
|
||||
"""
|
||||
Authenticate with username + password.
|
||||
@@ -137,7 +134,6 @@ def login():
|
||||
# ── Refresh ───────────────────────────────────────────────────────────────────
|
||||
|
||||
@bp.route('/auth/refresh', methods=['POST'])
|
||||
@csrf_exempt
|
||||
def refresh():
|
||||
"""
|
||||
Exchange a valid refresh token for a new access token.
|
||||
@@ -207,7 +203,6 @@ def refresh():
|
||||
# ── Logout ────────────────────────────────────────────────────────────────────
|
||||
|
||||
@bp.route('/auth/logout', methods=['POST'])
|
||||
@csrf_exempt
|
||||
@jwt_required
|
||||
def logout():
|
||||
"""
|
||||
@@ -261,7 +256,6 @@ def me():
|
||||
# ── Device token registration ─────────────────────────────────────────────────
|
||||
|
||||
@bp.route('/devices/register', methods=['POST'])
|
||||
@csrf_exempt
|
||||
@jwt_required
|
||||
def register_device():
|
||||
"""
|
||||
@@ -316,4 +310,4 @@ def register_device():
|
||||
logger.info('API DEVICE REGISTERED | user=%s | device_id=%s | apns_token=...%s',
|
||||
g.api_user.username, device_id, apns_token[-6:])
|
||||
|
||||
return api_ok({'registered': True})
|
||||
return api_ok({'registered': True})
|
||||
Reference in New Issue
Block a user