Move OAuth definitions into shared, add more

This commit is contained in:
Justin Spahr-Summers 2025-02-16 20:07:30 +00:00
commit afae4212e6
No known key found for this signature in database

104
src/shared/auth.ts Normal file
View file

@ -0,0 +1,104 @@
import { z } from "zod";
/**
* RFC 8414 OAuth 2.0 Authorization Server Metadata
*/
export const OAuthMetadataSchema = z
.object({
issuer: z.string(),
authorization_endpoint: z.string(),
token_endpoint: z.string(),
registration_endpoint: z.string().optional(),
scopes_supported: z.array(z.string()).optional(),
response_types_supported: z.array(z.string()),
response_modes_supported: z.array(z.string()).optional(),
grant_types_supported: z.array(z.string()).optional(),
token_endpoint_auth_methods_supported: z.array(z.string()).optional(),
token_endpoint_auth_signing_alg_values_supported: z
.array(z.string())
.optional(),
service_documentation: z.string().optional(),
revocation_endpoint: z.string().optional(),
revocation_endpoint_auth_methods_supported: z.array(z.string()).optional(),
revocation_endpoint_auth_signing_alg_values_supported: z
.array(z.string())
.optional(),
introspection_endpoint: z.string().optional(),
introspection_endpoint_auth_methods_supported: z
.array(z.string())
.optional(),
introspection_endpoint_auth_signing_alg_values_supported: z
.array(z.string())
.optional(),
code_challenge_methods_supported: z.array(z.string()).optional(),
})
.passthrough();
/**
* OAuth 2.1 token response
*/
export const OAuthTokensSchema = z
.object({
access_token: z.string(),
token_type: z.string(),
expires_in: z.number().optional(),
scope: z.string().optional(),
refresh_token: z.string().optional(),
})
.strip();
/**
* OAuth 2.1 error response
*/
export const OAuthErrorSchema = z
.object({
error: z.string(),
error_description: z.string().optional(),
error_uri: z.string().optional(),
});
/**
* RFC 7591 OAuth 2.0 Dynamic Client Registration metadata
*/
export const OAuthClientMetadataSchema = z.object({
redirect_uris: z.array(z.string()),
token_endpoint_auth_method: z.string().optional(),
grant_types: z.array(z.string()).optional(),
response_types: z.array(z.string()).optional(),
client_name: z.string().optional(),
client_uri: z.string().optional(),
logo_uri: z.string().optional(),
scope: z.string().optional(),
contacts: z.array(z.string()).optional(),
tos_uri: z.string().optional(),
policy_uri: z.string().optional(),
jwks_uri: z.string().optional(),
jwks: z.any().optional(),
software_id: z.string().optional(),
software_version: z.string().optional(),
}).passthrough();
/**
* RFC 7591 OAuth 2.0 Dynamic Client Registration response
*/
export const OAuthClientInformationSchema = OAuthClientMetadataSchema.extend({
client_id: z.string(),
client_secret: z.string().optional(),
client_id_issued_at: z.number().optional(),
client_secret_expires_at: z.number().optional(),
}).passthrough();
/**
* RFC 7591 OAuth 2.0 Dynamic Client Registration error response
*/
export const OAuthClientRegistrationErrorSchema = z.object({
error: z.string(),
error_description: z.string().optional(),
}).strip();
export type OAuthMetadata = z.infer<typeof OAuthMetadataSchema>;
export type OAuthTokens = z.infer<typeof OAuthTokensSchema>;
export type OAuthError = z.infer<typeof OAuthErrorSchema>;
export type OAuthClientMetadata = z.infer<typeof OAuthClientMetadataSchema>;
export type OAuthClientInformation = z.infer<typeof OAuthClientInformationSchema>;
export type OAuthClientRegistrationError = z.infer<typeof OAuthClientRegistrationErrorSchema>;