Files
team/server/public/model/oauth_metadata.go
zeekayandHanzo Dev c4c2c619ab Serve the HTTP API from /v1/team instead of /api/v4
The product namespace is team, and /api/ is not used as a path prefix
here — API hosts carry the api.* name and paths carry the version. This
moves the one constant every route mounts on, so the public router, the
local router and the websocket endpoint all follow it.

The two 404 catch-alls had the old prefix written out by hand, which
meant the constant was not actually the single source of truth; they now
derive from it, as do the emoji, image-proxy, remote-cluster and
self-ping URLs that were each carrying their own copy of the literal.

The remote-cluster path constants gain a leading slash from the shared
constant, so the two call sites that joined them with an explicit
separator would have produced a double slash and are adjusted.

APIURLSuffixV4 was a bare alias of the value and APIURLSuffixV5 mounted
a subrouter that no route ever registered on, so both are gone rather
than carried forward under names that no longer describe anything.
APIURLSuffixV1 is not ours at all — it addresses the external push
notification service — so it keeps its value and is renamed
PushURLSuffix to stop it reading as a version of this API.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-14 10:58:01 -07:00

72 lines
2.4 KiB
Go

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package model
import "net/url"
type AuthorizationServerMetadata struct {
Issuer string `json:"issuer"`
AuthorizationEndpoint string `json:"authorization_endpoint,omitempty"`
TokenEndpoint string `json:"token_endpoint,omitempty"`
ResponseTypesSupported []string `json:"response_types_supported"`
RegistrationEndpoint string `json:"registration_endpoint,omitempty"`
ScopesSupported []string `json:"scopes_supported,omitempty"`
GrantTypesSupported []string `json:"grant_types_supported,omitempty"`
TokenEndpointAuthMethodsSupported []string `json:"token_endpoint_auth_methods_supported,omitempty"`
CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported,omitempty"`
}
const (
GrantTypeAuthorizationCode = "authorization_code"
GrantTypeRefreshToken = "refresh_token"
ResponseTypeCode = "code"
ClientAuthMethodNone = "none"
ClientAuthMethodClientSecretPost = "client_secret_post"
ScopeUser = "user"
)
const (
OAuthAuthorizeEndpoint = "/oauth/authorize"
OAuthAccessTokenEndpoint = "/oauth/access_token"
OAuthDeauthorizeEndpoint = "/oauth/deauthorize"
OAuthAppsRegisterEndpoint = APIURLSuffix + "/oauth/apps/register"
OAuthMetadataEndpoint = "/.well-known/oauth-authorization-server"
)
func GetDefaultMetadata(siteURL string) (*AuthorizationServerMetadata, error) {
authorizationEndpoint, err := url.JoinPath(siteURL, OAuthAuthorizeEndpoint)
if err != nil {
return nil, err
}
tokenEndpoint, err := url.JoinPath(siteURL, OAuthAccessTokenEndpoint)
if err != nil {
return nil, err
}
return &AuthorizationServerMetadata{
Issuer: siteURL,
AuthorizationEndpoint: authorizationEndpoint,
TokenEndpoint: tokenEndpoint,
ResponseTypesSupported: []string{
ResponseTypeCode,
},
GrantTypesSupported: []string{
GrantTypeAuthorizationCode,
GrantTypeRefreshToken,
},
TokenEndpointAuthMethodsSupported: []string{
ClientAuthMethodNone, // Public clients (PKCE)
ClientAuthMethodClientSecretPost, // Confidential clients
},
ScopesSupported: []string{
ScopeUser,
},
CodeChallengeMethodsSupported: []string{
PKCECodeChallengeMethodS256, // S256 method supported for optional PKCE
},
}, nil
}