Remove guest login: every user registers with a phone number
POST /api/auth/session is gone (404). Existing is_guest rows keep refresh and upgrade-by-phone until the demo/guest rows are purged; the code that serves them is listed in docs/security-before-production.md §10. Tests that used the endpoint as a fixture now use accounts/testing.guest_session. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -23,15 +23,15 @@
|
||||
|---|---|---|---|
|
||||
| ۱ | کلیدِ امضای توکن روی سرور همان رشتهی داخلِ ریپو است | بحرانی — جعلِ ورود بهجای هر کاربر | کد آماده؛ اعمال روی سرور |
|
||||
| ۲ | ۷ حسابِ دمو با کدِ ورودِ ثابت روی پروداکشن | بالا | `.env` سرور |
|
||||
| ۳ | دادهی دمو و حسابِ مهمانِ عمومیِ `frontend-test-device` | بالا | دیتابیسِ سرور |
|
||||
| ۳ | دادهی دمو و حسابِ مهمانِ نمایشیِ `frontend-test-device` | بالا | دیتابیسِ سرور |
|
||||
| ۴ | `/api/health` جزئیاتِ داخلی را به همه نشان میدهد | متوسط | کد |
|
||||
| ۵ | Swagger، ReDoc و schemaی کاملِ API عمومیاند | متوسط | کد |
|
||||
| ۷ | پنلِ `/admin/` روی دامنهی عمومی | متوسط | nginx + کد |
|
||||
| ۸ | سرور بدونِ ArvanCloud روی پورتِ ۸۰ هم جواب میدهد | متوسط | ادمینِ سرور |
|
||||
| ۹ | کشِ مشترک (Redis) نیست؛ محدودیتها per-workerاند | متوسط | `.env` سرور |
|
||||
| ۱۰ | ورودِ مهمان فقط با `deviceId` است | کم (طراحی) | کد |
|
||||
| ۱۰ | حسابهای مهمانِ قدیمی (دمو و کاربرانِ پیش از حذفِ ورودِ مهمان) هنوز در دیتابیساند | کم | دیتابیسِ سرور |
|
||||
| ۱۱ | کدِ OTP بیهش در دیتابیس و در فهرستِ پنل | کم | کد |
|
||||
| ۱۲ | هزینهی دستیارِ AI با ساختِ حسابِ مهمان قابلِ بالا بردن است | کم (مالی) | کد |
|
||||
| ۱۲ | هزینهی دستیارِ AI با ساختِ حسابِ تازه (هر شماره ۳ سوالِ رایگان) قابلِ بالا بردن است | کم (مالی) | کد |
|
||||
| ۱۴ | SQLite روی دیسکِ مشترکِ پُر، بدونِ بکاپِ خودکارِ بیرون از ماشین | کم (داده) | زیرساخت |
|
||||
| ۱۵ | دسترسیِ سرور: حسابِ مشترک، رمز، sudoِ کامل | بالا | ادمینِ سرور |
|
||||
| ۱۶ | فرانت توکن را در `localStorage` نگه میدارد | کم | فرانت |
|
||||
@@ -85,15 +85,15 @@
|
||||
از تستِ دستیار؛ همراهِ بقیه پاک شوند.
|
||||
- **چیست:** کاربرهای ۶ (`deviceId = frontend-test-device`) و ۱۰ تا ۱۵، با درس، گفتگو،
|
||||
تیکت، خانواده و زیرمجموعه، روی دیتابیسِ پروداکشن ساخته شدهاند. `frontend-test-device`
|
||||
در ریپو نوشته شده؛ هر کس `POST /api/auth/session` با همین `deviceId` بزند، توکنِ همان
|
||||
حساب را میگیرد.
|
||||
در ریپو نوشته شده. `POST /api/auth/session` حذف شده، پس با آن دیگر توکن نمیدهد؛ ولی خودِ
|
||||
ردیفها (با `is_guest=True`) تا پاک نشوند در دیتابیساند.
|
||||
- **خطر:** دادهی ساختگی در آمار و جدولِ رتبهبندیِ واقعی؛ یک حسابِ عمومی که هر کس
|
||||
میتواند با آن کار کند (ثبتِ تیکت، گفتگو با AI به هزینهی ما).
|
||||
- **رفع:** پیش از کاربرِ واقعی پاک شوند. `purge_demo_data` اینها را **نمیگیرد** (از مسیرِ
|
||||
واقعیِ viewها ساخته شدهاند)؛ باید با شناسه پاک شوند، پیش از آن بکاپ. همراهِ آن پیشفرضِ
|
||||
`DEMO_GUEST_DEVICE_IDS` در `config/settings.py` (که حذفِ این مهمان را با `POST /api/user/delete`
|
||||
میبندد) هم برداشته شود.
|
||||
- **چطور بسنجید:** `POST /api/auth/session` با `frontend-test-device` باید `isNewUser: true` بدهد.
|
||||
- **چطور بسنجید:** در پنل یا shell، `User.objects.filter(is_guest=True).count()` پس از پاکسازی باید صفر باشد.
|
||||
|
||||
## ۴. `/api/health` عمومی و پرجزئیات
|
||||
|
||||
@@ -157,16 +157,15 @@
|
||||
- **رفع:** `CACHE_URL=redis://127.0.0.1:6379/1` (db0 مالِ اپِ دیگری است) و ریاستارت.
|
||||
- **چطور بسنجید:** `/api/health` → `checks.cache.backend` نباید `LocMemCache` باشد.
|
||||
|
||||
## ۱۰. ورودِ مهمان فقط با `deviceId`
|
||||
## ۱۰. حسابهای مهمانِ قدیمی
|
||||
|
||||
- **چیست:** `POST /api/auth/session` با هر `deviceId` یا حسابِ مهمانِ همان دستگاه را
|
||||
برمیگرداند یا میسازد (`accounts/views.py::GuestSessionView`). هیچ رازِ دیگری در کار نیست.
|
||||
- **خطر:** هر کس `deviceId`ِ یک مهمان را بداند (از `localStorage`، لاگ، اسکرینشات) وارد
|
||||
حسابِ او میشود. بعد از ثبتنام با شماره این راه بسته میشود (مهمان دیگر مهمان نیست) و همهی
|
||||
نشستهایی که پیش از آن گرفته شده بودند باطل میشوند. شناسهی دستگاه در پنل فقط برای ابرکاربر
|
||||
نمایش داده میشود.
|
||||
- **رفع:** برای مهمان هم یک رازِ تصادفیِ سمتِ سرور صادر شود و ورودِ دوباره با همان راز باشد،
|
||||
نه با `deviceId`ِ خام.
|
||||
- **چیست:** ورودِ مهمان (`POST /api/auth/session`) حذف شده و هر کاربرِ تازه با شماره ثبتنام میکند.
|
||||
ردیفهای مهمانِ پیشین (`User.is_guest=True`، شامل دموها) در دیتابیس ماندهاند و کدِ ارتقای مهمان به
|
||||
حسابِ شمارهدار (`LoginView`) و throttleهای مهمانمحور هنوز برایشان کار میکنند.
|
||||
- **خطر:** مهمانِ قدیمی هنوز با `refreshToken` ذخیرهشده در مرورگرش وارد میماند؛ شناسهی دستگاه دیگر
|
||||
راهِ ورود نیست.
|
||||
- **رفع:** پس از پاکسازیِ دموها (بند ۳) و دیدنِ اینکه مهمانِ واقعی نمانده، کدِ مهمان
|
||||
(`is_guest`، `GuestAware*Throttle`، ارتقا) حذف شود. تا آن روز عمداً نگه داشته شده.
|
||||
|
||||
## ۱۱. کدِ OTP بیهش در دیتابیس
|
||||
|
||||
@@ -179,8 +178,8 @@
|
||||
## ۱۲. هزینهی دستیارِ AI
|
||||
|
||||
- **چیست:** هر کاربر روزی ۳ سؤالِ رایگان دارد (`AI_DAILY_QUOTA_FREE`)
|
||||
و بعد فقط با اعتبارِ خریدهشده؛ ۲۰ در ساعت. مهمانها بر اساسِ IP محدود میشوند ولی هر IP ساعتی
|
||||
۶۰ حسابِ مهمانِ تازه میسازد (`guest_session`)، و هر حسابِ تازه ۳ سؤالِ رایگانِ تازه دارد. سقفِ
|
||||
و بعد فقط با اعتبارِ خریدهشده؛ ۲۰ در ساعت. هر شمارهی تازه ۳ سؤالِ رایگان میگیرد و ساختنِ شماره با سقفِ پیامک
|
||||
(بند ۲۴) محدود است. سقفِ
|
||||
روزانهی کلِ سامانه (`AI_GLOBAL_DAILY_MAX`، ۳۰۰۰) خرجِ کل را محدود میکند. طولِ سؤال حداکثر ۲۰۰۰ نویسه است.
|
||||
- **خطر:** با چند IP، اعتبارِ GapGPT در چند ساعت تمام میشود (اعتبار یک بار در ۲۰۲۶-۰۹-۲۵
|
||||
به صفر رسید، البته به دلیلِ دیگر).
|
||||
@@ -325,6 +324,7 @@
|
||||
|
||||
| حفاظ | تست |
|
||||
|---|---|
|
||||
| ورودِ مهمان وجود ندارد (`POST /api/auth/session` ۴۰۴ میدهد و کاربر نمیسازد)؛ حسابِ مهمانِ قدیمی همچنان refresh و ارتقا دارد | `accounts/tests.py` (`test_guest_login_endpoint_is_gone`)، `accounts/tests_guest_refresh.py` |
|
||||
| پلنِ هر خرید روی سفارش؛ خرید اشتراکِ فعال را دست نمیزند؛ یک کدِ تخفیف پیش از درگاه؛ امتیاز فقط از جوابِ ثبتشده | `payment/tests_audit_fixes.py`، `accounts/tests_audit_fixes.py` |
|
||||
| لینکِ پرداخت (`/api/payment/orders/{id}/pay`) فقط با امضای کوتاهعمرِ همراهِ `paymentUrl` باز میشود | `payment/tests.py` (`PaymentRedirectViewTests`) |
|
||||
| توکنِ تمدید فقط بهصورتِ هشِ SHA-256 ذخیره میشود | `accounts/tests.py` (`RefreshTokenStoredHashedTests`) |
|
||||
|
||||
Reference in New Issue
Block a user