Skip to content

Commit a83512b

Browse files
grdsdevCopilotCopilot
authored
feat(auth): add method for updating OAuth client (#840)
* feat(auth): add method for updating OAuth client - Fix documentation saying `browser` when it should be `client` - Fix clientId defined as raw String when it should be `UUID` - Fix types defined as enum when it should be made resilient and defined as a RawRepresentable struct * feat: add public init for UpdateOAuthClientParams * test: add test for update oauth client * docs: fix spelling and grammar in updateClient documentation (#841) * Initial plan * docs: fix spelling and grammar in updateClient documentation Co-authored-by: grdsdev <5923044+grdsdev@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: grdsdev <5923044+grdsdev@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 49fb42c commit a83512b

File tree

3 files changed

+197
-46
lines changed

3 files changed

+197
-46
lines changed

Sources/Auth/AuthAdminOAuth.swift

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public struct AuthAdminOAuth: Sendable {
2020
/// Lists all OAuth clients with optional pagination.
2121
/// Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
2222
///
23-
/// - Note: This function should only be called on a server. Never expose your `service_role` key in the browser.
23+
/// - Note: This function should only be called on a server. Never expose your `service_role` key in the client.
2424
public func listClients(
2525
params: PageParams? = nil
2626
) async throws -> ListOAuthClientsPaginatedResponse {
@@ -71,7 +71,7 @@ public struct AuthAdminOAuth: Sendable {
7171
/// Creates a new OAuth client.
7272
/// Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
7373
///
74-
/// - Note: This function should only be called on a server. Never expose your `service_role` key in the browser.
74+
/// - Note: This function should only be called on a server. Never expose your `service_role` key in the client.
7575
@discardableResult
7676
public func createClient(params: CreateOAuthClientParams) async throws -> OAuthClient {
7777
try await api.execute(
@@ -88,8 +88,8 @@ public struct AuthAdminOAuth: Sendable {
8888
/// Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
8989
///
9090
/// - Parameter clientId: The unique identifier of the OAuth client.
91-
/// - Note: This function should only be called on a server. Never expose your `service_role` key in the browser.
92-
public func getClient(clientId: String) async throws -> OAuthClient {
91+
/// - Note: This function should only be called on a server. Never expose your `service_role` key in the client.
92+
public func getClient(clientId: UUID) async throws -> OAuthClient {
9393
try await api.execute(
9494
HTTPRequest(
9595
url: configuration.url.appendingPathComponent("admin/oauth/clients/\(clientId)"),
@@ -99,13 +99,33 @@ public struct AuthAdminOAuth: Sendable {
9999
.decoded(decoder: configuration.decoder)
100100
}
101101

102+
/// Updates an existing OAuth client registration. Only the provided fields will be updated.
103+
/// Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
104+
///
105+
/// - Parameter clientId: The unique identifier of the OAuth client.
106+
/// - Parameter params: The fields to update.
107+
/// - Note: This function should only be called on a server. Never expose your `service_role` key in the client.
108+
public func updateClient(
109+
clientId: UUID,
110+
params: UpdateOAuthClientParams
111+
) async throws -> OAuthClient {
112+
try await api.execute(
113+
HTTPRequest(
114+
url: configuration.url.appendingPathComponent("admin/oauth/clients/\(clientId)"),
115+
method: .put,
116+
body: configuration.encoder.encode(params)
117+
)
118+
)
119+
.decoded(decoder: configuration.decoder)
120+
}
121+
102122
/// Deletes an OAuth client.
103123
/// Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
104124
///
105125
/// - Parameter clientId: The unique identifier of the OAuth client to delete.
106-
/// - Note: This function should only be called on a server. Never expose your `service_role` key in the browser.
126+
/// - Note: This function should only be called on a server. Never expose your `service_role` key in the client.
107127
@discardableResult
108-
public func deleteClient(clientId: String) async throws -> OAuthClient {
128+
public func deleteClient(clientId: UUID) async throws -> OAuthClient {
109129
try await api.execute(
110130
HTTPRequest(
111131
url: configuration.url.appendingPathComponent("admin/oauth/clients/\(clientId)"),
@@ -119,9 +139,9 @@ public struct AuthAdminOAuth: Sendable {
119139
/// Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
120140
///
121141
/// - Parameter clientId: The unique identifier of the OAuth client.
122-
/// - Note: This function should only be called on a server. Never expose your `service_role` key in the browser.
142+
/// - Note: This function should only be called on a server. Never expose your `service_role` key in the client.
123143
@discardableResult
124-
public func regenerateClientSecret(clientId: String) async throws -> OAuthClient {
144+
public func regenerateClientSecret(clientId: UUID) async throws -> OAuthClient {
125145
try await api.execute(
126146
HTTPRequest(
127147
url: configuration.url

Sources/Auth/Types.swift

Lines changed: 81 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,36 +1032,74 @@ public struct ListUsersPaginatedResponse: Hashable, Sendable {
10321032

10331033
/// OAuth client grant types supported by the OAuth 2.1 server.
10341034
/// Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
1035-
public enum OAuthClientGrantType: String, Codable, Hashable, Sendable {
1036-
case authorizationCode = "authorization_code"
1037-
case refreshToken = "refresh_token"
1035+
public struct OAuthClientGrantType: RawRepresentable, Codable, Hashable, Sendable,
1036+
ExpressibleByStringLiteral
1037+
{
1038+
public let rawValue: String
1039+
public init(rawValue: String) {
1040+
self.rawValue = rawValue
1041+
}
1042+
public init(stringLiteral value: String) {
1043+
self.init(rawValue: value)
1044+
}
1045+
1046+
public static let authorizationCode: OAuthClientGrantType = "authorization_code"
1047+
public static let refreshToken: OAuthClientGrantType = "refresh_token"
10381048
}
10391049

10401050
/// OAuth client response types supported by the OAuth 2.1 server.
10411051
/// Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
1042-
public enum OAuthClientResponseType: String, Codable, Hashable, Sendable {
1043-
case code
1052+
public struct OAuthClientResponseType: RawRepresentable, Codable, Hashable, Sendable,
1053+
ExpressibleByStringLiteral
1054+
{
1055+
public let rawValue: String
1056+
public init(rawValue: String) {
1057+
self.rawValue = rawValue
1058+
}
1059+
public init(stringLiteral value: String) {
1060+
self.init(rawValue: value)
1061+
}
1062+
1063+
public static let code: OAuthClientResponseType = "code"
10441064
}
10451065

10461066
/// OAuth client type indicating whether the client can keep credentials confidential.
10471067
/// Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
1048-
public enum OAuthClientType: String, Codable, Hashable, Sendable {
1049-
case `public`
1050-
case confidential
1068+
public struct OAuthClientType: RawRepresentable, Codable, Hashable, Sendable,
1069+
ExpressibleByStringLiteral
1070+
{
1071+
public let rawValue: String
1072+
public init(rawValue: String) {
1073+
self.rawValue = rawValue
1074+
}
1075+
public init(stringLiteral value: String) {
1076+
self.init(rawValue: value)
1077+
}
1078+
public static let `public`: OAuthClientType = "public"
1079+
public static let confidential: OAuthClientType = "confidential"
10511080
}
10521081

10531082
/// OAuth client registration type.
10541083
/// Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
1055-
public enum OAuthClientRegistrationType: String, Codable, Hashable, Sendable {
1056-
case dynamic
1057-
case manual
1084+
public struct OAuthClientRegistrationType: RawRepresentable, Codable, Hashable, Sendable,
1085+
ExpressibleByStringLiteral
1086+
{
1087+
public let rawValue: String
1088+
public init(rawValue: String) {
1089+
self.rawValue = rawValue
1090+
}
1091+
public init(stringLiteral value: String) {
1092+
self.init(rawValue: value)
1093+
}
1094+
public static let dynamic: OAuthClientRegistrationType = "dynamic"
1095+
public static let manual: OAuthClientRegistrationType = "manual"
10581096
}
10591097

10601098
/// OAuth client object returned from the OAuth 2.1 server.
10611099
/// Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
10621100
public struct OAuthClient: Codable, Hashable, Sendable {
10631101
/// Unique identifier for the OAuth client
1064-
public let clientId: String
1102+
public let clientId: UUID
10651103
/// Human-readable name of the OAuth client
10661104
public let clientName: String
10671105
/// Client secret (only returned on registration and regeneration)
@@ -1074,6 +1112,8 @@ public struct OAuthClient: Codable, Hashable, Sendable {
10741112
public let registrationType: OAuthClientRegistrationType
10751113
/// URI of the OAuth client
10761114
public let clientUri: String?
1115+
/// URL of the client application's logo
1116+
public let logoUri: String?
10771117
/// Array of allowed redirect URIs
10781118
public let redirectUris: [String]
10791119
/// Array of allowed grant types
@@ -1121,6 +1161,35 @@ public struct CreateOAuthClientParams: Encodable, Hashable, Sendable {
11211161
}
11221162
}
11231163

1164+
/// Parameters for updating an existing OAuth client.
1165+
/// Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
1166+
public struct UpdateOAuthClientParams: Encodable, Hashable, Sendable {
1167+
/// Human-readable name of the client application
1168+
public let clientName: String?
1169+
/// URL of the client application's homepage
1170+
public let clientUri: String?
1171+
/// URL of the client application's logo
1172+
public let logoUri: String?
1173+
/// Array of redirect URIs used by the client
1174+
public let redirectUris: [String]?
1175+
/// OAuth grant types the client is authorized to use
1176+
public let grantTypes: [OAuthClientGrantType]?
1177+
1178+
public init(
1179+
clientName: String? = nil,
1180+
clientUri: String? = nil,
1181+
logoUri: String? = nil,
1182+
redirectUris: [String]? = nil,
1183+
grantTypes: [OAuthClientGrantType]? = nil
1184+
) {
1185+
self.clientName = clientName
1186+
self.clientUri = clientUri
1187+
self.logoUri = logoUri
1188+
self.redirectUris = redirectUris
1189+
self.grantTypes = grantTypes
1190+
}
1191+
}
1192+
11241193
/// Response type for listing OAuth clients.
11251194
/// Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
11261195
public struct ListOAuthClientsPaginatedResponse: Hashable, Sendable {

0 commit comments

Comments
 (0)