// Copyright (C) 2021-present sam (starshines.gay) // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published // by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . using Catalogger.Backend.Database.Models; using Dapper; using NodaTime; namespace Catalogger.Backend.Database.Repositories; public class ApiTokenRepository(ILogger logger, DatabaseConnection conn, IClock clock) : IDisposable, IAsyncDisposable { private readonly ILogger _logger = logger.ForContext(); public async Task GetAsync(string token) => await conn.QueryFirstOrDefaultAsync( "select * from api_tokens where dashboard_token = @Token and expires_at > @Now", new { Token = token, Now = clock.GetCurrentInstant() } ); public async Task CreateAsync( string dashboardToken, string userId, string accessToken, string? refreshToken, int expiresIn ) { var expiresAt = clock.GetCurrentInstant() + Duration.FromSeconds(expiresIn); return await conn.QueryFirstAsync( """ insert into api_tokens (dashboard_token, user_id, access_token, refresh_token, expires_at) values (@dashboardToken, @userId, @accessToken, @refreshToken, @expiresAt) returning * """, new { dashboardToken, userId, accessToken, refreshToken, expiresAt, } ); } public async Task UpdateAsync( int id, string accessToken, string? refreshToken, int expiresIn ) { var expiresAt = clock.GetCurrentInstant() + Duration.FromSeconds(expiresIn); return await conn.QueryFirstAsync( """ update api_tokens set access_token = @accessToken, refresh_token = @refreshToken, expires_at = @expiresAt where id = @id returning * """, new { id, accessToken, refreshToken, expiresAt, } ); } public void Dispose() { conn.Dispose(); GC.SuppressFinalize(this); } public async ValueTask DisposeAsync() { await conn.DisposeAsync(); GC.SuppressFinalize(this); } }