@nathapp/nestjs-oauth-prisma 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +249 -0
- package/dist/abstract-prisma-public-client.repository.d.ts +20 -0
- package/dist/abstract-prisma-public-client.repository.js +54 -0
- package/dist/abstract-prisma-public-client.repository.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/oauth-prisma.module.d.ts +7 -0
- package/dist/oauth-prisma.module.js +75 -0
- package/dist/oauth-prisma.module.js.map +1 -0
- package/dist/oauth-prisma.types.d.ts +189 -0
- package/dist/oauth-prisma.types.js +43 -0
- package/dist/oauth-prisma.types.js.map +1 -0
- package/dist/prisma-consent-logout-target.resolver.d.ts +12 -0
- package/dist/prisma-consent-logout-target.resolver.js +43 -0
- package/dist/prisma-consent-logout-target.resolver.js.map +1 -0
- package/dist/prisma-oauth-access-token.repository.d.ts +41 -0
- package/dist/prisma-oauth-access-token.repository.js +124 -0
- package/dist/prisma-oauth-access-token.repository.js.map +1 -0
- package/dist/prisma-oauth-authorization-code.repository.d.ts +41 -0
- package/dist/prisma-oauth-authorization-code.repository.js +118 -0
- package/dist/prisma-oauth-authorization-code.repository.js.map +1 -0
- package/dist/prisma-oauth-client.repository.d.ts +50 -0
- package/dist/prisma-oauth-client.repository.js +193 -0
- package/dist/prisma-oauth-client.repository.js.map +1 -0
- package/dist/prisma-oauth-consent.repository.d.ts +36 -0
- package/dist/prisma-oauth-consent.repository.js +95 -0
- package/dist/prisma-oauth-consent.repository.js.map +1 -0
- package/dist/prisma-oauth-device-code.repository.d.ts +36 -0
- package/dist/prisma-oauth-device-code.repository.js +124 -0
- package/dist/prisma-oauth-device-code.repository.js.map +1 -0
- package/dist/prisma-oauth-pushed-request.repository.d.ts +16 -0
- package/dist/prisma-oauth-pushed-request.repository.js +104 -0
- package/dist/prisma-oauth-pushed-request.repository.js.map +1 -0
- package/dist/prisma-oauth-refresh-token.repository.d.ts +28 -0
- package/dist/prisma-oauth-refresh-token.repository.js +100 -0
- package/dist/prisma-oauth-refresh-token.repository.js.map +1 -0
- package/dist/prisma-oauth-scope.repository.d.ts +25 -0
- package/dist/prisma-oauth-scope.repository.js +87 -0
- package/dist/prisma-oauth-scope.repository.js.map +1 -0
- package/dist/prisma-oauth-signing-key.repository.d.ts +24 -0
- package/dist/prisma-oauth-signing-key.repository.js +110 -0
- package/dist/prisma-oauth-signing-key.repository.js.map +1 -0
- package/dist/prisma-signing-key.provider.d.ts +22 -0
- package/dist/prisma-signing-key.provider.js +133 -0
- package/dist/prisma-signing-key.provider.js.map +1 -0
- package/package.json +45 -0
- package/prisma/migrations/20260608_oauth_signing_keys_one_active/migration.mysql.sql +8 -0
- package/prisma/migrations/20260608_oauth_signing_keys_one_active/migration.sql +3 -0
- package/prisma/migrations/20260724_oauth_client_advanced_auth_fields/migration.mysql.sql +10 -0
- package/prisma/migrations/20260724_oauth_client_advanced_auth_fields/migration.sql +9 -0
- package/prisma/migrations/20260725_oauth_resource_indicator/migration.mysql.sql +10 -0
- package/prisma/migrations/20260725_oauth_resource_indicator/migration.sql +15 -0
- package/prisma/migrations/20260725_oauth_token_exchange_actor/migration.mysql.sql +2 -0
- package/prisma/migrations/20260725_oauth_token_exchange_actor/migration.sql +2 -0
- package/prisma/migrations/20261003_oauth_access_token_mtls_binding/migration.mysql.sql +2 -0
- package/prisma/migrations/20261003_oauth_access_token_mtls_binding/migration.sql +2 -0
- package/prisma/migrations/20261004_oauth_signing_keys_one_active_per_tenant/migration.mysql.sql +13 -0
- package/prisma/migrations/20261004_oauth_signing_keys_one_active_per_tenant/migration.sql +14 -0
- package/prisma/oauth.prisma +287 -0
- package/prisma/sql/long-text-columns.mysql.sql +29 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
-- MySQL equivalent of migration.sql.
|
|
2
|
+
ALTER TABLE `oauth_clients`
|
|
3
|
+
ADD COLUMN `token_endpoint_auth_method` VARCHAR(191) NULL,
|
|
4
|
+
ADD COLUMN `jwks` JSON NULL,
|
|
5
|
+
ADD COLUMN `jwks_uri` TEXT NULL,
|
|
6
|
+
ADD COLUMN `tls_client_auth_subject_dn` TEXT NULL,
|
|
7
|
+
ADD COLUMN `tls_client_auth_san_dns` JSON NULL,
|
|
8
|
+
ADD COLUMN `tls_client_auth_self_signed_thumbprint` VARCHAR(191) NULL,
|
|
9
|
+
ADD COLUMN `client_secret_hash_previous` VARCHAR(191) NULL,
|
|
10
|
+
ADD COLUMN `previous_secret_expires_at` DATETIME(6) NULL;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
ALTER TABLE "oauth_clients"
|
|
2
|
+
ADD COLUMN "token_endpoint_auth_method" TEXT,
|
|
3
|
+
ADD COLUMN "jwks" JSONB,
|
|
4
|
+
ADD COLUMN "jwks_uri" TEXT,
|
|
5
|
+
ADD COLUMN "tls_client_auth_subject_dn" TEXT,
|
|
6
|
+
ADD COLUMN "tls_client_auth_san_dns" JSONB,
|
|
7
|
+
ADD COLUMN "tls_client_auth_self_signed_thumbprint" TEXT,
|
|
8
|
+
ADD COLUMN "client_secret_hash_previous" TEXT,
|
|
9
|
+
ADD COLUMN "previous_secret_expires_at" TIMESTAMPTZ(6);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
-- MySQL equivalent of migration.sql. MySQL 8 accepts a JSON default only as an
|
|
2
|
+
-- expression, hence the parenthesised (JSON_ARRAY()).
|
|
3
|
+
ALTER TABLE `oauth_clients`
|
|
4
|
+
ADD COLUMN `allowed_resources` JSON NOT NULL DEFAULT (JSON_ARRAY()),
|
|
5
|
+
ADD COLUMN `require_resource` BOOLEAN NOT NULL DEFAULT FALSE;
|
|
6
|
+
|
|
7
|
+
ALTER TABLE `oauth_authorization_codes` ADD COLUMN `resource` TEXT NULL;
|
|
8
|
+
ALTER TABLE `oauth_pushed_requests` ADD COLUMN `resource` TEXT NULL;
|
|
9
|
+
ALTER TABLE `oauth_access_tokens` ADD COLUMN `resource` TEXT NULL;
|
|
10
|
+
ALTER TABLE `oauth_refresh_tokens` ADD COLUMN `resource` TEXT NULL;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ALTER TABLE "oauth_clients"
|
|
2
|
+
ADD COLUMN "allowed_resources" JSONB NOT NULL DEFAULT '[]',
|
|
3
|
+
ADD COLUMN "require_resource" BOOLEAN NOT NULL DEFAULT FALSE;
|
|
4
|
+
|
|
5
|
+
ALTER TABLE "oauth_authorization_codes"
|
|
6
|
+
ADD COLUMN "resource" TEXT;
|
|
7
|
+
|
|
8
|
+
ALTER TABLE "oauth_pushed_requests"
|
|
9
|
+
ADD COLUMN "resource" TEXT;
|
|
10
|
+
|
|
11
|
+
ALTER TABLE "oauth_access_tokens"
|
|
12
|
+
ADD COLUMN "resource" TEXT;
|
|
13
|
+
|
|
14
|
+
ALTER TABLE "oauth_refresh_tokens"
|
|
15
|
+
ADD COLUMN "resource" TEXT;
|
package/prisma/migrations/20261004_oauth_signing_keys_one_active_per_tenant/migration.mysql.sql
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
-- MySQL equivalent of migration.sql: one active signing key per tenant (NULL
|
|
2
|
+
-- tenant_id = the global key), replacing 20260608's global index. A functional
|
|
3
|
+
-- unique index (MySQL 8.0.13+) over an expression that is NULL for every
|
|
4
|
+
-- non-active row; NULLs never collide.
|
|
5
|
+
--
|
|
6
|
+
-- Preflight: resolve any rows this returns before creating the index:
|
|
7
|
+
-- SELECT tenant_id, COUNT(*) FROM oauth_signing_keys WHERE status = 'active'
|
|
8
|
+
-- GROUP BY tenant_id HAVING COUNT(*) > 1;
|
|
9
|
+
CREATE UNIQUE INDEX oauth_signing_keys_one_active_per_tenant
|
|
10
|
+
ON oauth_signing_keys ((CASE WHEN status = 'active' THEN COALESCE(tenant_id, '') ELSE NULL END));
|
|
11
|
+
|
|
12
|
+
-- Only if 20260608_oauth_signing_keys_one_active was applied:
|
|
13
|
+
DROP INDEX oauth_signing_keys_one_active ON oauth_signing_keys;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
-- One active signing key per tenant (NULL tenant_id = the global key), replacing
|
|
2
|
+
-- 20260608's global index. Signing keys became tenant-scoped after that index was
|
|
3
|
+
-- written, so the global index lets only one tenant hold an active key: on a
|
|
4
|
+
-- multi-tenant database every other tenant's first key insert fails.
|
|
5
|
+
--
|
|
6
|
+
-- Preflight: resolve any rows this returns (retire all but one active key per
|
|
7
|
+
-- tenant) before creating the index:
|
|
8
|
+
-- SELECT tenant_id, COUNT(*) FROM oauth_signing_keys WHERE status = 'active'
|
|
9
|
+
-- GROUP BY tenant_id HAVING COUNT(*) > 1;
|
|
10
|
+
CREATE UNIQUE INDEX IF NOT EXISTS oauth_signing_keys_one_active_per_tenant
|
|
11
|
+
ON oauth_signing_keys ((COALESCE(tenant_id, '')))
|
|
12
|
+
WHERE status = 'active';
|
|
13
|
+
|
|
14
|
+
DROP INDEX IF EXISTS oauth_signing_keys_one_active;
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
// === @nathapp/nestjs-oauth schema fragment ===
|
|
2
|
+
// Append these models to your application's schema.prisma.
|
|
3
|
+
//
|
|
4
|
+
// TZ NOTE: All DateTime fields use @db.Timestamptz(6) (timestamptz in PostgreSQL).
|
|
5
|
+
// When migrating an existing database, use:
|
|
6
|
+
// ALTER TABLE t ALTER COLUMN col TYPE TIMESTAMPTZ(6) USING col AT TIME ZONE 'UTC';
|
|
7
|
+
// The USING clause treats existing values as UTC — safe if your DB was UTC-configured.
|
|
8
|
+
// Verify your DB timezone (SHOW timezone;) before running migrations on production data.
|
|
9
|
+
|
|
10
|
+
model OAuthClient {
|
|
11
|
+
id String @id @default(uuid())
|
|
12
|
+
tenantId String? @map("tenant_id")
|
|
13
|
+
clientId String @unique @map("client_id")
|
|
14
|
+
clientSecretHash String? @map("client_secret_hash")
|
|
15
|
+
name String
|
|
16
|
+
description String? @db.Text
|
|
17
|
+
clientType String @default("confidential") @map("client_type")
|
|
18
|
+
redirectUris Json @default("[]") @map("redirect_uris")
|
|
19
|
+
postLogoutRedirectUris Json? @default("[]") @map("post_logout_redirect_uris")
|
|
20
|
+
grantTypes Json @default("[\"authorization_code\",\"refresh_token\"]") @map("grant_types")
|
|
21
|
+
responseTypes Json @default("[\"code\"]") @map("response_types")
|
|
22
|
+
accessTokenTtl Int @default(3600) @map("access_token_ttl")
|
|
23
|
+
refreshTokenTtl Int @default(604800) @map("refresh_token_ttl")
|
|
24
|
+
authCodeTtl Int @default(600) @map("auth_code_ttl")
|
|
25
|
+
pkceRequired String @default("required") @map("pkce_required")
|
|
26
|
+
requireConsent Boolean @default(true) @map("require_consent")
|
|
27
|
+
dpopBoundAccessTokens Boolean @default(false) @map("dpop_bound_access_tokens")
|
|
28
|
+
backchannelLogoutUri String? @db.Text @map("backchannel_logout_uri")
|
|
29
|
+
backchannelLogoutSessionRequired Boolean? @map("backchannel_logout_session_required")
|
|
30
|
+
frontchannelLogoutUri String? @db.Text @map("frontchannel_logout_uri")
|
|
31
|
+
frontchannelLogoutSessionRequired Boolean? @map("frontchannel_logout_session_required")
|
|
32
|
+
tokenEndpointAuthMethod String? @map("token_endpoint_auth_method")
|
|
33
|
+
allowedResources Json @default("[]") @map("allowed_resources")
|
|
34
|
+
requireResource Boolean @default(false) @map("require_resource")
|
|
35
|
+
jwks Json? @map("jwks")
|
|
36
|
+
jwksUri String? @db.Text @map("jwks_uri")
|
|
37
|
+
tlsClientAuthSubjectDn String? @db.Text @map("tls_client_auth_subject_dn")
|
|
38
|
+
tlsClientAuthSanDns Json? @map("tls_client_auth_san_dns")
|
|
39
|
+
tlsClientAuthSelfSignedThumbprint String? @map("tls_client_auth_self_signed_thumbprint")
|
|
40
|
+
clientSecretHashPrevious String? @map("client_secret_hash_previous")
|
|
41
|
+
previousSecretExpiresAt DateTime? @db.Timestamptz(6) @map("previous_secret_expires_at")
|
|
42
|
+
status Int @default(1)
|
|
43
|
+
createdAt DateTime @db.Timestamptz(6) @default(now()) @map("created_at")
|
|
44
|
+
updatedAt DateTime @db.Timestamptz(6) @updatedAt @map("updated_at")
|
|
45
|
+
|
|
46
|
+
scopes OAuthClientScope[]
|
|
47
|
+
authorizationCodes OAuthAuthorizationCode[]
|
|
48
|
+
accessTokens OAuthAccessToken[]
|
|
49
|
+
refreshTokens OAuthRefreshToken[]
|
|
50
|
+
consents OAuthConsent[]
|
|
51
|
+
deviceCodes OAuthDeviceCode[]
|
|
52
|
+
pushedRequests OAuthPushedRequest[]
|
|
53
|
+
|
|
54
|
+
@@index([tenantId])
|
|
55
|
+
@@map("oauth_clients")
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
model OAuthScope {
|
|
59
|
+
id String @id @default(uuid())
|
|
60
|
+
code String @unique
|
|
61
|
+
name String
|
|
62
|
+
description String?
|
|
63
|
+
claims Json @default("[]")
|
|
64
|
+
isSystem Boolean @default(false) @map("is_system")
|
|
65
|
+
status Int @default(1)
|
|
66
|
+
createdAt DateTime @db.Timestamptz(6) @default(now()) @map("created_at")
|
|
67
|
+
updatedAt DateTime @db.Timestamptz(6) @updatedAt @map("updated_at")
|
|
68
|
+
|
|
69
|
+
clients OAuthClientScope[]
|
|
70
|
+
authorizationCodes OAuthAuthorizationCodeScope[]
|
|
71
|
+
accessTokens OAuthAccessTokenScope[]
|
|
72
|
+
consents OAuthConsentScope[]
|
|
73
|
+
|
|
74
|
+
@@map("oauth_scopes")
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
model OAuthClientScope {
|
|
78
|
+
clientId String @map("client_id")
|
|
79
|
+
scopeId String @map("scope_id")
|
|
80
|
+
isDefault Boolean @default(false) @map("is_default")
|
|
81
|
+
|
|
82
|
+
client OAuthClient @relation(fields: [clientId], references: [id], onDelete: Cascade)
|
|
83
|
+
scope OAuthScope @relation(fields: [scopeId], references: [id])
|
|
84
|
+
|
|
85
|
+
@@id([clientId, scopeId])
|
|
86
|
+
@@map("oauth_client_scopes")
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
model OAuthAuthorizationCode {
|
|
90
|
+
id String @id @default(uuid())
|
|
91
|
+
tenantId String? @map("tenant_id")
|
|
92
|
+
code String @unique
|
|
93
|
+
clientId String @map("client_id")
|
|
94
|
+
userId String @map("user_id")
|
|
95
|
+
codeChallenge String? @map("code_challenge")
|
|
96
|
+
codeChallengeMethod String? @map("code_challenge_method")
|
|
97
|
+
redirectUri String @db.Text @map("redirect_uri")
|
|
98
|
+
state String? @db.Text
|
|
99
|
+
nonce String? @db.Text
|
|
100
|
+
sid String? @map("sid")
|
|
101
|
+
expiresAt DateTime @db.Timestamptz(6) @map("expires_at")
|
|
102
|
+
usedAt DateTime? @db.Timestamptz(6) @map("used_at")
|
|
103
|
+
authTime DateTime? @db.Timestamptz(6) @map("auth_time")
|
|
104
|
+
resource String? @db.Text @map("resource")
|
|
105
|
+
createdAt DateTime @db.Timestamptz(6) @default(now()) @map("created_at")
|
|
106
|
+
|
|
107
|
+
client OAuthClient @relation(fields: [clientId], references: [id])
|
|
108
|
+
scopes OAuthAuthorizationCodeScope[]
|
|
109
|
+
|
|
110
|
+
@@index([tenantId])
|
|
111
|
+
@@index([clientId])
|
|
112
|
+
@@index([userId])
|
|
113
|
+
@@index([expiresAt])
|
|
114
|
+
@@map("oauth_authorization_codes")
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
model OAuthAuthorizationCodeScope {
|
|
118
|
+
authCodeId String @map("auth_code_id")
|
|
119
|
+
scopeId String @map("scope_id")
|
|
120
|
+
|
|
121
|
+
authCode OAuthAuthorizationCode @relation(fields: [authCodeId], references: [id], onDelete: Cascade)
|
|
122
|
+
scope OAuthScope @relation(fields: [scopeId], references: [id])
|
|
123
|
+
|
|
124
|
+
@@id([authCodeId, scopeId])
|
|
125
|
+
@@map("oauth_authorization_code_scopes")
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
model OAuthAccessToken {
|
|
129
|
+
id String @id @default(uuid())
|
|
130
|
+
tenantId String? @map("tenant_id")
|
|
131
|
+
tokenHash String @unique @map("token_hash")
|
|
132
|
+
clientId String @map("client_id")
|
|
133
|
+
userId String? @map("user_id")
|
|
134
|
+
tokenType String @default("Bearer") @map("token_type")
|
|
135
|
+
expiresAt DateTime @db.Timestamptz(6) @map("expires_at")
|
|
136
|
+
revokedAt DateTime? @db.Timestamptz(6) @map("revoked_at")
|
|
137
|
+
cnfJkt String? @map("cnf_jkt")
|
|
138
|
+
cnfX5tS256 String? @map("cnf_x5t_s256")
|
|
139
|
+
createdAt DateTime @db.Timestamptz(6) @default(now()) @map("created_at")
|
|
140
|
+
|
|
141
|
+
refreshTokenId String? @map("refresh_token_id")
|
|
142
|
+
resource String? @db.Text @map("resource")
|
|
143
|
+
actorClientId String? @map("actor_client_id")
|
|
144
|
+
|
|
145
|
+
client OAuthClient @relation(fields: [clientId], references: [id])
|
|
146
|
+
scopes OAuthAccessTokenScope[]
|
|
147
|
+
|
|
148
|
+
@@index([tenantId])
|
|
149
|
+
@@index([clientId])
|
|
150
|
+
@@index([userId])
|
|
151
|
+
@@index([expiresAt])
|
|
152
|
+
@@index([refreshTokenId])
|
|
153
|
+
@@map("oauth_access_tokens")
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
model OAuthAccessTokenScope {
|
|
157
|
+
accessTokenId String @map("access_token_id")
|
|
158
|
+
scopeId String @map("scope_id")
|
|
159
|
+
|
|
160
|
+
accessToken OAuthAccessToken @relation(fields: [accessTokenId], references: [id], onDelete: Cascade)
|
|
161
|
+
scope OAuthScope @relation(fields: [scopeId], references: [id])
|
|
162
|
+
|
|
163
|
+
@@id([accessTokenId, scopeId])
|
|
164
|
+
@@map("oauth_access_token_scopes")
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
model OAuthRefreshToken {
|
|
168
|
+
id String @id @default(uuid())
|
|
169
|
+
tenantId String? @map("tenant_id")
|
|
170
|
+
tokenHash String @unique @map("token_hash")
|
|
171
|
+
clientId String @map("client_id")
|
|
172
|
+
userId String @map("user_id")
|
|
173
|
+
scope String? @db.Text
|
|
174
|
+
previousTokenHash String? @map("previous_token_hash")
|
|
175
|
+
expiresAt DateTime @db.Timestamptz(6) @map("expires_at")
|
|
176
|
+
revokedAt DateTime? @db.Timestamptz(6) @map("revoked_at")
|
|
177
|
+
cnfJkt String? @map("cnf_jkt")
|
|
178
|
+
lastUsedAt DateTime? @db.Timestamptz(6) @map("last_used_at")
|
|
179
|
+
resource String? @db.Text @map("resource")
|
|
180
|
+
createdAt DateTime @db.Timestamptz(6) @default(now()) @map("created_at")
|
|
181
|
+
|
|
182
|
+
client OAuthClient @relation(fields: [clientId], references: [id])
|
|
183
|
+
|
|
184
|
+
@@index([tenantId])
|
|
185
|
+
@@index([clientId])
|
|
186
|
+
@@index([userId])
|
|
187
|
+
@@index([expiresAt])
|
|
188
|
+
@@map("oauth_refresh_tokens")
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
model OAuthConsent {
|
|
192
|
+
id String @id @default(uuid())
|
|
193
|
+
tenantId String? @map("tenant_id")
|
|
194
|
+
clientId String @map("client_id")
|
|
195
|
+
userId String @map("user_id")
|
|
196
|
+
grantedAt DateTime @db.Timestamptz(6) @default(now()) @map("granted_at")
|
|
197
|
+
revokedAt DateTime? @db.Timestamptz(6) @map("revoked_at")
|
|
198
|
+
|
|
199
|
+
client OAuthClient @relation(fields: [clientId], references: [id])
|
|
200
|
+
scopes OAuthConsentScope[]
|
|
201
|
+
|
|
202
|
+
@@unique([clientId, userId])
|
|
203
|
+
@@index([tenantId])
|
|
204
|
+
@@index([userId])
|
|
205
|
+
@@map("oauth_consents")
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
model OAuthConsentScope {
|
|
209
|
+
consentId String @map("consent_id")
|
|
210
|
+
scopeId String @map("scope_id")
|
|
211
|
+
|
|
212
|
+
consent OAuthConsent @relation(fields: [consentId], references: [id], onDelete: Cascade)
|
|
213
|
+
scope OAuthScope @relation(fields: [scopeId], references: [id])
|
|
214
|
+
|
|
215
|
+
@@id([consentId, scopeId])
|
|
216
|
+
@@map("oauth_consent_scopes")
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Application invariant: at most one key may have status = 'active' at any time.
|
|
220
|
+
// Enforced via the raw SQL migration in prisma/migrations/*_oauth_signing_keys_one_active/.
|
|
221
|
+
model OAuthSigningKey {
|
|
222
|
+
id String @id @default(uuid())
|
|
223
|
+
tenantId String? @map("tenant_id")
|
|
224
|
+
kid String @unique
|
|
225
|
+
alg String @default("RS256")
|
|
226
|
+
privateKeyPem String @db.Text @map("private_key_pem")
|
|
227
|
+
publicKeyPem String @db.Text @map("public_key_pem")
|
|
228
|
+
status String @default("active")
|
|
229
|
+
createdAt DateTime @db.Timestamptz(6) @default(now()) @map("created_at")
|
|
230
|
+
expiresAt DateTime? @db.Timestamptz(6) @map("expires_at")
|
|
231
|
+
|
|
232
|
+
@@index([status])
|
|
233
|
+
@@index([tenantId, status])
|
|
234
|
+
@@map("oauth_signing_keys")
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
model OAuthDeviceCode {
|
|
238
|
+
id String @id @default(uuid())
|
|
239
|
+
tenantId String? @map("tenant_id")
|
|
240
|
+
deviceCodeHash String @unique @map("device_code_hash")
|
|
241
|
+
userCodeHash String @unique @map("user_code_hash")
|
|
242
|
+
clientId String @map("client_id")
|
|
243
|
+
scope String? @db.Text
|
|
244
|
+
status String @default("pending")
|
|
245
|
+
userId String? @map("user_id")
|
|
246
|
+
authTime DateTime? @db.Timestamptz(6) @map("auth_time")
|
|
247
|
+
interval Int @default(5)
|
|
248
|
+
lastPolledAt DateTime? @db.Timestamptz(6) @map("last_polled_at")
|
|
249
|
+
approvedAt DateTime? @db.Timestamptz(6) @map("approved_at")
|
|
250
|
+
consumedAt DateTime? @db.Timestamptz(6) @map("consumed_at")
|
|
251
|
+
expiresAt DateTime @db.Timestamptz(6) @map("expires_at")
|
|
252
|
+
createdAt DateTime @db.Timestamptz(6) @default(now()) @map("created_at")
|
|
253
|
+
|
|
254
|
+
client OAuthClient @relation(fields: [clientId], references: [id])
|
|
255
|
+
|
|
256
|
+
@@index([tenantId])
|
|
257
|
+
@@index([clientId])
|
|
258
|
+
@@index([expiresAt])
|
|
259
|
+
@@map("oauth_device_codes")
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
model OAuthPushedRequest {
|
|
263
|
+
id String @id @default(uuid())
|
|
264
|
+
tenantId String? @map("tenant_id")
|
|
265
|
+
requestUriHash String @unique @map("request_uri_hash")
|
|
266
|
+
clientId String @map("client_id")
|
|
267
|
+
responseType String @map("response_type")
|
|
268
|
+
redirectUri String @db.Text @map("redirect_uri")
|
|
269
|
+
scope String? @db.Text
|
|
270
|
+
state String? @db.Text
|
|
271
|
+
codeChallenge String? @map("code_challenge")
|
|
272
|
+
codeChallengeMethod String? @map("code_challenge_method")
|
|
273
|
+
nonce String? @db.Text
|
|
274
|
+
prompt String?
|
|
275
|
+
maxAge String? @map("max_age")
|
|
276
|
+
consumedAt DateTime? @db.Timestamptz(6) @map("consumed_at")
|
|
277
|
+
resource String? @db.Text @map("resource")
|
|
278
|
+
expiresAt DateTime @db.Timestamptz(6) @map("expires_at")
|
|
279
|
+
createdAt DateTime @db.Timestamptz(6) @default(now()) @map("created_at")
|
|
280
|
+
|
|
281
|
+
client OAuthClient @relation(fields: [clientId], references: [id])
|
|
282
|
+
|
|
283
|
+
@@index([tenantId])
|
|
284
|
+
@@index([clientId])
|
|
285
|
+
@@index([expiresAt])
|
|
286
|
+
@@map("oauth_pushed_requests")
|
|
287
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
-- MySQL only. Widens columns whose values can exceed VARCHAR(191) (Prisma's MySQL
|
|
2
|
+
-- mapping for a bare String). PostgreSQL needs nothing: String is already text there.
|
|
3
|
+
-- Apply once to a MySQL database created from an earlier version of this fragment.
|
|
4
|
+
ALTER TABLE `oauth_clients` MODIFY `description` TEXT NULL,
|
|
5
|
+
MODIFY `backchannel_logout_uri` TEXT NULL,
|
|
6
|
+
MODIFY `frontchannel_logout_uri` TEXT NULL,
|
|
7
|
+
MODIFY `jwks_uri` TEXT NULL,
|
|
8
|
+
MODIFY `tls_client_auth_subject_dn` TEXT NULL;
|
|
9
|
+
|
|
10
|
+
ALTER TABLE `oauth_authorization_codes` MODIFY `redirect_uri` TEXT NOT NULL,
|
|
11
|
+
MODIFY `state` TEXT NULL,
|
|
12
|
+
MODIFY `nonce` TEXT NULL,
|
|
13
|
+
MODIFY `resource` TEXT NULL;
|
|
14
|
+
|
|
15
|
+
ALTER TABLE `oauth_access_tokens` MODIFY `resource` TEXT NULL;
|
|
16
|
+
|
|
17
|
+
ALTER TABLE `oauth_refresh_tokens` MODIFY `scope` TEXT NULL,
|
|
18
|
+
MODIFY `resource` TEXT NULL;
|
|
19
|
+
|
|
20
|
+
ALTER TABLE `oauth_signing_keys` MODIFY `private_key_pem` TEXT NOT NULL,
|
|
21
|
+
MODIFY `public_key_pem` TEXT NOT NULL;
|
|
22
|
+
|
|
23
|
+
ALTER TABLE `oauth_device_codes` MODIFY `scope` TEXT NULL;
|
|
24
|
+
|
|
25
|
+
ALTER TABLE `oauth_pushed_requests` MODIFY `redirect_uri` TEXT NOT NULL,
|
|
26
|
+
MODIFY `scope` TEXT NULL,
|
|
27
|
+
MODIFY `state` TEXT NULL,
|
|
28
|
+
MODIFY `nonce` TEXT NULL,
|
|
29
|
+
MODIFY `resource` TEXT NULL;
|