Supabase Auth and Prisma Integration


Why This Integration?

Integrating Supabase Auth with Prisma offers a robust solution for managing user authentication alongside extended user profiles within a single application. While Supabase Auth provides a secure and scalable authentication system, it limits user-related data to basic information. By synchronizing auth.users with a custom public.users table managed by Prisma, we gain the flexibility to extend user profiles with additional fields and maintain referential integrity through foreign keys, enhancing our application’s data model and capabilities.

How It Works

Overview

This integration automatically mirrors entries from Supabase’s auth.users table to a custom public.users table in our database. This synchronization allows us to extend the user model with additional information (e.g., user settings) and establish foreign key relationships with other tables, all managed through Prisma.

Step 1: Setting Up Prisma

Define your User model in schema.prisma to mirror Supabase’s auth.users and include additional fields:

model User {
  id        String   @id @default(uuid()) @map("id")
  email     String   @unique
  settings  Json?
  createdAt DateTime @default(now()) @map("created_at")
  updatedAt DateTime @updatedAt @map("updated_at")

  @@map("users")
}


Step 2: Creating a PostgreSQL Trigger in Supabase

Implement a PostgreSQL trigger within Supabase to sync every new or updated entry in auth.users with public.users:

CREATE OR REPLACE FUNCTION public.handle_user_sync()
RETURNS TRIGGER AS $$
BEGIN
  IF TG_OP = 'INSERT' THEN
    INSERT INTO public.users (id, email, created_at, updated_at)
    VALUES (NEW.id, NEW.email, NOW(), NOW())
    ON CONFLICT (id) DO NOTHING;
    RETURN NEW;
  ELSIF TG_OP = 'UPDATE' THEN
    UPDATE public.users
    SET email = NEW.email, updated_at = NOW()
    WHERE id = NEW.id;
    RETURN NEW;
  END IF;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER sync_auth_users
AFTER INSERT OR UPDATE ON auth.users
FOR EACH ROW EXECUTE FUNCTION public.handle_user_sync();

Step 3: Managing User Data with Prisma

With the synchronization in place, use Prisma to manage public.users, adding any additional user-related data or settings as needed.

Security and Performance

  • Ensure sensitive user information is securely handled and access-controlled.
  • Monitor the performance impact of the database trigger, adjusting as necessary.

Testing

Before deployment, thoroughly test the integration in a development environment to confirm that user data syncs correctly and that your application logic functions as expected.

Conclusion

This README outlines the integration of Supabase Auth with Prisma for enhanced user data management. By leveraging the strengths of both platforms, we create a powerful foundation for building sophisticated and scalable applications.

Setting Up a PXE Boot Server with netboot.xyz Using Dnsmasq on Ubuntu

Introduction

In this blog post, we’ll guide you through setting up a PXE (Preboot Execution Environment) boot server with netboot.xyz on Ubuntu, leveraging dnsmasq for a simplified setup. This configuration allows networked machines to boot various operating systems from a single server, ideal for labs, data centers, or rapid OS deployments.

What is PXE Booting?

PXE booting enables computers to load and boot an operating system from a network server. This method is extensively used for system installations, recovery, and testing different operating systems without local storage.

Why netboot.xyz?

netboot.xyz is an open-source initiative that simplifies the PXE boot process with a dynamic boot menu, allowing selection from a range of operating systems and tools. This capability is crucial for efficient network and system management.

Why dnsmasq?

It supports DHCP and TFTP services, which is a more streamlined approach for setting up a PXE boot environment. Alternatively you can use isc-dhcp-server and tftpd-hpa.

Prerequisites

  • An Ubuntu 22.04 server (referred to as pxehost).
  • Basic Linux and network configuration knowledge.
  • Root or sudo privileges on the server.

Step 1: Installing Dnsmasq

Dnsmasq serves as both the DHCP and TFTP server, streamlining the setup. Install it using:

sudo apt-get update sudo apt-get install -y dnsmasq

Step 2: Configuring Dnsmasq

Edit /etc/dnsmasq.conf to include DHCP and TFTP settings:

sudo nano /etc/dnsmasq.conf

Add the following configuration:

# DHCP Settings dhcp-range=192.168.2.30,192.168.2.200,255.255.255.0,24h dhcp-option=option:router,192.168.2.1 dhcp-option=option:dns-server,localhost,1.1.1.1 dhcp-boot=netboot.xyz.kpxe # TFTP Settings enable-tftp tftp-root=/var/lib/tftpboot

Restart dnsmasq to apply the changes:

sudo systemctl restart dnsmasq

Step 3: Setting Up netboot.xyz

Download the netboot.xyz boot files into the TFTP directory:

sudo mkdir -p /var/lib/tftpboot cd /var/lib/tftpboot sudo wget https://boot.netboot.xyz/ipxe/netboot.xyz.kpxe sudo wget https://boot.netboot.xyz/ipxe/netboot.xyz.efi

Step 4: Testing the PXE Boot and Troubleshooting

Test the PXE boot on a client machine. If issues arise, check the dnsmasq logs:

bashCopy code

grep dnsmasq /var/log/syslog

For TFTP issues, attempt a manual TFTP download from another machine:

bashCopy code

tftp 192.168.2.5 get netboot.xyz.kpxe quit

Confirm that the TFTP server is correctly configured and accessible.

Conclusion

Using dnsmasq for PXE booting with netboot.xyz offers a streamlined, efficient approach to network booting. This setup is ideal for environments requiring quick and versatile OS deployments and system management.

