Lewati ke konten

Masking dan redaksi

Refund untuk NIK ************1349, HP +62*******171, rekening ******7890.

Jalan di browser kamu.

mask menjaga NIK, NPWP, nomor HP, dan nomor identitas lain supaya tidak bocor ke log, layar, atau tiket layanan. Berguna untuk prinsip minimalisasi data di UU Pelindungan Data Pribadi (UU PDP).

Go TypeScript Hasil
mask.NIK(s) mask.nik(s) Hanya 4 digit terakhir terlihat
mask.NPWP(s) mask.npwp(s) Hanya 4 digit terakhir terlihat
mask.NIP(s) mask.nip(s) Hanya 4 digit terakhir terlihat
mask.NISN(s) mask.nisn(s) Hanya 4 digit terakhir terlihat
mask.Account(s) mask.account(s) Hanya 4 digit terakhir terlihat
mask.Phone(s) mask.phone(s) +62 dan 3 digit terakhir terlihat
mask.Text(s) mask.text(s) Teks bebas dengan setiap deret 10 digit atau lebih di-mask
mask.Redact(v) mask.redact(v) Salinan objek, array, atau nilai yang sudah diredaksi
mask.NewHandler(next) Khusus Go Handler log/slog yang meredaksi sebelum next

Fungsi per jenis sama dengan nik.Mask, phone.Mask, dan seterusnya, dikumpulkan di satu tempat.

Text mencari angka yang mirip nomor identitas (10 digit atau lebih, boleh dengan pemisah umum) dan me-mask masing-masing sesuai jenisnya. Nomor HP menyisakan +62 dan 3 digit, lainnya 4 digit. Pemindaiannya linear dan menerima sampai 1 MiB (MaxText / MAX_TEXT). Input yang lebih panjang gagal dengan length.

Redact mengembalikan salinan di mana setiap string dan key melewati Text (string di atas 1 MiB menjadi [redacted]) dan setiap bilangan bulat 10 digit atau lebih di-mask. Fungsi ini tidak pernah mengubah input, tidak pernah memanggil getter (TypeScript mengembalikan [Getter]), melewati key __proto__, constructor, dan prototype, mengganti referensi melingkar dengan [Circular], dan berhenti di kedalaman 32 ([MaxDepth]).

Di Go, Redact menerima nilai apa pun. Struct menjadi map dengan key nama JSON-nya (field bertag json:"-" dan field tak terekspor dibuang), map, slice, array, dan pointer ditelusuri, []byte diperlakukan sebagai teks, dan time.Time dibiarkan. Nilai yang tidak bisa diperiksa, seperti fungsi dan channel, menjadi [redacted] alih-alih diteruskan apa adanya.

package main
import (
"encoding/json"
"fmt"
"github.com/haikalmumtaz233/nusaindex/mask"
)
func main() {
fmt.Println(mask.NIK("7502010706599583"))
fmt.Println(mask.NPWP("0029736758100600"))
fmt.Println(mask.Phone("0859-5257-171"))
fmt.Println(mask.NIP("198812272008092553"))
fmt.Println(mask.NISN("6299763315"))
fmt.Println(mask.Account("1234567890"))
line, err := mask.Text("customer 7502010706599583 called from 085952571710")
if err == nil {
fmt.Println(line)
}
record := map[string]any{
"name": "Budi",
"nik": "7502010706599583",
"notes": []any{"call 085952571710"},
}
safe, err := json.Marshal(mask.Redact(record))
if err == nil {
fmt.Println(string(safe))
}
}
Keluaran
************9583
************0600
+62*******171
**************2553
******3315
******7890
customer ************9583 called from +62********710
{"name":"Budi","nik":"************9583","notes":["call +62********710"]}

NewHandler membungkus slog.Handler apa pun dan meredaksi pesan, setiap key dan grup, serta setiap nilai string, angka, dan slog.Any (lewat Redact) sebelum record diteruskan.

package main
import (
"log/slog"
"os"
"github.com/haikalmumtaz233/nusaindex/mask"
)
func main() {
plain := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
ReplaceAttr: func(_ []string, a slog.Attr) slog.Attr {
if a.Key == slog.TimeKey {
return slog.Attr{}
}
return a
},
})
logger := slog.New(mask.NewHandler(plain))
logger.Info("signup 7502010706599583", slog.String("phone", "085952571710"))
}
Keluaran
level=INFO msg="signup ************9583" phone=+62********710