CREATE TABLE
    IF NOT EXISTS passkeys(
        id uuid PRIMARY KEY NOT NULL,
        user_id BIGINT NOT NULL,
        friendly_name TEXT NOT NULL,
        deleted_at BIGINT,
        created_at bigint NOT NULL DEFAULT now_utc_micro_seconds(),

CONSTRAINT fk_passkeys_user_id FOREIGN KEY(user_id) REFERENCES users(user_id) ON DELETE CASCADE
);

CREATE TABLE
    IF NOT EXISTS passkey_credentials(
        passkey_id uuid PRIMARY KEY NOT NULL,

        credential_id TEXT NOT NULL UNIQUE,

-- credential info

-- []byte data will be encoded in b64 before being inserted into the DB

-- fields that are are arrays will be comma separated strings

-- structs will be encoded into JSON before being inserted into DB (they don't need to be queried anyway)

public_key TEXT NOT NULL,
-- binary data
attestation_type TEXT NOT NULL,
authenticator_transports TEXT NOT NULL,
-- array
credential_flags TEXT NOT NULL,
-- struct
authenticator TEXT NOT NULL,
-- struct

created_at bigint NOT NULL DEFAULT now_utc_micro_seconds(),

CONSTRAINT fk_passkey_credentials_passkey_id FOREIGN KEY(passkey_id) REFERENCES passkeys(id) ON DELETE CASCADE
);

CREATE TABLE
    IF NOT EXISTS webauthn_sessions(
        id uuid PRIMARY KEY NOT NULL,

challenge TEXT NOT NULL UNIQUE,

user_id BIGINT NOT NULL,
-- this is meant to be []byte but we'll store it normally for us
allowed_credential_ids TEXT NOT NULL,
-- this is [][]byte, but we'll encode it to b64 to store in db
expires_at bigint NOT NULL,
-- this is time.Time but we'll encode it into unix

user_verification_requirement TEXT NOT NULL,
extensions TEXT NOT NULL,
-- this is a map[string]interface{} but we'll just store it as json

created_at bigint NOT NULL DEFAULT now_utc_micro_seconds(),

CONSTRAINT fk_webauthn_sessions_user_id FOREIGN KEY(user_id) REFERENCES users(user_id) ON DELETE CASCADE
);