44 lines
14 KiB
TypeScript
44 lines
14 KiB
TypeScript
/**
|
|
* Canonical 17-table Better-Auth SurrealQL schema.
|
|
*
|
|
* --- BEGIN BETTER_AUTH_SURREAL_SCHEMA ---
|
|
* Source: /mnt/f/surrealdb/surql/features/02-auth/02-better-auth.surql
|
|
* Byte-for-byte mirror of the canonical schema (modulo line-ending
|
|
* normalisation). Schema version moves in lockstep with this package
|
|
* version — pin them together.
|
|
* --- END BETTER_AUTH_SURREAL_SCHEMA ---
|
|
*/
|
|
|
|
import {
|
|
BETTER_AUTH_SURREALDB_CODES,
|
|
BetterAuthSurrealError,
|
|
} from "../error-codes/error-codes.js";
|
|
import type { SurrealClientView } from "../types/adapter.js";
|
|
|
|
export const BETTER_AUTH_SURREAL_SCHEMA: string =
|
|
"-- User table definition\n-- As user was created prior using snake case, we'll conform to that.\n-- We must, however, create the user table first using user.surql\nDEFINE FIELD OVERWRITE emailVerified ON user TYPE bool DEFAULT false;\n-- might scrap this, don't see a purpose, as we're changing to firstName in config\nDEFINE FIELD OVERWRITE name ON user TYPE option<string>;\nDEFINE FIELD OVERWRITE image ON user TYPE option<string>;\n\n-- Session table definition\nDEFINE TABLE OVERWRITE session SCHEMAFULL;\nDEFINE FIELD OVERWRITE userId ON session TYPE record<user> ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE expiresAt ON session TYPE option<datetime>;\nDEFINE FIELD OVERWRITE token ON session TYPE option<string>;\nDEFINE FIELD OVERWRITE ipAddress ON session TYPE option<string>;\nDEFINE FIELD OVERWRITE userAgent ON session TYPE option<string>;\nDEFINE FIELD OVERWRITE impersonatedBy ON session TYPE option<string>;\nDEFINE FIELD OVERWRITE activeOrganizationId ON session TYPE option<string>;\nDEFINE FIELD OVERWRITE activeTeamId ON session TYPE option<string>;\nDEFINE FIELD OVERWRITE createdAt ON session TYPE datetime DEFAULT time::now() VALUE $before OR time::now();\nDEFINE FIELD OVERWRITE updatedAt ON session TYPE datetime DEFAULT time::now() VALUE time::now();\n\n-- Account table definition\nDEFINE TABLE OVERWRITE account SCHEMAFULL;\nDEFINE FIELD OVERWRITE userId ON account TYPE string;\nDEFINE FIELD OVERWRITE providerId ON account TYPE string;\nDEFINE FIELD OVERWRITE accountId ON account TYPE string;\nDEFINE FIELD OVERWRITE accessToken ON account TYPE option<string>;\nDEFINE FIELD OVERWRITE refreshToken ON account TYPE option<string>;\nDEFINE FIELD OVERWRITE idToken ON account TYPE option<string>;\nDEFINE FIELD OVERWRITE password ON account TYPE string;\nDEFINE FIELD OVERWRITE accessTokenExpiresAt ON account TYPE option<datetime>;\nDEFINE FIELD OVERWRITE refreshTokenExpiresAt ON account TYPE option<datetime>;\nDEFINE FIELD OVERWRITE scope ON account TYPE option<string>;\nDEFINE FIELD OVERWRITE createdAt ON account TYPE datetime DEFAULT time::now() VALUE $before OR time::now();\nDEFINE FIELD OVERWRITE updatedAt ON account TYPE datetime DEFAULT time::now() VALUE time::now();\n\n-- Verification table definition\nDEFINE TABLE OVERWRITE verification SCHEMAFULL;\nDEFINE FIELD OVERWRITE createdAt ON verification TYPE datetime DEFAULT time::now() VALUE $before OR time::now();\nDEFINE FIELD OVERWRITE updatedAt ON verification TYPE datetime DEFAULT time::now() VALUE time::now();\nDEFINE FIELD OVERWRITE identifier ON verification TYPE string ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE val ON verification TYPE string ASSERT $value != NONE;\n\n-- Passkey table definition\nDEFINE TABLE OVERWRITE passkey SCHEMAFULL;\nDEFINE FIELD OVERWRITE userId ON passkey TYPE record<user> ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE name ON passkey TYPE option<string>;\nDEFINE FIELD OVERWRITE publicKey ON passkey TYPE string ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE credentialID ON passkey TYPE string ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE counter ON passkey TYPE int ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE deviceType ON passkey TYPE string ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE backedUp ON passkey TYPE bool ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE transports ON passkey TYPE option<string>;\nDEFINE FIELD OVERWRITE createdAt ON passkey TYPE option<datetime> DEFAULT time::now() VALUE $before OR time::now();\n\n-- Jwks table definition\nDEFINE TABLE OVERWRITE jwks SCHEMAFULL;\nDEFINE FIELD OVERWRITE publicKey ON jwks TYPE string ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE privateKey ON jwks TYPE string ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE createdAt ON jwks TYPE datetime ASSERT $value != NONE DEFAULT time::now() VALUE $before OR time::now();\n\n-- SsoProvider table definition\nDEFINE TABLE OVERWRITE sso_provider SCHEMAFULL;\nDEFINE FIELD OVERWRITE issuer ON sso_provider TYPE string ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE oidcConfig ON sso_provider TYPE option<string>;\nDEFINE FIELD OVERWRITE samlConfig ON sso_provider TYPE option<string>;\nDEFINE FIELD OVERWRITE userId ON sso_provider TYPE option<record<user>>;\nDEFINE FIELD OVERWRITE providerId ON sso_provider TYPE string ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE organizationId ON sso_provider TYPE option<string>;\nDEFINE FIELD OVERWRITE domain ON sso_provider TYPE string ASSERT $value != NONE;\n\n-- OauthApplication table definition\nDEFINE TABLE OVERWRITE oauth_application SCHEMAFULL;\nDEFINE FIELD OVERWRITE name ON oauth_application TYPE option<string>;\nDEFINE FIELD OVERWRITE icon ON oauth_application TYPE option<string>;\nDEFINE FIELD OVERWRITE metadata ON oauth_application TYPE option<string>;\nDEFINE FIELD OVERWRITE clientId ON oauth_application TYPE option<string>;\nDEFINE FIELD OVERWRITE clientSecret ON oauth_application TYPE option<string>;\nDEFINE FIELD OVERWRITE redirectURLs ON oauth_application TYPE option<string>;\nDEFINE FIELD OVERWRITE type ON oauth_application TYPE option<string>;\nDEFINE FIELD OVERWRITE disabled ON oauth_application TYPE option<bool>;\nDEFINE FIELD OVERWRITE userId ON oauth_application TYPE option<string>;\nDEFINE FIELD OVERWRITE createdAt ON oauth_application TYPE option<datetime> DEFAULT time::now() VALUE $before OR time::now();\nDEFINE FIELD OVERWRITE updatedAt ON oauth_application TYPE option<datetime> DEFAULT time::now() VALUE time::now();\n\n-- OauthAccessToken table definition\nDEFINE TABLE OVERWRITE oauth_access_token SCHEMAFULL;\nDEFINE FIELD OVERWRITE accessToken ON oauth_access_token TYPE option<string>;\nDEFINE FIELD OVERWRITE refreshToken ON oauth_access_token TYPE option<string>;\nDEFINE FIELD OVERWRITE accessTokenExpiresAt ON oauth_access_token TYPE option<datetime>;\nDEFINE FIELD OVERWRITE refreshTokenExpiresAt ON oauth_access_token TYPE option<datetime>;\nDEFINE FIELD OVERWRITE clientId ON oauth_access_token TYPE option<string>;\nDEFINE FIELD OVERWRITE userId ON oauth_access_token TYPE option<string>;\nDEFINE FIELD OVERWRITE scopes ON oauth_access_token TYPE option<string>;\nDEFINE FIELD OVERWRITE createdAt ON oauth_access_token TYPE option<datetime> DEFAULT time::now() VALUE $before OR time::now();\nDEFINE FIELD OVERWRITE updatedAt ON oauth_access_token TYPE option<datetime> DEFAULT time::now() VALUE time::now();\n\n-- OauthConsent table definition\nDEFINE TABLE OVERWRITE oauth_consent SCHEMAFULL;\nDEFINE FIELD OVERWRITE clientId ON oauth_consent TYPE option<string>;\nDEFINE FIELD OVERWRITE userId ON oauth_consent TYPE option<string>;\nDEFINE FIELD OVERWRITE scopes ON oauth_consent TYPE option<string>;\nDEFINE FIELD OVERWRITE createdAt ON oauth_consent TYPE option<datetime> DEFAULT time::now() VALUE $before OR time::now();\nDEFINE FIELD OVERWRITE updatedAt ON oauth_consent TYPE option<datetime> DEFAULT time::now() VALUE time::now();\nDEFINE FIELD OVERWRITE consentGiven ON oauth_consent TYPE option<bool>;\n\n-- Organization table definition\nDEFINE TABLE OVERWRITE organization SCHEMAFULL;\nDEFINE FIELD OVERWRITE name ON organization TYPE string ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE slug ON organization TYPE string ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE logo ON organization TYPE option<string>;\nDEFINE FIELD OVERWRITE metadata ON organization TYPE option<string>;\nDEFINE FIELD OVERWRITE createdAt ON organization TYPE datetime DEFAULT time::now() VALUE $before OR time::now();\n\n-- Member table definition\nDEFINE TABLE OVERWRITE member SCHEMAFULL;\nDEFINE FIELD OVERWRITE userId ON member TYPE record<user> ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE organizationId ON member TYPE record<organization> ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE role ON member TYPE string ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE createdAt ON member TYPE datetime DEFAULT time::now() VALUE $before OR time::now();\n\n-- Invitation table definition\nDEFINE TABLE OVERWRITE invitation SCHEMAFULL;\nDEFINE FIELD OVERWRITE email ON invitation TYPE string ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE inviterId ON invitation TYPE record<user> ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE organizationId ON invitation TYPE record<organization> ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE teamId ON invitation TYPE option<record<team>>;\nDEFINE FIELD OVERWRITE role ON invitation TYPE string ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE status ON invitation TYPE string ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE expiresAt ON invitation TYPE datetime ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE createdAt ON invitation TYPE datetime DEFAULT time::now() VALUE $before OR time::now();\n\n-- Team table definition\nDEFINE TABLE OVERWRITE team SCHEMAFULL;\nDEFINE FIELD OVERWRITE name ON team TYPE string ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE organizationId ON team TYPE record<organization> ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE createdAt ON team TYPE datetime DEFAULT time::now() VALUE $before OR time::now();\nDEFINE FIELD OVERWRITE updatedAt ON team TYPE option<datetime> DEFAULT time::now() VALUE time::now();\n\n-- TeamMember table definition\nDEFINE TABLE OVERWRITE team_member SCHEMAFULL;\nDEFINE FIELD OVERWRITE teamId ON team_member TYPE record<team> ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE userId ON team_member TYPE record<user> ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE createdAt ON team_member TYPE datetime DEFAULT time::now() VALUE $before OR time::now();\n\n-- TwoFactor table definition\nDEFINE TABLE OVERWRITE two_factor SCHEMAFULL;\nDEFINE FIELD OVERWRITE secret ON two_factor TYPE string ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE backupCodes ON two_factor TYPE string ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE userId ON two_factor TYPE record<user> ASSERT $value != NONE;\n\n-- ApiKey table definition\nDEFINE TABLE OVERWRITE api_key SCHEMAFULL;\nDEFINE FIELD OVERWRITE name ON api_key TYPE option<string>;\nDEFINE FIELD OVERWRITE start ON api_key TYPE option<string>;\nDEFINE FIELD OVERWRITE prefix ON api_key TYPE option<string>;\nDEFINE FIELD OVERWRITE key ON api_key TYPE string ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE userId ON api_key TYPE record<user> ASSERT $value != NONE;\nDEFINE FIELD OVERWRITE refillInterval ON api_key TYPE option<int>;\nDEFINE FIELD OVERWRITE refillAmount ON api_key TYPE option<int>;\nDEFINE FIELD OVERWRITE lastRefillAt ON api_key TYPE option<datetime>;\nDEFINE FIELD OVERWRITE enabled ON api_key TYPE bool DEFAULT true;\nDEFINE FIELD OVERWRITE rateLimitEnabled ON api_key TYPE bool DEFAULT false;\nDEFINE FIELD OVERWRITE rateLimitTimeWindow ON api_key TYPE option<int>;\nDEFINE FIELD OVERWRITE rateLimitMax ON api_key TYPE option<int>;\nDEFINE FIELD OVERWRITE requestCount ON api_key TYPE int DEFAULT 0;\nDEFINE FIELD OVERWRITE remaining ON api_key TYPE option<int>;\nDEFINE FIELD OVERWRITE lastRequest ON api_key TYPE option<datetime>;\nDEFINE FIELD OVERWRITE expiresAt ON api_key TYPE option<datetime>;\nDEFINE FIELD OVERWRITE createdAt ON api_key TYPE datetime DEFAULT time::now() VALUE $before OR time::now();\nDEFINE FIELD OVERWRITE updatedAt ON api_key TYPE datetime DEFAULT time::now() VALUE time::now();\nDEFINE FIELD OVERWRITE permissions ON api_key TYPE option<string>;\nDEFINE FIELD OVERWRITE metadata ON api_key TYPE option<object>;\n\n-- Define indexes for performance\nDEFINE INDEX OVERWRITE account_provider_id ON account FIELDS providerId, accountId UNIQUE;\nDEFINE INDEX OVERWRITE verification_identifier ON verification FIELDS identifier, val UNIQUE;\nDEFINE INDEX OVERWRITE sso_provider_id ON sso_provider FIELDS providerId UNIQUE;\nDEFINE INDEX OVERWRITE oauth_app_client_id ON oauth_application FIELDS clientId UNIQUE;\nDEFINE INDEX OVERWRITE oauth_access_token_idx ON oauth_access_token FIELDS accessToken UNIQUE;\nDEFINE INDEX OVERWRITE oauth_refresh_token_idx ON oauth_access_token FIELDS refreshToken UNIQUE;\nDEFINE INDEX OVERWRITE organization_slug_idx ON organization FIELDS slug UNIQUE;\nDEFINE INDEX OVERWRITE passkey_credential_idx ON passkey FIELDS credentialID;\nDEFINE INDEX OVERWRITE phone_number_idx ON user FIELDS phoneNumber UNIQUE;\nDEFINE INDEX OVERWRITE api_key_prefix_idx ON api_key FIELDS prefix;\nDEFINE INDEX OVERWRITE api_key_user_idx ON api_key FIELDS userId;\nDEFINE INDEX OVERWRITE member_org_user_idx ON member FIELDS organizationId, userId UNIQUE;\nDEFINE INDEX OVERWRITE team_org_idx ON team FIELDS organizationId;\nDEFINE INDEX OVERWRITE team_member_idx ON team_member FIELDS teamId, userId UNIQUE;\nDEFINE INDEX OVERWRITE invitation_email_org_idx ON invitation FIELDS email, organizationId;\n";
|
|
|
|
/**
|
|
* Apply the bundled schema string against the supplied SurrealDB client.
|
|
*
|
|
* Each top-level DDL statement is separated by `;` and executed in order.
|
|
* Re-application is idempotent because every `DEFINE TABLE` / `DEFINE FIELD`
|
|
* / `DEFINE INDEX` in the bundled schema uses the `OVERWRITE` flag.
|
|
*
|
|
* Wraps any underlying execution failure in `BetterAuthSurrealError` with
|
|
* code `QUERY_FAILED`, preserving the original error as `cause`.
|
|
*/
|
|
export async function applyBetterAuthSchema(
|
|
client: SurrealClientView
|
|
): Promise<void> {
|
|
try {
|
|
await client.execute(BETTER_AUTH_SURREAL_SCHEMA);
|
|
} catch (err) {
|
|
throw new BetterAuthSurrealError(
|
|
BETTER_AUTH_SURREALDB_CODES.QUERY_FAILED,
|
|
"applyBetterAuthSchema failed",
|
|
{ cause: err }
|
|
);
|
|
}
|
|
}
|