Skip to content

Commit 92454bf

Browse files
committed
Improve PWA support and cookie handling for mobile
Added proper PNG icons and maskable icons for PWA compatibility, updated manifest with new icons and orientation, and improved cookie handling for better persistence and compatibility on mobile PWAs (notably iOS). Also added Apple mobile web app meta tags to HTML templates.
1 parent 9127e39 commit 92454bf

8 files changed

Lines changed: 35 additions & 8 deletions

File tree

backend/app.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ def create_app():
6060
# Auth cookie flags
6161
app.config['AUTH_COOKIE_NAME'] = os.environ.get('AUTH_COOKIE_NAME', 'access_token')
6262
app.config['AUTH_COOKIE_SECURE'] = os.environ.get('AUTH_COOKIE_SECURE', 'false').lower() == 'true' or app.config['SESSION_COOKIE_SECURE']
63-
app.config['AUTH_COOKIE_SAMESITE'] = os.environ.get('AUTH_COOKIE_SAMESITE', 'Strict')
63+
# Default to Lax for broader compatibility (iOS PWA standalone quirks)
64+
app.config['AUTH_COOKIE_SAMESITE'] = os.environ.get('AUTH_COOKIE_SAMESITE', 'Lax')
6465
app.config['AUTH_COOKIE_DOMAIN'] = os.environ.get('AUTH_COOKIE_DOMAIN') # optional
6566

6667
init_db()
@@ -177,6 +178,8 @@ def _set_auth_cookie(resp, token: str):
177178
secure=bool(app.config['AUTH_COOKIE_SECURE']),
178179
samesite=app.config['AUTH_COOKIE_SAMESITE'],
179180
max_age=int(app.config['JWT_TTL_SECONDS']),
181+
# Also set expires to improve persistence on some mobile PWAs
182+
expires=datetime.now(timezone.utc) + timedelta(seconds=int(app.config['JWT_TTL_SECONDS'])),
180183
path='/',
181184
domain=app.config['AUTH_COOKIE_DOMAIN'] or None,
182185
)
@@ -372,10 +375,10 @@ def login():
372375
# Then try temp password if present and not expired
373376
if tmp_hash and tmp_exp:
374377
try:
375-
exp_dt = datetime.strptime(tmp_exp, '%Y-%m-%dT%H:%M:%fZ')
378+
exp_dt = datetime.strptime(tmp_exp, '%Y-%m-%dT%H:%M:%fZ').replace(tzinfo=timezone.utc)
376379
except Exception:
377380
exp_dt = None
378-
now = datetime.utcnow()
381+
now = datetime.now(timezone.utc)
379382
valid = bool(exp_dt and exp_dt >= now)
380383
if valid and check_password_hash(tmp_hash, password):
381384
authed_with_temp = True
@@ -789,7 +792,7 @@ def forgot_confirm():
789792
return jsonify(error=err or 'smtp_send_failed'), 500
790793
# Store temp password hash and expiry (1 day)
791794
try:
792-
expires = (datetime.utcnow() + timedelta(days=1)).strftime('%Y-%m-%dT%H:%M:%fZ')
795+
expires = (datetime.now(timezone.utc) + timedelta(days=1)).strftime('%Y-%m-%dT%H:%M:%fZ')
793796
cur.execute(
794797
"UPDATE users SET temp_password_hash=?, temp_password_expires=? WHERE id=?",
795798
(generate_password_hash(new_pw), expires, user_id),
895 Bytes
Loading
3.23 KB
Loading
895 Bytes
Loading
3.23 KB
Loading

backend/static/manifest.webmanifest

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,37 @@
22
"name": "EasyTodo",
33
"short_name": "EasyTodo",
44
"description": "轻量、简洁的待办事项应用",
5+
"id": "/",
56
"start_url": "/",
67
"scope": "/",
78
"display": "standalone",
9+
"orientation": "any",
810
"background_color": "#0b0b0c",
911
"theme_color": "#f7f8fa",
1012
"icons": [
1113
{
12-
"src": "/static/favicon.svg",
13-
"sizes": "any",
14-
"type": "image/svg+xml",
15-
"purpose": "any maskable"
14+
"src": "/static/icons/icon-192x192.png",
15+
"sizes": "192x192",
16+
"type": "image/png",
17+
"purpose": "any"
18+
},
19+
{
20+
"src": "/static/icons/icon-512x512.png",
21+
"sizes": "512x512",
22+
"type": "image/png",
23+
"purpose": "any"
24+
},
25+
{
26+
"src": "/static/icons/maskable-icon-192x192.png",
27+
"sizes": "192x192",
28+
"type": "image/png",
29+
"purpose": "maskable"
30+
},
31+
{
32+
"src": "/static/icons/maskable-icon-512x512.png",
33+
"sizes": "512x512",
34+
"type": "image/png",
35+
"purpose": "maskable"
1636
}
1737
]
1838
}

backend/templates/index.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
<head>
44
<meta charset="utf-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1" />
6+
<meta name="apple-mobile-web-app-capable" content="yes" />
7+
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
68
<title>{{ title or 'EasyTodo 待办' }}</title>
79
<meta name="theme-color" content="#f7f8fa" id="theme-color" />
810
<meta name="csrf-token" content="{{ csrf_token }}" />

backend/templates/login.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
<head>
44
<meta charset="utf-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1" />
6+
<meta name="apple-mobile-web-app-capable" content="yes" />
7+
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
68
<title>{{ title or '登录 / 注册 - EasyTodo' }}</title>
79
<meta name="theme-color" content="#f7f8fa" id="theme-color" />
810
<link rel="icon" href="/static/favicon.svg" />

0 commit comments

Comments
 (0)