Parent Portal adalah portal orang tua siswa YPII, dan Parent Portal tidak memakai kata sandi tetap. Setiap kali orang tua atau wali hendak masuk, Parent Portal menerbitkan satu kode OTP (One-Time Password) sekali pakai dan mengirimkannya ke alamat email yang dimasukkan — tetapi hanya bila alamat email itu tercatat di Odoo YPII sebagai kontak yang menjadi ayah, ibu, atau wali dari sekurang-kurangnya satu siswa. Dari layar halaman masuk, kedua kemungkinan itu tidak dapat dibedakan.
Ketika orang tua atau wali mengirimkan alamat email pada halaman masuk Parent Portal, layanan backend Parent Portal mencari kontak (res.partner) di Odoo YPII yang alamat emailnya cocok, lalu memeriksa apakah kontak itu tercantum sebagai father_id, mother_id, atau guardian_id pada sekurang-kurangnya satu record siswa (school_student). Bila kontak semacam itu ditemukan, Parent Portal membangkitkan kode OTP, menyimpan bentuk teracaknya di memori proses backend, lalu merakit satu email dan mengirimkannya sebagai pesan keluar Odoo YPII. Bila tidak ditemukan, tidak ada kode yang diterbitkan dan tidak ada email yang dikirim, sementara jawaban yang diterima halaman masuk tetap sama.
Sesudah orang tua atau wali memasukkan kode itu kembali, Parent Portal mencocokkannya dengan bentuk teracak yang tersimpan. Bila cocok dan masih berlaku, Parent Portal menerbitkan token akses dan token penyegar yang ditandatangani Parent Portal sendiri.
Otomasi ini dijalankan tiga bagian yang berbeda perannya.
Parent Portal tidak berbicara SMTP sendiri. Layanan backend Parent Portal membuat record mail.mail di Odoo YPII lalu memanggil metode send pada record itu, sehingga kredensial SMTP tetap tinggal di Odoo YPII sebagai ir.mail_server dan tidak pernah disalin ke konfigurasi Parent Portal. Pemanggilan send dilakukan seketika, bukan dibiarkan menunggu penjadwal email Odoo YPII yang berjalan sekitar satu menit sekali — jeda selama itu akan memakan sebagian besar masa berlaku kode OTP yang hanya lima menit.
Isi email kode OTP dirakit oleh layanan backend Parent Portal, bukan oleh template email (mail.template) di Odoo YPII. Nama sekolah, logo, dan warna utama pada email diambil dari berkas identitas merek yang di-mount ke container backend melalui BRANDING_CONFIG_PATH. Konsekuensinya, perubahan tampilan email kode OTP dilakukan di berkas identitas merek Parent Portal, bukan di menu template email Odoo YPII.
Bentuk teracak kode OTP, masa berlakunya, dan sisa jatah percobaan disimpan di dalam memori proses layanan backend Parent Portal — bukan di basis data, bukan di Odoo YPII, dan bukan di penyimpanan bersama seperti Redis. Ini pilihan yang disengaja untuk deployment satu instance, dan membawa dua akibat operasional yang harus diketahui.
Setiap kali container backend Parent Portal di-restart atau dinaikkan versinya, seluruh kode OTP yang sedang berlaku hangus seketika. Orang tua atau wali yang sudah menerima kode tetapi belum memasukkannya harus meminta kode baru. Karena itu restart backend pada jam sibuk masuk portal akan terlihat oleh pengguna sebagai kode yang tiba-tiba ditolak.
Penyimpanan kode OTP juga tidak konsisten bila layanan backend Parent Portal dijalankan lebih dari satu instance: kode yang diterbitkan instance pertama tidak dikenali instance kedua, sehingga verifikasi gagal secara acak tergantung instance mana yang melayani permintaan. Selama Parent Portal masih memakai penyimpanan di memori proses, penambahan replika backend tidak boleh dilakukan tanpa lebih dulu memindahkan penyimpanan kode OTP ke penyimpanan bersama.
Pemicunya adalah pengiriman alamat email pada halaman masuk Parent Portal, baik saat pertama kali meminta kode maupun saat menekan kirim ulang. Otomasi berlanjut sampai email benar-benar dikirim hanya bila seluruh syarat berikut terpenuhi.
OTP_RESEND_COOLDOWN_SECONDS detik yang lalu.res.partner) di Odoo YPII yang alamat emailnya cocok dengan alamat yang dimasukkan. Pencocokan dilakukan tanpa membedakan huruf besar dan kecil, setelah alamat dinormalkan menjadi huruf kecil dan dibuang spasi di kedua ujungnya.Bila syarat nomor 3 atau nomor 4 tidak terpenuhi, otomasi berhenti tanpa menerbitkan kode dan tanpa mengirim email, sedangkan halaman masuk Parent Portal tetap menerima jawaban keberhasilan yang sama.
Pencocokan kontak hanya memakai field email, tidak memakai nomor telepon seluler. Orang tua atau wali yang di Odoo YPII hanya memiliki nomor telepon tanpa alamat email tidak akan pernah dapat masuk ke Parent Portal sampai alamat emailnya diisi oleh sekolah.
OTP_LENGTH digit memakai pembangkit acak kriptografis.Dua keputusan pada langkah 10 dan 14 berjalan seiring: status orang tua atau wali selalu dibaca ulang dari Odoo YPII. Akibatnya, pencabutan kaitan orang tua dengan seorang siswa di Odoo YPII langsung berlaku pada permintaan berikutnya, tanpa perlu menunggu token sesi kedaluwarsa.
Jawaban "tidak ditemukan" untuk siswa di luar daftar anak pemegang sesi adalah pilihan yang disengaja. Membedakan "ditolak" dari "tidak ditemukan" akan mengonfirmasi bahwa siswa dengan pengenal tersebut memang ada — dan untuk data anak di bawah umur, mengonfirmasi keberadaan record milik keluarga lain sudah merupakan kebocoran.
Selain jalur OTP, layanan backend Parent Portal memiliki satu jalur masuk lain yang menukar pasangan alamat email dan satu password administrator bersama dengan sesi sebagai orang tua atau wali pemilik alamat email itu. Jalur ini disediakan untuk keperluan pengujian dan dukungan teknis, yaitu pihak yang tidak memiliki akses ke kotak masuk email orang tua.
ADMIN_LOGIN_ENABLED bernilai false, atau selama ADMIN_LOGIN_PASSWORD masih kosong, permintaan ke jalur ini dijawab sebagai tidak ditemukan — seolah-olah jalur itu tidak pernah ada.ADMIN_LOGIN_MAX_ATTEMPTS kegagalan berturut-turut, alamat IP itu dikunci selama ADMIN_LOGIN_LOCKOUT_SECONDS detik dan permintaannya dijawab dengan penolakan disertai keterangan waktu tunggu.Password administrator ini adalah satu rahasia untuk seluruh deployment, bukan kredensial per pengguna, dan pemegangnya dapat masuk sebagai orang tua atau wali mana pun yang punya anak terdaftar. Bila jalur ini pernah diaktifkan untuk keperluan pengujian, matikan kembali setelah selesai dan ganti passwordnya.
Seluruh perilaku otomasi ini ditentukan variabel lingkungan pada deployment Parent Portal, bukan oleh pengaturan di dalam Odoo YPII. Nilai pada tabel berikut adalah nilai yang berlaku pada stack Parent Portal YPII.
| Yang diatur | Variabel | Nilai bawaan | Akibat bila salah |
|---|---|---|---|
| Jumlah digit kode OTP | OTP_LENGTH |
6 |
Kode lebih pendek menurunkan kesulitan menebak |
| Masa berlaku satu kode | OTP_TTL_SECONDS |
300 (5 menit) |
Terlalu pendek membuat kode kedaluwarsa sebelum email tiba |
| Batas percobaan memasukkan kode | OTP_MAX_ATTEMPTS |
5 |
Terlalu longgar membuka peluang menebak berulang |
| Jeda minimum kirim ulang | OTP_RESEND_COOLDOWN_SECONDS |
60 |
Terlalu pendek membuka peluang pengiriman email beruntun |
| Identitas pengirim email kode OTP | OTP_EMAIL_FROM |
Portal Orang Tua YPII <noreply@ypiigroup.or.id> |
Kosong membuat email tiba atas nama akun layanan Odoo YPII, terbaca sebagai Administrator |
| Kunci penanda tangan sesi | JWT_SECRET |
kosong pada berkas contoh, wajib diisi saat deploy | Kosong membuat verifikasi kode berakhir dengan kegagalan layanan dan tidak seorang pun dapat masuk |
| Algoritma penanda tangan sesi | JWT_ALGORITHM |
HS256 |
Nilai yang tidak dikenal membuat penerbitan token gagal |
| Masa berlaku token akses | ACCESS_TOKEN_TTL_SECONDS |
900 (15 menit) |
Terlalu panjang memperbesar jendela penyalahgunaan token yang bocor |
| Masa berlaku token penyegar | REFRESH_TOKEN_TTL_SECONDS |
1209600 (14 hari) |
Terlalu panjang membuat sesi lama tetap hidup setelah perangkat berpindah tangan |
| Captcha pada permintaan kode | CAPTCHA_ENABLED, HCAPTCHA_SECRET, HCAPTCHA_SITE_KEY |
false, kosong, kosong |
Captcha dinyalakan tanpa secret membuat setiap permintaan kode ditolak; tanpa site key, widget tidak muncul di halaman masuk |
| Batas waktu memanggil hCaptcha | HCAPTCHA_TIMEOUT_SECONDS |
5 |
Terlalu panjang membuat halaman masuk menggantung saat hCaptcha lambat |
| Alamat layanan pemeriksa captcha | HCAPTCHA_VERIFY_URL |
https://api.hcaptcha.com/siteverify |
Alamat keliru membuat seluruh verifikasi captcha gagal |
| Sumber nama sekolah dan logo pada email | BRANDING_CONFIG_PATH |
/etc/portal/branding.json |
Berkas hilang atau rusak membuat kesiapan layanan gagal, sedangkan email tetap memakai identitas merek terakhir yang sah |
| Jalur masuk administrator | ADMIN_LOGIN_ENABLED, ADMIN_LOGIN_PASSWORD |
false, kosong |
Dinyalakan berarti membuka pintu masuk sebagai orang tua mana pun dengan satu password bersama |
| Penguncian jalur administrator | ADMIN_LOGIN_MAX_ATTEMPTS, ADMIN_LOGIN_LOCKOUT_SECONDS |
5, 900 (15 menit) |
Terlalu longgar membuka peluang menebak password administrator |
| Koneksi ke Odoo YPII | ODOO_BASE_URL, ODOO_DB, ODOO_CLIENT_ID, ODOO_CLIENT_SECRET |
alamat dan basis data instance Odoo YPII | Salah satu keliru membuat pencarian kontak dan pengiriman email sama-sama gagal |
Selain variabel di atas, mail server Odoo YPII (ir.mail_server) harus terkonfigurasi dan berstatus aktif. Bila mail server itu mati, kode OTP Parent Portal tidak punya jalur pengiriman lain untuk dijatuhi — tidak ada cadangan.
Dua prinsip memandu penanganan kegagalan pada otomasi Parent Portal ini: apa pun yang meragukan diperlakukan sebagai gagal, dan alasan kegagalannya tidak pernah sampai ke layar. Baik kontak yang tidak ketemu di Odoo YPII maupun email yang gagal terkirim berakhir pada tampilan yang sama bagi orang tua atau wali.
| Kegagalan | Yang dilihat pengguna | Yang sebenarnya terjadi |
|---|---|---|
| Alamat email tidak tercatat di Odoo YPII | Pesan keberhasilan umum; kode tidak pernah tiba | Tidak ada kode diterbitkan dan tidak ada email dikirim |
| Kontak ada di Odoo YPII tetapi bukan ayah, ibu, atau wali siswa mana pun | Pesan keberhasilan umum; kode tidak pernah tiba | Kontak tidak memenuhi syarat pembukaan sesi |
| Orang tua hanya punya nomor telepon, tanpa alamat email di Odoo YPII | Pesan keberhasilan umum; kode tidak pernah tiba | Tidak ada alamat tujuan pengiriman; sekolah harus mengisi email kontak di Odoo YPII |
| Mail server Odoo YPII mati atau menolak kiriman | Pesan keberhasilan umum; kode tidak pernah tiba | Kegagalan pengiriman ditelan dan hanya dicatat di log layanan backend Parent Portal |
| Layanan hCaptcha tidak terjangkau atau kehabisan waktu | Permintaan kode ditolak | Verifikasi captcha bersifat gagal-tertutup, sehingga dianggap tidak lolos |
JWT_SECRET kosong pada deployment |
Kode OTP tiba, tetapi memasukkannya berakhir dengan kegagalan layanan | Parent Portal menolak menerbitkan sesi yang tidak aman |
| Kode dimasukkan setelah masa berlaku habis atau setelah jatah percobaan habis | Kode ditolak | Kode sudah dibuang dari penyimpanan; orang tua harus meminta kode baru |
| Container backend Parent Portal di-restart sesudah kode dikirim | Kode ditolak walaupun baru saja tiba | Penyimpanan kode berada di memori proses dan ikut hilang saat restart |
| Kode diminta ulang sebelum jeda kirim ulang habis | Penolakan disertai keterangan waktu tunggu | Jeda kirim ulang menahan permintaan sebelum kontak dicari ke Odoo YPII |
Karena permintaan kode yang berhasil dan yang tidak menghasilkan tampilan yang sama, laporan "kode OTP tidak pernah sampai" tidak dapat dipakai untuk menyimpulkan bahwa alamat email pengguna tidak terdaftar. Penyebabnya bisa alamat tidak tercatat di Odoo YPII, kontak tidak terkait ke siswa mana pun, atau mail server Odoo YPII yang sedang bermasalah. Pemeriksaannya dilakukan di Odoo YPII dan pada log layanan backend Parent Portal, bukan dari layar orang tua.
Satu penolakan yang tidak bersifat umum adalah penolakan karena jeda kirim ulang. Penolakan itu hanya mungkin muncul untuk alamat email yang memang baru saja menerima kode, yaitu alamat yang lolos pemeriksaan kontak. Petugas dukungan yang memakai penolakan ini sebagai petunjuk keterdaftaran harus menyadari bahwa ia sedang membaca sinyal yang seharusnya tidak dipakai untuk itu.
Jejak otomasi ini tersebar di tiga tempat, dan tidak satu pun di antaranya terlihat dari layar orang tua.
/api/v1/ready) — inilah satu-satunya tempat kesalahan konfigurasi yang mematikan proses masuk menjadi terlihat. Endpoint ini menjalankan tiga pemeriksaan sekaligus, dan membalas status tidak siap bila salah satunya gagal: Odoo YPII tidak memiliki ir.mail_server yang aktif; captcha dinyalakan tetapi HCAPTCHA_SECRET kosong; atau BRANDING_CONFIG_PATH diisi tetapi berkasnya hilang atau rusak.Pada jalur OTP, alamat email sengaja tidak pernah dicatat ke log, termasuk saat pengiriman gagal, agar log layanan backend Parent Portal tidak berubah menjadi daftar alamat email orang tua siswa. Kode OTP juga tidak pernah dicatat ke log dalam bentuk apa pun. Pencatatan alamat email hanya terjadi pada jalur masuk administrator, yang hanya dapat dilewati pemegang password administrator.
Record pesan keluar kode OTP di Odoo YPII ditandai untuk menghapus dirinya sendiri begitu terkirim, dan penghapusan itu ikut membuang pesan terkaitnya. Karena itu email kode OTP yang berhasil terkirim tidak dapat ditelusuri kembali isinya di Odoo YPII, dan tidak ada arsip kode yang pernah diterbitkan. Dengan kata lain, kosongnya jejak email di Odoo YPII sama sekali tidak membuktikan bahwa kode OTP tidak pernah dikirimkan.