GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com β€” GitHub - ilhamnoerr95/fe-authenticator

BranchesTags
Open more actions menu

Latest commit

 

History

6 Commits
6 Commits

Folders and files

NameName
Last commit message
Last commit date
.agents/agents
.agents/agents
 
 
.github/agents
.github/agents
 
 
.tamagui
.tamagui
 
 
.vscode
.vscode
 
 
app
app
 
 
assets/images
assets/images
 
 
components
components
 
 
constants
constants
 
 
contexts
contexts
 
 
hooks
hooks
 
 
lib
lib
 
 
scripts
scripts
 
 
services
services
 
 
.env.example
.env.example
 
 
.gitignore
.gitignore
 
 
README.md
README.md
 
 
app.json
app.json
 
 
babel.config.js
babel.config.js
 
 
eslint.config.js
eslint.config.js
 
 
package.json
package.json
 
 
pnpm-lock.yaml
pnpm-lock.yaml
 
 
pnpm-workspace.yaml
pnpm-workspace.yaml
 
 
tamagui.build.ts
tamagui.build.ts
 
 
tamagui.config.ts
tamagui.config.ts
 
 
themes.ts
themes.ts
 
 
tsconfig.json
tsconfig.json
 
 

Repository files navigation

FE Authenticator

Aplikasi TOTP (Time-based One-Time Password) authenticator yang dibangun dengan React Native + Expo. Mirip seperti Google Authenticator β€” menampilkan kode OTP 6-digit yang berubah setiap 30 detik, lengkap dengan countdown ring dan fitur tap-to-copy.

Tech Stack

  • Framework: Expo (SDK 54) dengan Expo Router (file-based routing)
  • UI Library: Tamagui (2.0.0-rc.41)
  • Language: TypeScript
  • OTP Generation: otplib (TOTP)
  • Secure Storage: expo-secure-store (native) / localStorage (web)
  • Animation: react-native-reanimated
  • Testing: Jest + jest-expo
  • Package Manager: pnpm

Fitur

  • πŸ” Autentikasi β€” Login & Register dengan email/password, terhubung ke backend NestJS
  • πŸ”‘ TOTP Code Generation β€” Generate kode OTP 6-digit setiap 30 detik
  • ⏱️ Countdown Ring β€” Visual countdown circular yang menunjukkan sisa waktu kode aktif
  • πŸ“‹ Tap to Copy β€” Tap kode untuk copy ke clipboard dengan haptic feedback
  • πŸŒ™ Dark/Light Mode β€” Theme toggle dengan dukungan system preference
  • πŸ“± Multi-platform β€” Berjalan di iOS, Android, dan Web
  • πŸ”’ Secure Token Storage β€” Token tersimpan di SecureStore (native) atau localStorage (web)

Struktur Projek

app/                  # Routes (file-based routing)
β”œβ”€β”€ _layout.tsx       # Root layout (providers, navigation)
β”œβ”€β”€ index.tsx         # Home screen (OTP list)
β”œβ”€β”€ login.tsx         # Login screen
└── register.tsx      # Register screen

components/           # Reusable UI components
β”œβ”€β”€ auth-form.tsx     # Form login/register
β”œβ”€β”€ brand.tsx         # Brand/logo component
β”œβ”€β”€ theme-toggle.tsx  # Dark/light mode toggle
└── ...

contexts/             # React Context providers
β”œβ”€β”€ auth-context.tsx  # Auth state management
└── theme-context.tsx # Theme preference management

services/             # API & storage layer
β”œβ”€β”€ api.ts            # HTTP client untuk backend NestJS
└── storage.ts        # Abstraksi secure storage

constants/            # App-wide constants
β”œβ”€β”€ colors.ts         # Color palette
β”œβ”€β”€ totp.ts           # TOTP config (period, warn threshold)
└── validation.ts     # Password policy rules

lib/                  # Utility functions
└── utils.ts          # Password validation, color helper, OTP formatting

hooks/                # Custom React hooks
β”œβ”€β”€ use-theme-color.ts
└── use-color-scheme.ts

