mirror of
https://github.com/RayLabsHQ/gitea-mirror.git
synced 2026-07-05 17:31:55 +02:00
66e3284898
Resolves #306. SSO sign-in via OIDC (Authentik / Keycloak / etc.) now links the SSO identity to an existing email/password admin instead of bouncing to /login with `?error=UNKNOWN`. Account-linking is gated on the operator-supplied **Domain** field — cross-domain claims from a compromised IdP are refused. Also bundles the deprecated `oidcProvider` → `@better-auth/oauth-provider` migration. **Operators using the OAuth-provider feature must rotate registered client secrets after upgrade** (legacy plaintext → hashed storage; see the 0012 migration notes). Verified end-to-end on the pr-307 image against a real Authentik instance: SSO login lands on the dashboard, `accounts` table gets both `credential` and `authentik` rows for the same user. See PR description for full details.
127 lines
5.2 KiB
SQL
127 lines
5.2 KiB
SQL
-- Migrate the OAuth/OIDC *provider* feature from the deprecated
|
|
-- `oidc-provider` plugin to `@better-auth/oauth-provider`.
|
|
--
|
|
-- Tables: oauth_applications -> oauth_clients, oauth_access_tokens reshaped,
|
|
-- new oauth_refresh_tokens, oauth_consent -> oauth_consents, plus a `jwks`
|
|
-- table for the `jwt` plugin (id_token signing keys).
|
|
--
|
|
-- Data preservation:
|
|
-- * Registered clients are copied from oauth_applications into oauth_clients,
|
|
-- converting the legacy comma-separated `redirect_urls` into the JSON
|
|
-- string[] (`redirect_uris`) the new adapter expects.
|
|
-- * Access tokens and consent records are NOT migrated: access tokens are
|
|
-- short-lived (and the column shape changed entirely), and consents are
|
|
-- cheaply re-granted on next authorization. Both old tables are dropped.
|
|
--
|
|
-- NOTE: legacy client secrets were stored in plaintext, whereas the new
|
|
-- provider stores them hashed. Migrated client secrets will therefore not
|
|
-- validate as-is — affected applications must rotate their secret after
|
|
-- upgrade.
|
|
|
|
CREATE TABLE `oauth_clients` (
|
|
`id` text PRIMARY KEY NOT NULL,
|
|
`client_id` text NOT NULL,
|
|
`client_secret` text,
|
|
`name` text,
|
|
`disabled` integer DEFAULT false,
|
|
`skip_consent` integer,
|
|
`enable_end_session` integer,
|
|
`subject_type` text,
|
|
`scopes` text,
|
|
`user_id` text,
|
|
`uri` text,
|
|
`icon` text,
|
|
`contacts` text,
|
|
`tos` text,
|
|
`policy` text,
|
|
`software_id` text,
|
|
`software_version` text,
|
|
`software_statement` text,
|
|
`redirect_uris` text NOT NULL,
|
|
`post_logout_redirect_uris` text,
|
|
`token_endpoint_auth_method` text,
|
|
`grant_types` text,
|
|
`response_types` text,
|
|
`public` integer,
|
|
`type` text,
|
|
`require_pkce` integer,
|
|
`reference_id` text,
|
|
`metadata` text,
|
|
`created_at` integer DEFAULT (unixepoch()),
|
|
`updated_at` integer DEFAULT (unixepoch()),
|
|
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
|
|
);
|
|
--> statement-breakpoint
|
|
CREATE UNIQUE INDEX `oauth_clients_client_id_unique` ON `oauth_clients` (`client_id`);--> statement-breakpoint
|
|
CREATE INDEX `idx_oauth_clients_client_id` ON `oauth_clients` (`client_id`);--> statement-breakpoint
|
|
CREATE INDEX `idx_oauth_clients_user_id` ON `oauth_clients` (`user_id`);--> statement-breakpoint
|
|
INSERT INTO `oauth_clients` (
|
|
`id`, `client_id`, `client_secret`, `name`, `disabled`, `user_id`,
|
|
`redirect_uris`, `type`, `metadata`, `created_at`, `updated_at`
|
|
)
|
|
SELECT
|
|
`id`, `client_id`, `client_secret`, `name`, `disabled`, `user_id`,
|
|
'["' || replace(`redirect_urls`, ',', '","') || '"]',
|
|
`type`, `metadata`, `created_at`, `updated_at`
|
|
FROM `oauth_applications`;--> statement-breakpoint
|
|
DROP TABLE `oauth_applications`;--> statement-breakpoint
|
|
DROP TABLE `oauth_access_tokens`;--> statement-breakpoint
|
|
CREATE TABLE `oauth_access_tokens` (
|
|
`id` text PRIMARY KEY NOT NULL,
|
|
`token` text,
|
|
`client_id` text NOT NULL,
|
|
`session_id` text,
|
|
`user_id` text,
|
|
`reference_id` text,
|
|
`refresh_id` text,
|
|
`expires_at` integer,
|
|
`created_at` integer DEFAULT (unixepoch()),
|
|
`scopes` text NOT NULL,
|
|
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
|
|
);
|
|
--> statement-breakpoint
|
|
CREATE UNIQUE INDEX `oauth_access_tokens_token_unique` ON `oauth_access_tokens` (`token`);--> statement-breakpoint
|
|
CREATE INDEX `idx_oauth_access_tokens_token` ON `oauth_access_tokens` (`token`);--> statement-breakpoint
|
|
CREATE INDEX `idx_oauth_access_tokens_client_id` ON `oauth_access_tokens` (`client_id`);--> statement-breakpoint
|
|
CREATE INDEX `idx_oauth_access_tokens_user_id` ON `oauth_access_tokens` (`user_id`);--> statement-breakpoint
|
|
CREATE TABLE `oauth_refresh_tokens` (
|
|
`id` text PRIMARY KEY NOT NULL,
|
|
`token` text NOT NULL,
|
|
`client_id` text NOT NULL,
|
|
`session_id` text,
|
|
`user_id` text NOT NULL,
|
|
`reference_id` text,
|
|
`expires_at` integer,
|
|
`created_at` integer DEFAULT (unixepoch()),
|
|
`revoked` integer,
|
|
`auth_time` integer,
|
|
`scopes` text NOT NULL,
|
|
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
|
|
);
|
|
--> statement-breakpoint
|
|
CREATE UNIQUE INDEX `oauth_refresh_tokens_token_unique` ON `oauth_refresh_tokens` (`token`);--> statement-breakpoint
|
|
CREATE INDEX `idx_oauth_refresh_tokens_token` ON `oauth_refresh_tokens` (`token`);--> statement-breakpoint
|
|
CREATE INDEX `idx_oauth_refresh_tokens_client_id` ON `oauth_refresh_tokens` (`client_id`);--> statement-breakpoint
|
|
CREATE INDEX `idx_oauth_refresh_tokens_user_id` ON `oauth_refresh_tokens` (`user_id`);--> statement-breakpoint
|
|
DROP TABLE `oauth_consent`;--> statement-breakpoint
|
|
CREATE TABLE `oauth_consents` (
|
|
`id` text PRIMARY KEY NOT NULL,
|
|
`client_id` text NOT NULL,
|
|
`user_id` text,
|
|
`reference_id` text,
|
|
`scopes` text NOT NULL,
|
|
`created_at` integer DEFAULT (unixepoch()),
|
|
`updated_at` integer DEFAULT (unixepoch()),
|
|
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
|
|
);
|
|
--> statement-breakpoint
|
|
CREATE INDEX `idx_oauth_consents_client_id` ON `oauth_consents` (`client_id`);--> statement-breakpoint
|
|
CREATE INDEX `idx_oauth_consents_user_id` ON `oauth_consents` (`user_id`);--> statement-breakpoint
|
|
CREATE TABLE `jwks` (
|
|
`id` text PRIMARY KEY NOT NULL,
|
|
`public_key` text NOT NULL,
|
|
`private_key` text NOT NULL,
|
|
`created_at` integer DEFAULT (unixepoch()) NOT NULL,
|
|
`expires_at` integer
|
|
);
|