How to Set Up Split DNS Configuration on macOS for Specific Domains

Introduction

For someone who needs to direct traffic for specific domains to a particular server, setting up a split DNS configuration on macOS is a straightforward way to achieve this. Today, we’ll explore how to resolve all domains ending in .sf through a designated DNS server at 172.16.7.1.

What is Split DNS?

Split DNS is a configuration where DNS queries for specific domains are handled by a designated DNS server, while all other queries go through the default DNS settings. This setup is particularly useful in development environments or for internal network purposes.

Setting Up Split DNS on macOS

To set up a split DNS configuration on macOS, we’ll use the built-in resolver feature. Here’s how:

Step 1: Create a Resolver Directory

Open Terminal and create a directory for resolver if it doesn’t already exist:

bashCopy code

sudo mkdir -v /etc/resolver

Step 2: Create a Resolver File

In /etc/resolver/, create a file named sf:

bashCopy code

sudo nano /etc/resolver/sf

Add the following line to specify the DNS server:Copy code

nameserver 172.16.7.1

Save and exit the editor.

Step 3: Flush DNS Cache

Flush the DNS cache to ensure your changes take effect:

bashCopy code

sudo dscacheutil -flushcache sudo killall -HUP mDNSResponder

Testing Your Configuration

After setting up, test it with nslookup or dig:

bashCopy code

nslookup example.sf

The server should now point to 172.16.7.1.

Troubleshooting

If the DNS queries are still being resolved by the default server (like Google’s 8.8.8.8), here are some things to check:

  • Correct File and Syntax: Ensure /etc/resolver/sf is correctly set up.
  • Permissions: Verify the file’s permissions and ownership.
  • Direct Testing: Query the DNS server directly with dig @172.16.7.1 example.sf.
  • Network Connectivity: Confirm that 172.16.7.1 is reachable and correctly configured.
  • Restart Network Services: Sometimes, toggling network services can help.
  • Reboot: When in doubt, reboot!

Resolving DNS Issues on a VPN-Connected Ubuntu Machine

Introduction

Recently, I encountered a challenging issue while working with a machine (10.7.0.12) connected via a WireGuard VPN, with the host at 10.7.0.1. The core problem was a lack of internet access, despite a functioning network connection. This blog post details the steps I took to diagnose and resolve this DNS-related issue.

The Problem

While SSH’d into 10.7.0.12, I realized I couldn’t access the internet. The first hint of trouble came when I tried pinging Google:

ping google.com
ping: google.com: Temporary failure in name resolution

This error pointed towards a potential DNS issue, especially since my SSH connection was active, indicating that the network was operational.

Diagnosing the Issue

To further investigate, I ran nslookup to check DNS resolution:

nslookup google.com
;; communications error to 10.7.0.1#53: connection refused
Server:        127.0.0.53
Address:    127.0.0.53#53

** server can't find google.com: SERVFAIL

These results confirmed that DNS queries to 10.7.0.1 were being refused, despite the machine itself being reachable (verified by pinging 10.7.0.1).

Resolving the Issue

Step 1: Local DNS Test on the Host

On the host machine (10.7.0.1), I tested DNS resolution locally with nslookup google.com 127.0.0.1, which worked fine. This hinted that the issue might be related to a firewall configuration.

Step 2: Checking and Updating Firewall Settings

Using ufw status numbered, I discovered that the IP I was using wasn’t on the allowlist. After adding it and restarting the dnsmasq service, I was able to resolve DNS queries from 10.7.0.12.

Step 3: Configuring Conditional DNS Forwarding

However, a new requirement emerged: I needed to ensure that only DNS queries for domains ending in .ds were forwarded to 10.7.0.1. To achieve this, I configured dnsmasq on 10.7.0.12:

echo 'server=/ds/10.7.0.1' | sudo tee -a /etc/dnsmasq.conf
sudo systemctl restart dnsmasq

Note you need to have server=8.8.8.8 or something as well in order to resolve dns normally. Otherwise 127.0.0.53#53 cannot resolve DNS.

Step 4: Verifying the Configuration

Finally, I verified that DNS queries for .ds domains were correctly directed to 10.7.0.1, while others were handled locally on 10.7.0.12. This was done using dig or nslookup with different domain types.

Conclusion

In this case, a combination of firewall adjustment and DNS forwarding configuration resolved the internet access problem.

Convert cardano Bech32 address to stake key

Cardano payment addresses are bech32 encoded since Shelly. These addresses can be decoded in python

from typing import Optional
import bech32
import binascii


def resolve_addr2stake_py(address: str) -> Optional[str]:
    hrp, by = bech32.bech32_decode(address)
    if hrp != 'addr':
        return None
    words = bech32.convertbits(by, 5, 8, False)
    res = ''
    for w in words:
        res = f'{res}{format(w, "x").zfill(2)}'
    mainnet_addr = f'e1{res[-56:]}'
    array = binascii.unhexlify(mainnet_addr)
    words = [x for x in array]
    bech32_words = bech32.convertbits(words, 8, 5)
    bech32_addr = bech32.bech32_encode('stake', bech32_words)
    return bech32_addr

You can confirm this works by

address = 'addr1qxdvcswn0exwc2vjfr6u6f6qndfhmk94xjrt5tztpelyk4yg83zn9d4vrrtzs98lcl5u5q6mv7ngmg829xxvy3g5ydls7c76wu'

resolve_addr2stake_py(address)

Out: 'stake1uxyrc3fjk6kp343gznlu06w2qddk0f5d5r4znrxzg52zxlclk0hlq'