Alur Aplikasi

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        App Launch                                β”‚
β”‚                            β”‚                                    β”‚
β”‚                    β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”                           β”‚
β”‚                    β”‚ Animated Splash β”‚                           β”‚
β”‚                    β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜                           β”‚
β”‚                            β”‚                                    β”‚
β”‚                    β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”                           β”‚
β”‚                    β”‚  Auth Check    β”‚                           β”‚
β”‚                    β”‚ (SecureStore)  β”‚                           β”‚
β”‚                    β””β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”˜                           β”‚
β”‚                        β”‚       β”‚                                β”‚
β”‚              token ada β”‚       β”‚ token kosong                   β”‚
β”‚                        β”‚       β”‚                                β”‚
β”‚                β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”  β”Œβ”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                    β”‚
β”‚                β”‚  Home /  β”‚  β”‚  Login     β”‚                    β”‚
β”‚                β”‚  OTP Listβ”‚  β”‚  Screen    β”‚                    β”‚
β”‚                β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”˜                    β”‚
β”‚                                 β”‚     β”‚                        β”‚
β”‚                        login    β”‚     β”‚ tap "Sign up"          β”‚
β”‚                        berhasil β”‚     β”‚                        β”‚
β”‚                                 β”‚   β”Œβ”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”‚
β”‚                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚  Register  β”‚            β”‚
β”‚                β”‚                    β”‚  Screen    β”‚            β”‚
β”‚                β”‚                    β””β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β”‚
β”‚                β”‚                       β”‚                       β”‚
β”‚                β”‚              register berhasil                β”‚
β”‚                β”‚              (redirect ke login)              β”‚
β”‚                β”‚                       β”‚                       β”‚
β”‚                β”‚              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”                    β”‚
β”‚                β”‚              β”‚  Login    β”‚                    β”‚
β”‚                β”‚              β”‚  Screen   β”‚                    β”‚
β”‚                β”‚              β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜                    β”‚
β”‚                β”‚                   β”‚ login berhasil            β”‚
β”‚                β–Ό                   β–Ό                            β”‚
β”‚         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                       β”‚
β”‚         β”‚      Home Screen (index)     β”‚                       β”‚
β”‚         β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚                       β”‚
β”‚         β”‚  β”‚ Header: Brand + Logout  β”‚ β”‚                       β”‚
β”‚         β”‚  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚                       β”‚
β”‚         β”‚  β”‚ OTP Card (Google)       β”‚ β”‚                       β”‚
β”‚         β”‚  β”‚  β€’ Kode 6-digit         β”‚ β”‚                       β”‚
β”‚         β”‚  β”‚  β€’ Countdown Ring       β”‚ β”‚                       β”‚
β”‚         β”‚  β”‚  β€’ Tap β†’ Copy           β”‚ β”‚                       β”‚
β”‚         β”‚  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚                       β”‚
β”‚         β”‚  β”‚ OTP Card (GitHub)       β”‚ β”‚                       β”‚
β”‚         β”‚  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚                       β”‚
β”‚         β”‚  β”‚ OTP Card (Email)        β”‚ β”‚                       β”‚
β”‚         β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚                       β”‚
β”‚         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Detail Alur

  1. App Launch β†’ Menampilkan animated splash screen, lalu mengecek token di SecureStore/localStorage.
  2. Belum login β†’ Redirect otomatis ke /login.
  3. Login Screen β†’ User mengisi email & password β†’ hit API POST /api/v1/auth/login β†’ token disimpan di SecureStore β†’ redirect ke Home.
  4. Register Screen β†’ User mengisi email & password (harus memenuhi password policy) β†’ hit API POST /api/v1/auth/register β†’ tampilkan notifikasi sukses β†’ redirect ke Login.
  5. Home Screen (Authenticated) β†’ Menampilkan daftar kode OTP 6-digit yang di-generate setiap 30 detik menggunakan TOTP. Setiap kode memiliki countdown ring dan bisa di-tap untuk copy ke clipboard (dengan haptic feedback di native).
  6. Logout β†’ Hapus token dari SecureStore β†’ redirect kembali ke Login.

State Management Flow

AuthProvider (Context)
β”œβ”€β”€ initializing: true β†’ Loading spinner
β”œβ”€β”€ isAuthenticated: false β†’ Redirect ke /login
└── isAuthenticated: true β†’ Tampilkan Home
    β”œβ”€β”€ login(email, pw) β†’ API call β†’ simpan token β†’ set isAuthenticated = true
    β”œβ”€β”€ register(email, pw) β†’ API call β†’ redirect ke login (TANPA auto-login)
    └── logout() β†’ hapus token β†’ set isAuthenticated = false

Prasyarat

  • Node.js (v18+)
  • pnpm
  • Backend NestJS yang berjalan (lihat konfigurasi API di bawah)

Instalasi

  1. Clone repository dan install dependencies:

    pnpm install
  2. Salin file environment:

    cp .env.example .env
  3. Edit .env sesuai platform yang digunakan:

    # Web / iOS simulator
    EXPO_PUBLIC_API_URL=http://localhost:3000
    
    # Android emulator
    EXPO_PUBLIC_API_URL=http://10.0.2.2:3000
    
    # Physical device (ganti dengan IP LAN mesin kamu)
    EXPO_PUBLIC_API_URL=http://192.168.1.10:3000

Menjalankan Aplikasi

# Start Expo dev server
pnpm start

# Langsung buka di platform tertentu
pnpm ios       # iOS Simulator
pnpm android   # Android Emulator
pnpm web       # Browser

Testing

pnpm test

Linting

pnpm lint

Konfigurasi Backend

Aplikasi ini terhubung ke backend NestJS dengan endpoint:

  • POST /api/v1/auth/register β€” Registrasi user baru
  • POST /api/v1/auth/login β€” Login user

Backend harus berjalan dan accessible sesuai EXPO_PUBLIC_API_URL yang dikonfigurasi.

Password Policy

Password harus memenuhi kriteria berikut:

  • Minimal 8 karakter
  • Mengandung huruf besar (A-Z)
  • Mengandung huruf kecil (a-z)
  • Mengandung angka (0-9)
  • Mengandung karakter spesial

Reset Project

Untuk memulai dari awal (memindahkan starter code ke app-example):

pnpm reset-project

About

No description, website, or topics provided.

Resources

Readme
Activity

Stars

1 star

Watchers

0 watching

Forks

0 forks
Report repository

Releases

Packages

Contributors

Languages

You are visitor 01402520 β€” GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800Γ—600. No cookies required.