TimberID
Log In
  • 🌳Welcome to TimberID
  • Overview
    • 🌳Background
  • User Guide
    • πŸ”°Registering
    • πŸͺ΅Single Reference Sample + Import
      • ⁉️Import Errors
    • πŸ”ŽOrigin Verification
    • πŸ“€Exporting
    • 🌎Earth Engine API
    • ⚑Administration Guide
      • πŸ§‘β€πŸ€β€πŸ§‘Creating Organizations
      • 🚸Managing Users
    • πŸ“—Glossary
    • πŸ›Report an Issue
  • Architecture of TimberID
    • πŸ› οΈHigh Level Design
    • πŸ“šOpen Source Github Repositories
    • 🏯Detailed Design
      • 🌐Client
      • πŸ–₯️Server
      • πŸ—ΊοΈExternal integrations and maps
      • 🌎Earth Engine
      • πŸ‘©β€πŸ”¬Research Colabs
        • Data Ingestion
        • Model Training (Variational Inference)
        • Isoscape Generation
        • Validation of Isoscapes
    • 🌩️GCP Guide
      • πŸ“ˆAnalytics
      • πŸ’ΎDatabase Query Builder
      • πŸ’°Budget Alerts
      • πŸŒ„Domain Name Configuration
      • ⚠️Backups and Disaster Recovery
    • πŸš€Test Procedure for Production Release
  • Internal
    • πŸ”Internal Information
Powered by GitBook
On this page
  • FrontEnd Detail Design
  • Login, Signup and Password Reset
  • Confirming User Permissions
  • New user flow
  • Lists (Species, Municipalities)
  • Localization
  • Deploying Front End for Testing and Production

Was this helpful?

  1. Architecture of TimberID
  2. Detailed Design

Client

PreviousDetailed DesignNextServer

Last updated 1 year ago

Was this helpful?

FrontEnd Detail Design

The Client consists of the Front End, which is written in Typescript and hosted using . This is a Firebase web application and directly reads and writes to the underlying backend .

The Front End is open sourced at .

The client contains the following functionality

Login, Signup and Password Reset

TimberID uses built in Firebase functionality to sign up with Google or email/password.

    function attemptSignIn() {
        setErrorText({email: '', password: ''})
        setSubmitIsLoading(true);
        const email = (document.getElementById('email') as HTMLInputElement).value;
        const password = (document.getElementById('password') as HTMLInputElement).value;
        console.log('username: ' + email + ' password: ' + password);
        signInWithEmailAndPassword(auth, email, password)
            .then((userCredential) => {
                // Signed in 
                const user = userCredential.user;
                console.log('signed in');
                router.push('/samples');
            })

signInWithEmailAndPassword is built into Firebase as are GoogleAuthProvider.

Users must choose an Organization when they sign in, which determines what data they see.

Confirming User Permissions

User data and permissions are stored in the "users" collection in Firestore. Each user has their own document where the document ID is the user's Firebase auth user ID making it easy to know which document to fetch when checking which permissions a user has. The following data is stored for each user:

{
 date_added: string
 email: string
 name: string // First and last name 
 org: string // The org ID number 
 org_name: string // The org name
 role: string // Can only be either "member", "admin" or "site_admin"
}

We know what a user's permissions are based on the role they have. A member can only create/view/edite samples in their organization. An admin is an org admin and has full control of all aspects of their organization including approving new members, promoting other members to admin status, and removing members from their organization. A site_admin has full control of all aspects of the site including approving any member request, removing any member from any org, viewing any sample created on the application, and promoting members or admins to site_admin status.

These roles must be checked when a user attempts to access a page that is meant only for specific user roles. For example the following snippet shows how to check if a user is an admin or site_admin and forwards them away from the page if they aren't.

onAuthStateChanged(auth, (user) => {
    if (!user) {
        router.push('/login');
    } else {
        const userDocRef = doc(db, "users", user.uid);
        getDoc(userDocRef).then((docRef) => {
            if (docRef.exists()) {
                const docData = docRef.data();
                    if (docData.role !== 'admin' && docData.role !== 'site_admin') {
                        router.push('/samples');
                    }
                    setUserData(docRef.data() as UserData);
                }
            }).catch((error) => {
                console.log(error)
            });
        }
    });

Even if a user falls through this test without the correct role, the Firestore security rules will make sure they don't see any privileged information however it is best if they don't have access to the pages in the first place. Only an admin has permissions to update the data in a user's user document.

New user flow

When a new user attempts to join the application their data is added as a new document to the "new_users" collection with the new users firebase auth user ID as the document ID.

When an org admin goes to the "Sign up requests" page, the "new_users" collection is searched for users attempting to join the same organization as the admin and are shown to the admin to be approved/rejected. If a user is approved, a new entry is made for them in the "users" collection with the data shown above.

If a new user attempts to create a new organization when they sign up, their data is added to the "new_orgs" document in the "new_users" collection. These requests are only shown to the site_admin to be approved/rejected.

Lists (Species, Municipalities)

It's very likely that the list for Species or Municipalities will need to be updated in the future. These can be found below.

Data Source
Location
Original Source

Species

State List

List of states in Brazil

Municipalities

List of valid municipalities in Brazil

Localization

There also may be cases where the text had never been translated at all. If that happens, you can follow the pattern of another localized snippet and reference translations.json.

    <div className='input-text-field-wrapper half-width'>
        <TextField
            size='small'
            fullWidth
            id="mean_annual_precipitation"
            name="mean_annual_precipitation"
            label={t('meanAnnualPrecipitation')}
            sx={style}
            onChange={handleChange}
            value={formData.mean_annual_precipitation}
        />
    </div>

Deploying Front End for Testing and Production

Before merging a PR to Main, you should have unit tests and manually test with the generated hosted url github actions created for you.

  • Merging code into the PRD branch will automatically update the production environment.

Domain Name Management and Custom Domain Names

Currently, TimberID.org has two domains

Domain Name
Management Url
Description

TimerID.org

Production website automatically sync'd to the PRD branch

Test.TimberID.org

Test branch with separate database and functions, automatically sync'd to the main branch

Security Rules are described in depth in the section.

Originally obtained from imaflora. An outstanding item is to query this data dynamically from

Translation to Portuguese may be incorrect as the original source of TimberID is english. You can find all translated snippets .

For example, meanAnnualPrecipitation is localized in via t('meanAnnualPrecipitation'):

Add your string to for every language and then use the style above to pull it from the localization table.

You should first install the to manage deployments. This tool allows you to .

The github repository has github actions already configured to generate live previews URLS for all PRs. You can find out more about how these actions were configured .

Merging code into the Main branch will automatically update the development environment: .

Before merging code from Main into the PRD branch, you should run through the on test.timberid.org, which should have latest source from the Main branch.

🏯
🌐
login.tsx
Server
here
sample_data_input
translations.json
firebase CLI
view and test your changes before going live
here
test.timberid.org
manual test procedures
species_list.tsx
Brazilian Flora
states_list.tsx
municipalities_list.tsx
https://domains.google.com/registrar/timberid.org/dns?authuser=0&hl=en-US
https://domains.google.com/registrar/timberid.org/dns?authuser=0&hl=en-US
Firebase Hosting
Firestore
the tnc-br github organization
Drawing