--
-- DSP OAuth schema for JupyterHub integration
--
-- Run inside the MySQL container, e.g.:
--   docker-compose exec db mysql -u root -p niph_dsps < db/migrations/20241103_oauth_tables.sql
--

START TRANSACTION;

CREATE TABLE IF NOT EXISTS `dsp_oauth_clients` (
  `client_id` varchar(128) NOT NULL,
  `client_name` varchar(255) NOT NULL,
  `client_secret_hash` varchar(255) DEFAULT NULL,
  `redirect_uris` text NOT NULL,
  `allowed_scopes` varchar(255) DEFAULT NULL,
  `is_confidential` tinyint(1) NOT NULL DEFAULT 1,
  `is_revoked` tinyint(1) NOT NULL DEFAULT 0,
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`client_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

CREATE TABLE IF NOT EXISTS `dsp_oauth_auth_codes` (
  `code_hash` char(64) NOT NULL,
  `client_id` varchar(128) NOT NULL,
  `person_id` int(11) NOT NULL,
  `scope` varchar(255) DEFAULT NULL,
  `redirect_uri` varchar(2000) NOT NULL,
  `expires_at` datetime NOT NULL,
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`code_hash`),
  KEY `idx_oauth_auth_client` (`client_id`),
  KEY `idx_oauth_auth_expires` (`expires_at`),
  CONSTRAINT `dsp_oauth_auth_codes_ibfk_1` FOREIGN KEY (`client_id`) REFERENCES `dsp_oauth_clients` (`client_id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `dsp_oauth_auth_codes_ibfk_2` FOREIGN KEY (`person_id`) REFERENCES `ist_tbl_people` (`pkisp_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

CREATE TABLE IF NOT EXISTS `dsp_oauth_access_tokens` (
  `token_hash` char(64) NOT NULL,
  `client_id` varchar(128) NOT NULL,
  `person_id` int(11) NOT NULL,
  `scope` varchar(255) DEFAULT NULL,
  `expires_at` datetime NOT NULL,
  `refresh_token_hash` char(64) DEFAULT NULL,
  `refresh_expires_at` datetime DEFAULT NULL,
  `is_revoked` tinyint(1) NOT NULL DEFAULT 0,
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `last_used_at` datetime DEFAULT NULL,
  `revoked_at` datetime DEFAULT NULL,
  PRIMARY KEY (`token_hash`),
  KEY `idx_oauth_access_client` (`client_id`),
  KEY `idx_oauth_access_person` (`person_id`),
  KEY `idx_oauth_access_refresh` (`refresh_token_hash`),
  KEY `idx_oauth_access_expires` (`expires_at`),
  CONSTRAINT `dsp_oauth_access_tokens_ibfk_1` FOREIGN KEY (`client_id`) REFERENCES `dsp_oauth_clients` (`client_id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `dsp_oauth_access_tokens_ibfk_2` FOREIGN KEY (`person_id`) REFERENCES `ist_tbl_people` (`pkisp_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

COMMIT;

--
-- Optional helper to register the JupyterHub client.
-- Replace the placeholder secret/redirects before running.
--
-- INSERT INTO dsp_oauth_clients (
--   client_id,
--   client_name,
--   client_secret_hash,
--   redirect_uris,
--   allowed_scopes
-- ) VALUES (
--   'hub-client',
--   'DSP JupyterHub',
--   '$2y$10$replace_this_with_password_hash',
--   'https://hub.example.com/hub/oauth_callback',
--   'profile'
-- )
-- ON DUPLICATE KEY UPDATE
--   client_name = VALUES(client_name),
--   client_secret_hash = VALUES(client_secret_hash),
--   redirect_uris = VALUES(redirect_uris),
--   allowed_scopes = VALUES(allowed_scopes),
--   updated_at = NOW();
