Compare commits
4 Commits
auth@0.43.
...
auth@0.42.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5fd3cb59c | ||
|
|
f36d360b9e | ||
|
|
61af5087fd | ||
|
|
7429d8ae3f |
@@ -368,7 +368,6 @@
|
||||
"reference/auth/post-user-mfa",
|
||||
"reference/auth/post-user-password",
|
||||
"reference/auth/post-user-password-reset",
|
||||
"reference/auth/get-user-provider-{provider}-tokens",
|
||||
"reference/auth/post-user-webauthn-add",
|
||||
"reference/auth/post-user-webauthn-verify",
|
||||
"reference/auth/get-verify",
|
||||
|
||||
@@ -610,7 +610,7 @@ paths:
|
||||
/signin/provider/{provider}/callback:
|
||||
get:
|
||||
summary: OAuth2 provider callback endpoint
|
||||
description: Handles the callback from OAuth2 providers after user authorization. Processes the authorization code and creates a user session. A cookie with token information is set upon successful authentication. This cookie can be retrieved via the getProviderTokens endpoint
|
||||
description: Handles the callback from OAuth2 providers after user authorization. Processes the authorization code and creates a user session.
|
||||
operationId: signInProviderCallbackGet
|
||||
tags:
|
||||
- authentication
|
||||
@@ -669,10 +669,6 @@ paths:
|
||||
headers:
|
||||
Location:
|
||||
$ref: "#/components/headers/RedirectLocation"
|
||||
Set-Cookie:
|
||||
description: Sets cookie with token information
|
||||
schema:
|
||||
type: string
|
||||
content: {}
|
||||
default:
|
||||
content:
|
||||
@@ -734,10 +730,6 @@ paths:
|
||||
headers:
|
||||
Location:
|
||||
$ref: "#/components/headers/RedirectLocation"
|
||||
Set-Cookie:
|
||||
description: Sets cookie with token information
|
||||
schema:
|
||||
type: string
|
||||
content: {}
|
||||
default:
|
||||
content:
|
||||
@@ -1198,42 +1190,6 @@ paths:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
description: "An error occurred while processing the request"
|
||||
|
||||
/user/provider/{provider}/tokens:
|
||||
get:
|
||||
summary: Get OAuth2 provider tokens from cookies
|
||||
description: Retrieves the OAuth2 provider access and refresh tokens from cookies set during the OAuth2 callback. This endpoint must be called immediately after completing the OAuth2 flow to ensure the tokens are correct. The cookies will be removed after calling this endpoint.
|
||||
operationId: getProviderTokens
|
||||
tags:
|
||||
- authentication
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/SignInProvider"
|
||||
- name: Cookie
|
||||
in: header
|
||||
required: true
|
||||
description: Cookies containing ProviderRefreshToken and ProviderAccessToken
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: Successfully retrieved provider tokens
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/GetProviderTokensResponse"
|
||||
headers:
|
||||
Set-Cookie:
|
||||
description: Removes cookie with token information
|
||||
schema:
|
||||
type: string
|
||||
default:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
description: "An error occurred while processing the request"
|
||||
|
||||
/user/webauthn/add:
|
||||
post:
|
||||
summary: Initialize adding of a new webauthn security key
|
||||
@@ -1651,24 +1607,6 @@ components:
|
||||
- message
|
||||
- error
|
||||
|
||||
GetProviderTokensResponse:
|
||||
type: object
|
||||
description: "OAuth2 provider tokens retrieved from cookies"
|
||||
additionalProperties: false
|
||||
properties:
|
||||
accessToken:
|
||||
type: string
|
||||
description: "OAuth2 provider access token"
|
||||
example: "ya29.a0AfH6SMBx..."
|
||||
refreshToken:
|
||||
type: string
|
||||
nullable: true
|
||||
description: "OAuth2 provider refresh token (if available)"
|
||||
example: "1//0gK8..."
|
||||
required:
|
||||
- accessToken
|
||||
|
||||
|
||||
IdTokenProvider:
|
||||
type: string
|
||||
additionalProperties: false
|
||||
@@ -2574,6 +2512,7 @@ components:
|
||||
- facebook
|
||||
- windowslive
|
||||
- twitter
|
||||
deprecated: true
|
||||
|
||||
TicketQuery:
|
||||
in: query
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
title: "getProviderTokens"
|
||||
openapi: get /user/provider/{provider}/tokens
|
||||
sidebarTitle: /user/provider/{provider}/tokens
|
||||
---
|
||||
@@ -468,30 +468,6 @@ This method may return different T based on the response code:
|
||||
|
||||
`Promise`<[`FetchResponse`](./fetch#fetchresponse)<[`JWKSet`](#jwkset)>>
|
||||
|
||||
#### getProviderTokens()
|
||||
|
||||
```ts
|
||||
getProviderTokens(provider: SignInProvider, options?: RequestInit): Promise<FetchResponse<GetProviderTokensResponse>>;
|
||||
```
|
||||
|
||||
Summary: Get OAuth2 provider tokens from cookies
|
||||
Retrieves the OAuth2 provider access and refresh tokens from cookies set during the OAuth2 callback. This endpoint must be called immediately after completing the OAuth2 flow to ensure the tokens are correct. The cookies will be removed after calling this endpoint.
|
||||
|
||||
This method may return different T based on the response code:
|
||||
|
||||
- 200: GetProviderTokensResponse
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Parameter | Type |
|
||||
| ---------- | ----------------------------------- |
|
||||
| `provider` | [`SignInProvider`](#signinprovider) |
|
||||
| `options?` | `RequestInit` |
|
||||
|
||||
##### Returns
|
||||
|
||||
`Promise`<[`FetchResponse`](./fetch#fetchresponse)<[`GetProviderTokensResponse`](#getprovidertokensresponse)>>
|
||||
|
||||
#### getUser()
|
||||
|
||||
```ts
|
||||
@@ -1466,33 +1442,6 @@ status: number
|
||||
|
||||
---
|
||||
|
||||
## GetProviderTokensResponse
|
||||
|
||||
OAuth2 provider tokens retrieved from cookies
|
||||
|
||||
### Properties
|
||||
|
||||
#### accessToken
|
||||
|
||||
```ts
|
||||
accessToken: string
|
||||
```
|
||||
|
||||
(`string`) - OAuth2 provider access token
|
||||
|
||||
- Example - `"ya29.a0AfH6SMBx..."`
|
||||
|
||||
#### refreshToken?
|
||||
|
||||
```ts
|
||||
optional refreshToken: string;
|
||||
```
|
||||
|
||||
OAuth2 provider refresh token (if available)
|
||||
Example - `"1//0gK8..."`
|
||||
|
||||
---
|
||||
|
||||
## GetVersionResponse200
|
||||
|
||||
### Properties
|
||||
|
||||
@@ -454,7 +454,7 @@ Example - `"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."`
|
||||
|
||||
##### Inherited from
|
||||
|
||||
[`Session`](./auth#session).[`accessToken`](./auth#accesstoken-1)
|
||||
[`Session`](./auth#session).[`accessToken`](./auth#accesstoken)
|
||||
|
||||
#### accessTokenExpiresIn
|
||||
|
||||
@@ -490,7 +490,7 @@ Pattern - \b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b
|
||||
|
||||
##### Inherited from
|
||||
|
||||
[`Session`](./auth#session).[`refreshToken`](./auth#refreshtoken-4)
|
||||
[`Session`](./auth#session).[`refreshToken`](./auth#refreshtoken-3)
|
||||
|
||||
#### refreshTokenId
|
||||
|
||||
|
||||
@@ -363,25 +363,6 @@ export interface ErrorResponse {
|
||||
error: ErrorResponseError;
|
||||
}
|
||||
|
||||
/**
|
||||
* OAuth2 provider tokens retrieved from cookies
|
||||
@property accessToken (`string`) - OAuth2 provider access token
|
||||
* Example - `"ya29.a0AfH6SMBx..."`
|
||||
@property refreshToken? (`string`) - OAuth2 provider refresh token (if available)
|
||||
* Example - `"1//0gK8..."`*/
|
||||
export interface GetProviderTokensResponse {
|
||||
/**
|
||||
* OAuth2 provider access token
|
||||
* Example - `"ya29.a0AfH6SMBx..."`
|
||||
*/
|
||||
accessToken: string;
|
||||
/**
|
||||
* OAuth2 provider refresh token (if available)
|
||||
* Example - `"1//0gK8..."`
|
||||
*/
|
||||
refreshToken?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -2027,18 +2008,6 @@ export interface Client {
|
||||
options?: RequestInit,
|
||||
): Promise<FetchResponse<OKResponse>>;
|
||||
|
||||
/**
|
||||
Summary: Get OAuth2 provider tokens from cookies
|
||||
Retrieves the OAuth2 provider access and refresh tokens from cookies set during the OAuth2 callback. This endpoint must be called immediately after completing the OAuth2 flow to ensure the tokens are correct. The cookies will be removed after calling this endpoint.
|
||||
|
||||
This method may return different T based on the response code:
|
||||
- 200: GetProviderTokensResponse
|
||||
*/
|
||||
getProviderTokens(
|
||||
provider: SignInProvider,
|
||||
options?: RequestInit,
|
||||
): Promise<FetchResponse<GetProviderTokensResponse>>;
|
||||
|
||||
/**
|
||||
Summary: Initialize adding of a new webauthn security key
|
||||
Start the process of adding a new WebAuthn security key to the user's account. Returns a challenge that must be completed by the user's authenticator device. Requires elevated permissions.
|
||||
@@ -3215,39 +3184,6 @@ export const createAPIClient = (
|
||||
} as FetchResponse<OKResponse>;
|
||||
};
|
||||
|
||||
const getProviderTokens = async (
|
||||
provider: SignInProvider,
|
||||
options?: RequestInit,
|
||||
): Promise<FetchResponse<GetProviderTokensResponse>> => {
|
||||
const url = `${baseURL}/user/provider/${provider}/tokens`;
|
||||
const res = await fetch(url, {
|
||||
...options,
|
||||
method: "GET",
|
||||
headers: {
|
||||
...options?.headers,
|
||||
},
|
||||
});
|
||||
|
||||
if (res.status >= 300) {
|
||||
const responseBody = [412].includes(res.status) ? null : await res.text();
|
||||
const payload: unknown = responseBody ? JSON.parse(responseBody) : {};
|
||||
throw new FetchError(payload, res.status, res.headers);
|
||||
}
|
||||
|
||||
const responseBody = [204, 205, 304].includes(res.status)
|
||||
? null
|
||||
: await res.text();
|
||||
const payload: GetProviderTokensResponse = responseBody
|
||||
? JSON.parse(responseBody)
|
||||
: {};
|
||||
|
||||
return {
|
||||
body: payload,
|
||||
status: res.status,
|
||||
headers: res.headers,
|
||||
} as FetchResponse<GetProviderTokensResponse>;
|
||||
};
|
||||
|
||||
const addSecurityKey = async (
|
||||
options?: RequestInit,
|
||||
): Promise<FetchResponse<PublicKeyCredentialCreationOptions>> => {
|
||||
@@ -3404,7 +3340,6 @@ export const createAPIClient = (
|
||||
verifyChangeUserMfa,
|
||||
changeUserPassword,
|
||||
sendPasswordResetEmail,
|
||||
getProviderTokens,
|
||||
addSecurityKey,
|
||||
verifyAddSecurityKey,
|
||||
verifyTicketURL,
|
||||
|
||||
@@ -2,6 +2,23 @@
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [auth@0.42.4] - 2025-10-20
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- *(auth)* Apply relationships on new projects (#3617)
|
||||
|
||||
## [auth@0.42.3] - 2025-10-20
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- *(auth)* Always apply expected metadata (#3616)
|
||||
|
||||
|
||||
### ⚙️ Miscellaneous Tasks
|
||||
|
||||
- *(storage)* Migrate to urfave and slog libraries (#3606)
|
||||
|
||||
## [auth@0.42.2] - 2025-10-13
|
||||
|
||||
### ⚙️ Miscellaneous Tasks
|
||||
|
||||
@@ -610,7 +610,7 @@ paths:
|
||||
/signin/provider/{provider}/callback:
|
||||
get:
|
||||
summary: OAuth2 provider callback endpoint
|
||||
description: Handles the callback from OAuth2 providers after user authorization. Processes the authorization code and creates a user session. A cookie with token information is set upon successful authentication. This cookie can be retrieved via the getProviderTokens endpoint
|
||||
description: Handles the callback from OAuth2 providers after user authorization. Processes the authorization code and creates a user session.
|
||||
operationId: signInProviderCallbackGet
|
||||
tags:
|
||||
- authentication
|
||||
@@ -669,10 +669,6 @@ paths:
|
||||
headers:
|
||||
Location:
|
||||
$ref: "#/components/headers/RedirectLocation"
|
||||
Set-Cookie:
|
||||
description: Sets cookie with token information
|
||||
schema:
|
||||
type: string
|
||||
content: {}
|
||||
default:
|
||||
content:
|
||||
@@ -734,10 +730,6 @@ paths:
|
||||
headers:
|
||||
Location:
|
||||
$ref: "#/components/headers/RedirectLocation"
|
||||
Set-Cookie:
|
||||
description: Sets cookie with token information
|
||||
schema:
|
||||
type: string
|
||||
content: {}
|
||||
default:
|
||||
content:
|
||||
@@ -1198,42 +1190,6 @@ paths:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
description: "An error occurred while processing the request"
|
||||
|
||||
/user/provider/{provider}/tokens:
|
||||
get:
|
||||
summary: Get OAuth2 provider tokens from cookies
|
||||
description: Retrieves the OAuth2 provider access and refresh tokens from cookies set during the OAuth2 callback. This endpoint must be called immediately after completing the OAuth2 flow to ensure the tokens are correct. The cookies will be removed after calling this endpoint.
|
||||
operationId: getProviderTokens
|
||||
tags:
|
||||
- authentication
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/SignInProvider"
|
||||
- name: Cookie
|
||||
in: header
|
||||
required: true
|
||||
description: Cookies containing ProviderRefreshToken and ProviderAccessToken
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: Successfully retrieved provider tokens
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/GetProviderTokensResponse"
|
||||
headers:
|
||||
Set-Cookie:
|
||||
description: Removes cookie with token information
|
||||
schema:
|
||||
type: string
|
||||
default:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
description: "An error occurred while processing the request"
|
||||
|
||||
/user/webauthn/add:
|
||||
post:
|
||||
summary: Initialize adding of a new webauthn security key
|
||||
@@ -1651,24 +1607,6 @@ components:
|
||||
- message
|
||||
- error
|
||||
|
||||
GetProviderTokensResponse:
|
||||
type: object
|
||||
description: "OAuth2 provider tokens retrieved from cookies"
|
||||
additionalProperties: false
|
||||
properties:
|
||||
accessToken:
|
||||
type: string
|
||||
description: "OAuth2 provider access token"
|
||||
example: "ya29.a0AfH6SMBx..."
|
||||
refreshToken:
|
||||
type: string
|
||||
nullable: true
|
||||
description: "OAuth2 provider refresh token (if available)"
|
||||
example: "1//0gK8..."
|
||||
required:
|
||||
- accessToken
|
||||
|
||||
|
||||
IdTokenProvider:
|
||||
type: string
|
||||
additionalProperties: false
|
||||
@@ -2574,6 +2512,7 @@ components:
|
||||
- facebook
|
||||
- windowslive
|
||||
- twitter
|
||||
deprecated: true
|
||||
|
||||
TicketQuery:
|
||||
in: query
|
||||
|
||||
@@ -133,9 +133,6 @@ type ServerInterface interface {
|
||||
// Request password reset
|
||||
// (POST /user/password/reset)
|
||||
SendPasswordResetEmail(c *gin.Context)
|
||||
// Get OAuth2 provider tokens from cookies
|
||||
// (GET /user/provider/{provider}/tokens)
|
||||
GetProviderTokens(c *gin.Context, provider GetProviderTokensParamsProvider, params GetProviderTokensParams)
|
||||
// Initialize adding of a new webauthn security key
|
||||
// (POST /user/webauthn/add)
|
||||
AddSecurityKey(c *gin.Context)
|
||||
@@ -824,59 +821,6 @@ func (siw *ServerInterfaceWrapper) SendPasswordResetEmail(c *gin.Context) {
|
||||
siw.Handler.SendPasswordResetEmail(c)
|
||||
}
|
||||
|
||||
// GetProviderTokens operation middleware
|
||||
func (siw *ServerInterfaceWrapper) GetProviderTokens(c *gin.Context) {
|
||||
|
||||
var err error
|
||||
|
||||
// ------------- Path parameter "provider" -------------
|
||||
var provider GetProviderTokensParamsProvider
|
||||
|
||||
err = runtime.BindStyledParameterWithOptions("simple", "provider", c.Param("provider"), &provider, runtime.BindStyledParameterOptions{Explode: false, Required: true})
|
||||
if err != nil {
|
||||
siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter provider: %w", err), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
c.Set(BearerAuthScopes, []string{})
|
||||
|
||||
// Parameter object where we will unmarshal all parameters from the context
|
||||
var params GetProviderTokensParams
|
||||
|
||||
headers := c.Request.Header
|
||||
|
||||
// ------------- Required header parameter "Cookie" -------------
|
||||
if valueList, found := headers[http.CanonicalHeaderKey("Cookie")]; found {
|
||||
var Cookie string
|
||||
n := len(valueList)
|
||||
if n != 1 {
|
||||
siw.ErrorHandler(c, fmt.Errorf("Expected one value for Cookie, got %d", n), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
err = runtime.BindStyledParameterWithOptions("simple", "Cookie", valueList[0], &Cookie, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true})
|
||||
if err != nil {
|
||||
siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter Cookie: %w", err), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
params.Cookie = Cookie
|
||||
|
||||
} else {
|
||||
siw.ErrorHandler(c, fmt.Errorf("Header parameter Cookie is required, but not found"), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
for _, middleware := range siw.HandlerMiddlewares {
|
||||
middleware(c)
|
||||
if c.IsAborted() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
siw.Handler.GetProviderTokens(c, provider, params)
|
||||
}
|
||||
|
||||
// AddSecurityKey operation middleware
|
||||
func (siw *ServerInterfaceWrapper) AddSecurityKey(c *gin.Context) {
|
||||
|
||||
@@ -1039,7 +983,6 @@ func RegisterHandlersWithOptions(router gin.IRouter, si ServerInterface, options
|
||||
router.POST(options.BaseURL+"/user/mfa", wrapper.VerifyChangeUserMfa)
|
||||
router.POST(options.BaseURL+"/user/password", wrapper.ChangeUserPassword)
|
||||
router.POST(options.BaseURL+"/user/password/reset", wrapper.SendPasswordResetEmail)
|
||||
router.GET(options.BaseURL+"/user/provider/:provider/tokens", wrapper.GetProviderTokens)
|
||||
router.POST(options.BaseURL+"/user/webauthn/add", wrapper.AddSecurityKey)
|
||||
router.POST(options.BaseURL+"/user/webauthn/verify", wrapper.VerifyAddSecurityKey)
|
||||
router.GET(options.BaseURL+"/verify", wrapper.VerifyTicket)
|
||||
@@ -1607,8 +1550,7 @@ type SignInProviderCallbackGetResponseObject interface {
|
||||
}
|
||||
|
||||
type SignInProviderCallbackGet302ResponseHeaders struct {
|
||||
Location string
|
||||
SetCookie string
|
||||
Location string
|
||||
}
|
||||
|
||||
type SignInProviderCallbackGet302Response struct {
|
||||
@@ -1617,7 +1559,6 @@ type SignInProviderCallbackGet302Response struct {
|
||||
|
||||
func (response SignInProviderCallbackGet302Response) VisitSignInProviderCallbackGetResponse(w http.ResponseWriter) error {
|
||||
w.Header().Set("Location", fmt.Sprint(response.Headers.Location))
|
||||
w.Header().Set("Set-Cookie", fmt.Sprint(response.Headers.SetCookie))
|
||||
w.WriteHeader(302)
|
||||
return nil
|
||||
}
|
||||
@@ -1644,8 +1585,7 @@ type SignInProviderCallbackPostResponseObject interface {
|
||||
}
|
||||
|
||||
type SignInProviderCallbackPost302ResponseHeaders struct {
|
||||
Location string
|
||||
SetCookie string
|
||||
Location string
|
||||
}
|
||||
|
||||
type SignInProviderCallbackPost302Response struct {
|
||||
@@ -1654,7 +1594,6 @@ type SignInProviderCallbackPost302Response struct {
|
||||
|
||||
func (response SignInProviderCallbackPost302Response) VisitSignInProviderCallbackPostResponse(w http.ResponseWriter) error {
|
||||
w.Header().Set("Location", fmt.Sprint(response.Headers.Location))
|
||||
w.Header().Set("Set-Cookie", fmt.Sprint(response.Headers.SetCookie))
|
||||
w.WriteHeader(302)
|
||||
return nil
|
||||
}
|
||||
@@ -2105,44 +2044,6 @@ func (response SendPasswordResetEmaildefaultJSONResponse) VisitSendPasswordReset
|
||||
return json.NewEncoder(w).Encode(response.Body)
|
||||
}
|
||||
|
||||
type GetProviderTokensRequestObject struct {
|
||||
Provider GetProviderTokensParamsProvider `json:"provider"`
|
||||
Params GetProviderTokensParams
|
||||
}
|
||||
|
||||
type GetProviderTokensResponseObject interface {
|
||||
VisitGetProviderTokensResponse(w http.ResponseWriter) error
|
||||
}
|
||||
|
||||
type GetProviderTokens200ResponseHeaders struct {
|
||||
SetCookie string
|
||||
}
|
||||
|
||||
type GetProviderTokens200JSONResponse struct {
|
||||
Body GetProviderTokensResponse
|
||||
Headers GetProviderTokens200ResponseHeaders
|
||||
}
|
||||
|
||||
func (response GetProviderTokens200JSONResponse) VisitGetProviderTokensResponse(w http.ResponseWriter) error {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Set-Cookie", fmt.Sprint(response.Headers.SetCookie))
|
||||
w.WriteHeader(200)
|
||||
|
||||
return json.NewEncoder(w).Encode(response.Body)
|
||||
}
|
||||
|
||||
type GetProviderTokensdefaultJSONResponse struct {
|
||||
Body ErrorResponse
|
||||
StatusCode int
|
||||
}
|
||||
|
||||
func (response GetProviderTokensdefaultJSONResponse) VisitGetProviderTokensResponse(w http.ResponseWriter) error {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(response.StatusCode)
|
||||
|
||||
return json.NewEncoder(w).Encode(response.Body)
|
||||
}
|
||||
|
||||
type AddSecurityKeyRequestObject struct {
|
||||
}
|
||||
|
||||
@@ -2375,9 +2276,6 @@ type StrictServerInterface interface {
|
||||
// Request password reset
|
||||
// (POST /user/password/reset)
|
||||
SendPasswordResetEmail(ctx context.Context, request SendPasswordResetEmailRequestObject) (SendPasswordResetEmailResponseObject, error)
|
||||
// Get OAuth2 provider tokens from cookies
|
||||
// (GET /user/provider/{provider}/tokens)
|
||||
GetProviderTokens(ctx context.Context, request GetProviderTokensRequestObject) (GetProviderTokensResponseObject, error)
|
||||
// Initialize adding of a new webauthn security key
|
||||
// (POST /user/webauthn/add)
|
||||
AddSecurityKey(ctx context.Context, request AddSecurityKeyRequestObject) (AddSecurityKeyResponseObject, error)
|
||||
@@ -3545,34 +3443,6 @@ func (sh *strictHandler) SendPasswordResetEmail(ctx *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// GetProviderTokens operation middleware
|
||||
func (sh *strictHandler) GetProviderTokens(ctx *gin.Context, provider GetProviderTokensParamsProvider, params GetProviderTokensParams) {
|
||||
var request GetProviderTokensRequestObject
|
||||
|
||||
request.Provider = provider
|
||||
request.Params = params
|
||||
|
||||
handler := func(ctx *gin.Context, request interface{}) (interface{}, error) {
|
||||
return sh.ssi.GetProviderTokens(ctx, request.(GetProviderTokensRequestObject))
|
||||
}
|
||||
for _, middleware := range sh.middlewares {
|
||||
handler = middleware(handler, "GetProviderTokens")
|
||||
}
|
||||
|
||||
response, err := handler(ctx, request)
|
||||
|
||||
if err != nil {
|
||||
ctx.Error(err)
|
||||
ctx.Status(http.StatusInternalServerError)
|
||||
} else if validResponse, ok := response.(GetProviderTokensResponseObject); ok {
|
||||
if err := validResponse.VisitGetProviderTokensResponse(ctx.Writer); err != nil {
|
||||
ctx.Error(err)
|
||||
}
|
||||
} else if response != nil {
|
||||
ctx.Error(fmt.Errorf("unexpected response type: %T", response))
|
||||
}
|
||||
}
|
||||
|
||||
// AddSecurityKey operation middleware
|
||||
func (sh *strictHandler) AddSecurityKey(ctx *gin.Context) {
|
||||
var request AddSecurityKeyRequestObject
|
||||
@@ -3686,177 +3556,171 @@ func (sh *strictHandler) GetVersion(ctx *gin.Context) {
|
||||
// Base64 encoded, gzipped, json marshaled Swagger object
|
||||
var swaggerSpec = []string{
|
||||
|
||||
"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",
|
||||
"q3C1rf8AAA==",
|
||||
"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",
|
||||
"AP//J2Dqrmj4AAA=",
|
||||
}
|
||||
|
||||
// GetSwagger returns the content of the embedded swagger specification file
|
||||
|
||||
@@ -206,42 +206,22 @@ const (
|
||||
|
||||
// Defines values for SignInProviderCallbackPostParamsProvider.
|
||||
const (
|
||||
SignInProviderCallbackPostParamsProviderApple SignInProviderCallbackPostParamsProvider = "apple"
|
||||
SignInProviderCallbackPostParamsProviderAzuread SignInProviderCallbackPostParamsProvider = "azuread"
|
||||
SignInProviderCallbackPostParamsProviderBitbucket SignInProviderCallbackPostParamsProvider = "bitbucket"
|
||||
SignInProviderCallbackPostParamsProviderDiscord SignInProviderCallbackPostParamsProvider = "discord"
|
||||
SignInProviderCallbackPostParamsProviderEntraid SignInProviderCallbackPostParamsProvider = "entraid"
|
||||
SignInProviderCallbackPostParamsProviderFacebook SignInProviderCallbackPostParamsProvider = "facebook"
|
||||
SignInProviderCallbackPostParamsProviderGithub SignInProviderCallbackPostParamsProvider = "github"
|
||||
SignInProviderCallbackPostParamsProviderGitlab SignInProviderCallbackPostParamsProvider = "gitlab"
|
||||
SignInProviderCallbackPostParamsProviderGoogle SignInProviderCallbackPostParamsProvider = "google"
|
||||
SignInProviderCallbackPostParamsProviderLinkedin SignInProviderCallbackPostParamsProvider = "linkedin"
|
||||
SignInProviderCallbackPostParamsProviderSpotify SignInProviderCallbackPostParamsProvider = "spotify"
|
||||
SignInProviderCallbackPostParamsProviderStrava SignInProviderCallbackPostParamsProvider = "strava"
|
||||
SignInProviderCallbackPostParamsProviderTwitch SignInProviderCallbackPostParamsProvider = "twitch"
|
||||
SignInProviderCallbackPostParamsProviderTwitter SignInProviderCallbackPostParamsProvider = "twitter"
|
||||
SignInProviderCallbackPostParamsProviderWindowslive SignInProviderCallbackPostParamsProvider = "windowslive"
|
||||
SignInProviderCallbackPostParamsProviderWorkos SignInProviderCallbackPostParamsProvider = "workos"
|
||||
)
|
||||
|
||||
// Defines values for GetProviderTokensParamsProvider.
|
||||
const (
|
||||
GetProviderTokensParamsProviderApple GetProviderTokensParamsProvider = "apple"
|
||||
GetProviderTokensParamsProviderAzuread GetProviderTokensParamsProvider = "azuread"
|
||||
GetProviderTokensParamsProviderBitbucket GetProviderTokensParamsProvider = "bitbucket"
|
||||
GetProviderTokensParamsProviderDiscord GetProviderTokensParamsProvider = "discord"
|
||||
GetProviderTokensParamsProviderEntraid GetProviderTokensParamsProvider = "entraid"
|
||||
GetProviderTokensParamsProviderFacebook GetProviderTokensParamsProvider = "facebook"
|
||||
GetProviderTokensParamsProviderGithub GetProviderTokensParamsProvider = "github"
|
||||
GetProviderTokensParamsProviderGitlab GetProviderTokensParamsProvider = "gitlab"
|
||||
GetProviderTokensParamsProviderGoogle GetProviderTokensParamsProvider = "google"
|
||||
GetProviderTokensParamsProviderLinkedin GetProviderTokensParamsProvider = "linkedin"
|
||||
GetProviderTokensParamsProviderSpotify GetProviderTokensParamsProvider = "spotify"
|
||||
GetProviderTokensParamsProviderStrava GetProviderTokensParamsProvider = "strava"
|
||||
GetProviderTokensParamsProviderTwitch GetProviderTokensParamsProvider = "twitch"
|
||||
GetProviderTokensParamsProviderTwitter GetProviderTokensParamsProvider = "twitter"
|
||||
GetProviderTokensParamsProviderWindowslive GetProviderTokensParamsProvider = "windowslive"
|
||||
GetProviderTokensParamsProviderWorkos GetProviderTokensParamsProvider = "workos"
|
||||
Apple SignInProviderCallbackPostParamsProvider = "apple"
|
||||
Azuread SignInProviderCallbackPostParamsProvider = "azuread"
|
||||
Bitbucket SignInProviderCallbackPostParamsProvider = "bitbucket"
|
||||
Discord SignInProviderCallbackPostParamsProvider = "discord"
|
||||
Entraid SignInProviderCallbackPostParamsProvider = "entraid"
|
||||
Facebook SignInProviderCallbackPostParamsProvider = "facebook"
|
||||
Github SignInProviderCallbackPostParamsProvider = "github"
|
||||
Gitlab SignInProviderCallbackPostParamsProvider = "gitlab"
|
||||
Google SignInProviderCallbackPostParamsProvider = "google"
|
||||
Linkedin SignInProviderCallbackPostParamsProvider = "linkedin"
|
||||
Spotify SignInProviderCallbackPostParamsProvider = "spotify"
|
||||
Strava SignInProviderCallbackPostParamsProvider = "strava"
|
||||
Twitch SignInProviderCallbackPostParamsProvider = "twitch"
|
||||
Twitter SignInProviderCallbackPostParamsProvider = "twitter"
|
||||
Windowslive SignInProviderCallbackPostParamsProvider = "windowslive"
|
||||
Workos SignInProviderCallbackPostParamsProvider = "workos"
|
||||
)
|
||||
|
||||
// Defines values for VerifyTicketParamsType.
|
||||
@@ -386,15 +366,6 @@ type ErrorResponse struct {
|
||||
// ErrorResponseError Error code identifying the specific application error
|
||||
type ErrorResponseError string
|
||||
|
||||
// GetProviderTokensResponse OAuth2 provider tokens retrieved from cookies
|
||||
type GetProviderTokensResponse struct {
|
||||
// AccessToken OAuth2 provider access token
|
||||
AccessToken string `json:"accessToken"`
|
||||
|
||||
// RefreshToken OAuth2 provider refresh token (if available)
|
||||
RefreshToken *string `json:"refreshToken"`
|
||||
}
|
||||
|
||||
// IdTokenProvider defines model for IdTokenProvider.
|
||||
type IdTokenProvider string
|
||||
|
||||
@@ -936,15 +907,6 @@ type SignInProviderCallbackPostFormdataBody struct {
|
||||
// SignInProviderCallbackPostParamsProvider defines parameters for SignInProviderCallbackPost.
|
||||
type SignInProviderCallbackPostParamsProvider string
|
||||
|
||||
// GetProviderTokensParams defines parameters for GetProviderTokens.
|
||||
type GetProviderTokensParams struct {
|
||||
// Cookie Cookies containing ProviderRefreshToken and ProviderAccessToken
|
||||
Cookie string `json:"Cookie"`
|
||||
}
|
||||
|
||||
// GetProviderTokensParamsProvider defines parameters for GetProviderTokens.
|
||||
type GetProviderTokensParamsProvider string
|
||||
|
||||
// VerifyTicketParams defines parameters for VerifyTicket.
|
||||
type VerifyTicketParams struct {
|
||||
// Ticket Ticket
|
||||
|
||||
@@ -224,10 +224,6 @@ func (response ErrorResponse) VisitGetUserResponse(w http.ResponseWriter) error
|
||||
return response.visit(w)
|
||||
}
|
||||
|
||||
func (response ErrorResponse) VisitGetProviderTokensResponse(w http.ResponseWriter) error {
|
||||
return response.visit(w)
|
||||
}
|
||||
|
||||
func (response ErrorResponse) VisitVerifySignInPasswordlessSmsResponse(
|
||||
w http.ResponseWriter,
|
||||
) error {
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/nhost/nhost/services/auth/go/api"
|
||||
"github.com/nhost/nhost/services/auth/go/middleware"
|
||||
)
|
||||
|
||||
func getCookie(
|
||||
ctx context.Context, name string, cookieHeader string, logger *slog.Logger,
|
||||
) *http.Cookie {
|
||||
cookies := strings.SplitSeq(cookieHeader, ";")
|
||||
|
||||
for c := range cookies {
|
||||
cookie, err := http.ParseSetCookie(c)
|
||||
if err != nil {
|
||||
logger.WarnContext(ctx, "error parsing cookie", logError(err))
|
||||
continue
|
||||
}
|
||||
|
||||
if cookie.Name == name {
|
||||
return cookie
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ctrl *Controller) GetProviderTokens( //nolint:ireturn
|
||||
ctx context.Context,
|
||||
req api.GetProviderTokensRequestObject,
|
||||
) (api.GetProviderTokensResponseObject, error) {
|
||||
logger := middleware.LoggerFromContext(ctx)
|
||||
logger = logger.With("provider", req.Provider)
|
||||
|
||||
_, apiErr := ctrl.wf.GetJWTInContext(ctx, logger)
|
||||
if apiErr != nil {
|
||||
return ctrl.sendError(apiErr), nil
|
||||
}
|
||||
|
||||
cookieName := string(req.Provider) + cookieSuffixProviderToken
|
||||
cookie := getCookie(ctx, cookieName, req.Params.Cookie, logger)
|
||||
|
||||
var (
|
||||
accessToken string
|
||||
refreshToken *string
|
||||
)
|
||||
if cookie != nil {
|
||||
v, err := url.QueryUnescape(cookie.Value)
|
||||
if err != nil {
|
||||
logger.WarnContext(ctx, "error unescaping cookie value", logError(err))
|
||||
return ctrl.sendError(ErrInternalServerError), nil
|
||||
}
|
||||
|
||||
var m map[string]any
|
||||
if err := json.NewDecoder(strings.NewReader(v)).Decode(&m); err != nil {
|
||||
logger.WarnContext(ctx, "error decoding cookie value", logError(err))
|
||||
return ctrl.sendError(ErrInternalServerError), nil
|
||||
}
|
||||
|
||||
accessToken, _ = m["accessToken"].(string)
|
||||
rt, _ := m["refreshToken"].(string)
|
||||
|
||||
if rt != "" {
|
||||
refreshToken = &rt
|
||||
}
|
||||
}
|
||||
|
||||
return api.GetProviderTokens200JSONResponse{
|
||||
Body: api.GetProviderTokensResponse{
|
||||
AccessToken: accessToken,
|
||||
RefreshToken: refreshToken,
|
||||
},
|
||||
Headers: api.GetProviderTokens200ResponseHeaders{
|
||||
SetCookie: providerCookies(
|
||||
string(req.Provider), "", "", ctrl.config.UseSecureCookies(), -1,
|
||||
),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
@@ -1,195 +0,0 @@
|
||||
package controller_test
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/nhost/nhost/services/auth/go/api"
|
||||
"github.com/nhost/nhost/services/auth/go/controller"
|
||||
"github.com/nhost/nhost/services/auth/go/controller/mock"
|
||||
"go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
func TestGetProviderTokens(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
jwtTokenFn := func() *jwt.Token {
|
||||
return &jwt.Token{
|
||||
Raw: "",
|
||||
Method: jwt.SigningMethodHS256,
|
||||
Header: map[string]any{
|
||||
"alg": "HS256",
|
||||
"typ": "JWT",
|
||||
},
|
||||
Claims: jwt.MapClaims{
|
||||
"exp": float64(time.Now().Add(900 * time.Second).Unix()),
|
||||
"https://hasura.io/jwt/claims": map[string]any{
|
||||
"x-hasura-allowed-roles": []any{"anonymous"},
|
||||
"x-hasura-default-role": "anonymous",
|
||||
"x-hasura-user-id": "db477732-48fa-4289-b694-2886a646b6eb",
|
||||
"x-hasura-user-is-anonymous": "true",
|
||||
},
|
||||
"iat": float64(time.Now().Unix()),
|
||||
"iss": "hasura-auth",
|
||||
"sub": "db477732-48fa-4289-b694-2886a646b6eb",
|
||||
},
|
||||
Signature: []byte{},
|
||||
Valid: true,
|
||||
}
|
||||
}
|
||||
|
||||
cases := []testRequest[api.GetProviderTokensRequestObject, api.GetProviderTokensResponseObject]{
|
||||
{
|
||||
name: "success - one cookie",
|
||||
config: getConfig,
|
||||
db: func(ctrl *gomock.Controller) controller.DBClient {
|
||||
mock := mock.NewMockDBClient(ctrl)
|
||||
return mock
|
||||
},
|
||||
request: api.GetProviderTokensRequestObject{
|
||||
Provider: "fake",
|
||||
Params: api.GetProviderTokensParams{
|
||||
Cookie: "fakeProviderTokens=%7B%22accessToken%22%3A%22valid-accesstoken-1%22%2C%22refreshToken%22%3A%22valid-refreshtoken-1%22%7D;", //nolint:lll
|
||||
},
|
||||
},
|
||||
expectedResponse: api.GetProviderTokens200JSONResponse{
|
||||
Headers: api.GetProviderTokens200ResponseHeaders{
|
||||
SetCookie: "fakeProviderTokens=; Path=/; Max-Age=0; HttpOnly; Secure; SameSite=Strict",
|
||||
},
|
||||
Body: api.GetProviderTokensResponse{
|
||||
AccessToken: "valid-accesstoken-1",
|
||||
RefreshToken: ptr("valid-refreshtoken-1"),
|
||||
},
|
||||
},
|
||||
expectedJWT: nil,
|
||||
jwtTokenFn: jwtTokenFn,
|
||||
getControllerOpts: nil,
|
||||
},
|
||||
|
||||
{
|
||||
name: "success - more cookies",
|
||||
config: getConfig,
|
||||
db: func(ctrl *gomock.Controller) controller.DBClient {
|
||||
mock := mock.NewMockDBClient(ctrl)
|
||||
return mock
|
||||
},
|
||||
request: api.GetProviderTokensRequestObject{
|
||||
Provider: "fake",
|
||||
Params: api.GetProviderTokensParams{
|
||||
Cookie: "someCookie=; fakeProviderTokens=%7B%22accessToken%22%3A%22valid-accesstoken-1%22%2C%22refreshToken%22%3A%22valid-refreshtoken-1%22%7D;", //nolint:lll
|
||||
},
|
||||
},
|
||||
expectedResponse: api.GetProviderTokens200JSONResponse{
|
||||
Headers: api.GetProviderTokens200ResponseHeaders{
|
||||
SetCookie: "fakeProviderTokens=; Path=/; Max-Age=0; HttpOnly; Secure; SameSite=Strict",
|
||||
},
|
||||
Body: api.GetProviderTokensResponse{
|
||||
AccessToken: "valid-accesstoken-1",
|
||||
RefreshToken: ptr("valid-refreshtoken-1"),
|
||||
},
|
||||
},
|
||||
expectedJWT: nil,
|
||||
jwtTokenFn: jwtTokenFn,
|
||||
getControllerOpts: nil,
|
||||
},
|
||||
|
||||
{
|
||||
name: "success - missing cookie",
|
||||
config: getConfig,
|
||||
db: func(ctrl *gomock.Controller) controller.DBClient {
|
||||
mock := mock.NewMockDBClient(ctrl)
|
||||
return mock
|
||||
},
|
||||
request: api.GetProviderTokensRequestObject{
|
||||
Provider: "fake",
|
||||
Params: api.GetProviderTokensParams{
|
||||
Cookie: "someCookie=;",
|
||||
},
|
||||
},
|
||||
expectedResponse: api.GetProviderTokens200JSONResponse{
|
||||
Headers: api.GetProviderTokens200ResponseHeaders{
|
||||
SetCookie: "fakeProviderTokens=; Path=/; Max-Age=0; HttpOnly; Secure; SameSite=Strict",
|
||||
},
|
||||
Body: api.GetProviderTokensResponse{
|
||||
AccessToken: "",
|
||||
RefreshToken: nil,
|
||||
},
|
||||
},
|
||||
expectedJWT: nil,
|
||||
jwtTokenFn: jwtTokenFn,
|
||||
getControllerOpts: nil,
|
||||
},
|
||||
|
||||
{
|
||||
name: "success - no cookies",
|
||||
config: getConfig,
|
||||
db: func(ctrl *gomock.Controller) controller.DBClient {
|
||||
mock := mock.NewMockDBClient(ctrl)
|
||||
return mock
|
||||
},
|
||||
request: api.GetProviderTokensRequestObject{
|
||||
Provider: "fake",
|
||||
Params: api.GetProviderTokensParams{
|
||||
Cookie: "",
|
||||
},
|
||||
},
|
||||
expectedResponse: api.GetProviderTokens200JSONResponse{
|
||||
Headers: api.GetProviderTokens200ResponseHeaders{
|
||||
SetCookie: "fakeProviderTokens=; Path=/; Max-Age=0; HttpOnly; Secure; SameSite=Strict",
|
||||
},
|
||||
Body: api.GetProviderTokensResponse{
|
||||
AccessToken: "",
|
||||
RefreshToken: nil,
|
||||
},
|
||||
},
|
||||
expectedJWT: nil,
|
||||
jwtTokenFn: jwtTokenFn,
|
||||
getControllerOpts: nil,
|
||||
},
|
||||
|
||||
{
|
||||
name: "missing jwt",
|
||||
config: getConfig,
|
||||
db: func(ctrl *gomock.Controller) controller.DBClient {
|
||||
mock := mock.NewMockDBClient(ctrl)
|
||||
|
||||
return mock
|
||||
},
|
||||
request: api.GetProviderTokensRequestObject{
|
||||
Provider: "fake",
|
||||
Params: api.GetProviderTokensParams{
|
||||
Cookie: "someCookie=;",
|
||||
},
|
||||
},
|
||||
expectedResponse: controller.ErrorResponse{
|
||||
Error: "invalid-request",
|
||||
Message: "The request payload is incorrect",
|
||||
Status: http.StatusBadRequest,
|
||||
},
|
||||
expectedJWT: nil,
|
||||
jwtTokenFn: nil,
|
||||
getControllerOpts: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
|
||||
c, jwtGetter := getController(t, ctrl, tc.config, tc.db, tc.getControllerOpts...)
|
||||
|
||||
ctx := t.Context()
|
||||
if tc.jwtTokenFn != nil {
|
||||
ctx = jwtGetter.ToContext(t.Context(), tc.jwtTokenFn())
|
||||
}
|
||||
|
||||
assertRequest(
|
||||
ctx, t, c.GetProviderTokens, tc.request, tc.expectedResponse,
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,7 @@ package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/nhost/nhost/services/auth/go/api"
|
||||
@@ -13,11 +11,6 @@ import (
|
||||
"github.com/nhost/nhost/services/auth/go/providers"
|
||||
)
|
||||
|
||||
const (
|
||||
sevenDaysInSeconds = 7 * 24 * 60 * 60
|
||||
cookieSuffixProviderToken = "ProviderTokens"
|
||||
)
|
||||
|
||||
type providerCallbackData struct {
|
||||
State string
|
||||
Provider string
|
||||
@@ -85,17 +78,15 @@ func (ctrl *Controller) signinProviderProviderCallbackOauthFlow(
|
||||
ctx context.Context,
|
||||
req providerCallbackData,
|
||||
logger *slog.Logger,
|
||||
) (oidc.Profile, string, string, *APIError) {
|
||||
) (oidc.Profile, *APIError) {
|
||||
p := ctrl.Providers.Get(req.Provider)
|
||||
if p == nil {
|
||||
logger.ErrorContext(ctx, "provider not enabled")
|
||||
return oidc.Profile{}, "", "", ErrDisabledEndpoint
|
||||
return oidc.Profile{}, ErrDisabledEndpoint
|
||||
}
|
||||
|
||||
var (
|
||||
profile oidc.Profile
|
||||
refreshToken, accessToken string
|
||||
)
|
||||
var profile oidc.Profile
|
||||
|
||||
switch {
|
||||
case p.IsOauth1():
|
||||
accessTokenValue, accessTokenSecret, err := p.Oauth1().AccessToken(
|
||||
@@ -103,45 +94,40 @@ func (ctrl *Controller) signinProviderProviderCallbackOauthFlow(
|
||||
)
|
||||
if err != nil {
|
||||
logger.ErrorContext(ctx, "failed to request token", logError(err))
|
||||
return oidc.Profile{}, "", "", ErrOauthProfileFetchFailed
|
||||
return oidc.Profile{}, ErrOauthProfileFetchFailed
|
||||
}
|
||||
|
||||
profile, err = p.Oauth1().GetProfile(ctx, accessTokenValue, accessTokenSecret)
|
||||
if err != nil {
|
||||
logger.ErrorContext(ctx, "failed to get user info", logError(err))
|
||||
return oidc.Profile{}, "", "", ErrOauthProfileFetchFailed
|
||||
return oidc.Profile{}, ErrOauthProfileFetchFailed
|
||||
}
|
||||
|
||||
accessToken = accessTokenValue
|
||||
default:
|
||||
token, err := p.Oauth2().Exchange(ctx, deptr(req.Code))
|
||||
if err != nil {
|
||||
logger.ErrorContext(ctx, "failed to exchange token", logError(err))
|
||||
return oidc.Profile{}, "", "", ErrOauthTokenExchangeFailed
|
||||
return oidc.Profile{}, ErrOauthTokenExchangeFailed
|
||||
}
|
||||
|
||||
profile, err = p.Oauth2().GetProfile(ctx, token.AccessToken, req.IDToken, req.Extras)
|
||||
if err != nil {
|
||||
logger.ErrorContext(ctx, "failed to get user info", logError(err))
|
||||
return oidc.Profile{}, "", "", ErrOauthProfileFetchFailed
|
||||
return oidc.Profile{}, ErrOauthProfileFetchFailed
|
||||
}
|
||||
|
||||
refreshToken = token.RefreshToken
|
||||
accessToken = token.AccessToken
|
||||
}
|
||||
|
||||
if profile.ProviderUserID == "" {
|
||||
logger.ErrorContext(ctx, "provider user id is empty")
|
||||
return oidc.Profile{}, "", "", ErrOauthProfileFetchFailed
|
||||
return oidc.Profile{}, ErrOauthProfileFetchFailed
|
||||
}
|
||||
|
||||
return profile, refreshToken, accessToken, nil
|
||||
return profile, nil
|
||||
}
|
||||
|
||||
func (ctrl *Controller) signinProviderProviderCallback(
|
||||
ctx context.Context,
|
||||
req providerCallbackData,
|
||||
) (*url.URL, string, string, *APIError) {
|
||||
) (*url.URL, *APIError) {
|
||||
logger := middleware.LoggerFromContext(ctx)
|
||||
|
||||
options, connnect, redirectTo, apiErr := ctrl.signinProviderProviderCallbackValidate(
|
||||
@@ -150,30 +136,26 @@ func (ctrl *Controller) signinProviderProviderCallback(
|
||||
logger,
|
||||
)
|
||||
if apiErr != nil {
|
||||
return redirectTo, "", "", apiErr
|
||||
return redirectTo, apiErr
|
||||
}
|
||||
|
||||
profile, provRefreshToken, provAccessToken, apiErr := ctrl.signinProviderProviderCallbackOauthFlow(
|
||||
ctx,
|
||||
req,
|
||||
logger,
|
||||
)
|
||||
profile, apiErr := ctrl.signinProviderProviderCallbackOauthFlow(ctx, req, logger)
|
||||
if apiErr != nil {
|
||||
return redirectTo, "", "", apiErr
|
||||
return redirectTo, apiErr
|
||||
}
|
||||
|
||||
if connnect != nil {
|
||||
if apiErr := ctrl.signinProviderProviderCallbackConnect(
|
||||
ctx, *connnect, req.Provider, profile, logger,
|
||||
); apiErr != nil {
|
||||
return redirectTo, "", "", apiErr
|
||||
return redirectTo, apiErr
|
||||
}
|
||||
} else {
|
||||
session, apiErr := ctrl.providerSignInFlow(
|
||||
ctx, profile, req.Provider, options, logger,
|
||||
)
|
||||
if apiErr != nil {
|
||||
return redirectTo, "", "", apiErr
|
||||
return redirectTo, apiErr
|
||||
}
|
||||
|
||||
if session != nil {
|
||||
@@ -183,7 +165,7 @@ func (ctrl *Controller) signinProviderProviderCallback(
|
||||
}
|
||||
}
|
||||
|
||||
return redirectTo, provRefreshToken, provAccessToken, nil
|
||||
return redirectTo, nil
|
||||
}
|
||||
|
||||
func (ctrl *Controller) SignInProviderCallbackGet( //nolint:ireturn
|
||||
@@ -203,7 +185,7 @@ func (ctrl *Controller) SignInProviderCallbackGet( //nolint:ireturn
|
||||
ErrorURI: req.Params.ErrorUri,
|
||||
}
|
||||
|
||||
redirectTo, provRefreshToken, provAccessToken, apiErr := ctrl.signinProviderProviderCallback(
|
||||
redirectTo, apiErr := ctrl.signinProviderProviderCallback(
|
||||
ctx,
|
||||
providerCallbackData,
|
||||
)
|
||||
@@ -214,13 +196,6 @@ func (ctrl *Controller) SignInProviderCallbackGet( //nolint:ireturn
|
||||
return api.SignInProviderCallbackGet302Response{
|
||||
Headers: api.SignInProviderCallbackGet302ResponseHeaders{
|
||||
Location: redirectTo.String(),
|
||||
SetCookie: providerCookies(
|
||||
string(req.Provider),
|
||||
provRefreshToken,
|
||||
provAccessToken,
|
||||
ctrl.config.UseSecureCookies(),
|
||||
sevenDaysInSeconds,
|
||||
),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
@@ -266,36 +241,6 @@ func (ctrl *Controller) signinProviderProviderCallbackConnect(
|
||||
return nil
|
||||
}
|
||||
|
||||
func providerCookies(
|
||||
providerName, refreshToken, accessToken string, secure bool, maxAge int,
|
||||
) string {
|
||||
var b []byte
|
||||
if accessToken == "" && refreshToken == "" {
|
||||
b = []byte(``)
|
||||
} else {
|
||||
var err error
|
||||
|
||||
b, err = json.Marshal(map[string]string{
|
||||
"refreshToken": refreshToken,
|
||||
"accessToken": accessToken,
|
||||
})
|
||||
if err != nil {
|
||||
// This should never happen
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
return (&http.Cookie{ //nolint:exhaustruct
|
||||
Name: providerName + cookieSuffixProviderToken,
|
||||
Value: url.QueryEscape(string(b)),
|
||||
Path: "/",
|
||||
HttpOnly: true,
|
||||
Secure: secure,
|
||||
SameSite: http.SameSiteStrictMode,
|
||||
MaxAge: maxAge,
|
||||
}).String()
|
||||
}
|
||||
|
||||
func (ctrl *Controller) SignInProviderCallbackPost( //nolint:ireturn
|
||||
ctx context.Context,
|
||||
req api.SignInProviderCallbackPostRequestObject,
|
||||
@@ -315,7 +260,7 @@ func (ctrl *Controller) SignInProviderCallbackPost( //nolint:ireturn
|
||||
ErrorURI: req.Body.ErrorUri,
|
||||
}
|
||||
|
||||
redirectTo, provRefreshToken, provAccessToken, apiErr := ctrl.signinProviderProviderCallback(
|
||||
redirectTo, apiErr := ctrl.signinProviderProviderCallback(
|
||||
ctx,
|
||||
providerCallbackData,
|
||||
)
|
||||
@@ -326,15 +271,6 @@ func (ctrl *Controller) SignInProviderCallbackPost( //nolint:ireturn
|
||||
return api.SignInProviderCallbackPost302Response{
|
||||
Headers: api.SignInProviderCallbackPost302ResponseHeaders{
|
||||
Location: redirectTo.String(),
|
||||
SetCookie: providerCookies(
|
||||
string(
|
||||
req.Provider,
|
||||
),
|
||||
provRefreshToken,
|
||||
provAccessToken,
|
||||
ctrl.config.UseSecureCookies(),
|
||||
sevenDaysInSeconds,
|
||||
),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -131,8 +131,7 @@ func TestSignInProviderCallback(t *testing.T) { //nolint:maintidx
|
||||
},
|
||||
expectedResponse: api.SignInProviderCallbackGet302Response{
|
||||
Headers: api.SignInProviderCallbackGet302ResponseHeaders{
|
||||
Location: `^http://localhost:3000\?refreshToken=.*$`,
|
||||
SetCookie: "fakeProviderTokens=%7B%22accessToken%22%3A%22valid-accesstoken-1%22%2C%22refreshToken%22%3A%22valid-refreshtoken-1%22%7D; Path=/; Max-Age=604800; HttpOnly; Secure; SameSite=Strict", //nolint:lll
|
||||
Location: `^http://localhost:3000\?refreshToken=.*$`,
|
||||
},
|
||||
},
|
||||
expectedJWT: nil,
|
||||
@@ -206,8 +205,7 @@ func TestSignInProviderCallback(t *testing.T) { //nolint:maintidx
|
||||
},
|
||||
expectedResponse: api.SignInProviderCallbackGet302Response{
|
||||
Headers: api.SignInProviderCallbackGet302ResponseHeaders{
|
||||
Location: `^http://localhost:3000/redirect/me/here\?refreshToken=.*$`,
|
||||
SetCookie: "fakeProviderTokens=%7B%22accessToken%22%3A%22valid-accesstoken-1%22%2C%22refreshToken%22%3A%22valid-refreshtoken-1%22%7D; Path=/; Max-Age=604800; HttpOnly; Secure; SameSite=Strict", //nolint:lll
|
||||
Location: `^http://localhost:3000/redirect/me/here\?refreshToken=.*$`,
|
||||
},
|
||||
},
|
||||
expectedJWT: nil,
|
||||
@@ -445,8 +443,7 @@ func TestSignInProviderCallback(t *testing.T) { //nolint:maintidx
|
||||
},
|
||||
expectedResponse: api.SignInProviderCallbackGet302Response{
|
||||
Headers: api.SignInProviderCallbackGet302ResponseHeaders{
|
||||
Location: `^http://localhost:3000\?refreshToken=.*$`,
|
||||
SetCookie: "fakeProviderTokens=%7B%22accessToken%22%3A%22valid-accesstoken-1%22%2C%22refreshToken%22%3A%22valid-refreshtoken-1%22%7D; Path=/; Max-Age=604800; HttpOnly; Secure; SameSite=Strict", //nolint:lll
|
||||
Location: `^http://localhost:3000\?refreshToken=.*$`,
|
||||
},
|
||||
},
|
||||
expectedJWT: nil,
|
||||
@@ -558,8 +555,7 @@ func TestSignInProviderCallback(t *testing.T) { //nolint:maintidx
|
||||
},
|
||||
expectedResponse: api.SignInProviderCallbackGet302Response{
|
||||
Headers: api.SignInProviderCallbackGet302ResponseHeaders{
|
||||
Location: `^http://localhost:3000\?refreshToken=.*$`,
|
||||
SetCookie: "fakeProviderTokens=%7B%22accessToken%22%3A%22valid-accesstoken-1%22%2C%22refreshToken%22%3A%22valid-refreshtoken-1%22%7D; Path=/; Max-Age=604800; HttpOnly; Secure; SameSite=Strict", //nolint:lll
|
||||
Location: `^http://localhost:3000\?refreshToken=.*$`,
|
||||
},
|
||||
},
|
||||
expectedJWT: nil,
|
||||
@@ -729,7 +725,7 @@ func TestSignInProviderCallback(t *testing.T) { //nolint:maintidx
|
||||
Provider: "fake",
|
||||
},
|
||||
expectedResponse: controller.ErrorRedirectResponse{
|
||||
Headers: struct{ Location string }{
|
||||
Headers: api.SignInProviderCallbackGet302ResponseHeaders{
|
||||
Location: `http://localhost:3000?error=oauth-provider-error&errorDescription=Provider+returned+an+error&provider_error=error-coming-from-provider&provider_error_description=This+is+an+error+coming+from+the+provider&provider_error_url=https%3A%2F%2Fexample.com%2Ferror`, //nolint:lll
|
||||
},
|
||||
},
|
||||
@@ -814,8 +810,7 @@ func TestSignInProviderCallback(t *testing.T) { //nolint:maintidx
|
||||
},
|
||||
expectedResponse: api.SignInProviderCallbackGet302Response{
|
||||
Headers: api.SignInProviderCallbackGet302ResponseHeaders{
|
||||
Location: `^http://localhost:3000/connect-success$`,
|
||||
SetCookie: "fakeProviderTokens=%7B%22accessToken%22%3A%22valid-accesstoken-1%22%2C%22refreshToken%22%3A%22valid-refreshtoken-1%22%7D; Path=/; Max-Age=604800; HttpOnly; Secure; SameSite=Strict", //nolint:lll
|
||||
Location: `^http://localhost:3000/connect-success$`,
|
||||
},
|
||||
},
|
||||
expectedJWT: nil,
|
||||
@@ -1078,8 +1073,7 @@ func TestSignInProviderCallback(t *testing.T) { //nolint:maintidx
|
||||
},
|
||||
expectedResponse: api.SignInProviderCallbackGet302Response{
|
||||
Headers: api.SignInProviderCallbackGet302ResponseHeaders{
|
||||
Location: `^http://localhost:3000\?refreshToken=.*$`,
|
||||
SetCookie: "fakeProviderTokens=%7B%22accessToken%22%3A%22valid-accesstoken-empty-email%22%2C%22refreshToken%22%3A%22valid-refreshtoken-empty-email%22%7D; Path=/; Max-Age=604800; HttpOnly; Secure; SameSite=Strict", //nolint:lll
|
||||
Location: `^http://localhost:3000\?refreshToken=.*$`,
|
||||
},
|
||||
},
|
||||
expectedJWT: nil,
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -11,8 +12,10 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
timeout = 10
|
||||
hasuraDBName = "default"
|
||||
timeout = 10
|
||||
hasuraDBName = "default"
|
||||
errorCodeAlreadyTracked = "already-tracked"
|
||||
errorCodeAlreadyExists = "already-exists"
|
||||
)
|
||||
|
||||
type hasuraErrResponse struct {
|
||||
@@ -21,6 +24,19 @@ type hasuraErrResponse struct {
|
||||
Code string `json:"code"`
|
||||
}
|
||||
|
||||
type metadataError struct {
|
||||
code string
|
||||
msg string
|
||||
}
|
||||
|
||||
func (e *metadataError) Error() string {
|
||||
return e.msg
|
||||
}
|
||||
|
||||
func (e *metadataError) Code() string {
|
||||
return e.code
|
||||
}
|
||||
|
||||
func postMetadata(ctx context.Context, url, hasuraSecret string, data any) error {
|
||||
client := &http.Client{ //nolint: exhaustruct
|
||||
Timeout: time.Second * timeout,
|
||||
@@ -57,8 +73,12 @@ func postMetadata(ctx context.Context, url, hasuraSecret string, data any) error
|
||||
)
|
||||
}
|
||||
|
||||
if errResponse.Code == "already-tracked" || errResponse.Code == "already-exists" {
|
||||
return nil
|
||||
if errResponse.Code == errorCodeAlreadyTracked ||
|
||||
errResponse.Code == errorCodeAlreadyExists {
|
||||
return &metadataError{
|
||||
code: errResponse.Code,
|
||||
msg: errResponse.Error,
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("status_code: %d\nresponse: %s", resp.StatusCode, b) //nolint: err113
|
||||
@@ -68,8 +88,9 @@ func postMetadata(ctx context.Context, url, hasuraSecret string, data any) error
|
||||
}
|
||||
|
||||
type TrackTable struct {
|
||||
Type string `json:"type"`
|
||||
Args PgTrackTableArgs `json:"args"`
|
||||
Type string `json:"type"`
|
||||
Args PgTrackTableArgs `json:"args"`
|
||||
IsEnum bool `json:"is_enum,omitempty"` //nolint: tagliatelle
|
||||
}
|
||||
|
||||
type Table struct {
|
||||
@@ -96,9 +117,29 @@ type Configuration struct {
|
||||
}
|
||||
|
||||
type PgTrackTableArgs struct {
|
||||
Source string `json:"source"`
|
||||
Table Table `json:"table"`
|
||||
Configuration Configuration `json:"configuration"`
|
||||
Source string `json:"source"`
|
||||
Table Table `json:"table"`
|
||||
Configuration Configuration `json:"configuration"`
|
||||
ObjectRelationships []ObjectRelationshipConfig `json:"object_relationships,omitempty"` //nolint: tagliatelle
|
||||
ArrayRelationships []ArrayRelationshipConfig `json:"array_relationships,omitempty"` //nolint: tagliatelle
|
||||
}
|
||||
|
||||
type ObjectRelationshipConfig struct {
|
||||
Name string `json:"name"`
|
||||
Using ObjectRelationshipConfigUsing `json:"using"`
|
||||
}
|
||||
|
||||
type ObjectRelationshipConfigUsing struct {
|
||||
ForeignKeyConstraintOn any `json:"foreign_key_constraint_on"` //nolint: tagliatelle
|
||||
}
|
||||
|
||||
type ArrayRelationshipConfig struct {
|
||||
Name string `json:"name"`
|
||||
Using ArrayRelationshipConfigUsing `json:"using"`
|
||||
}
|
||||
|
||||
type ArrayRelationshipConfigUsing struct {
|
||||
ForeignKeyConstraintOn ForeignKeyConstraintOn `json:"foreign_key_constraint_on"` //nolint: tagliatelle
|
||||
}
|
||||
|
||||
type CreateObjectRelationship struct {
|
||||
@@ -150,14 +191,126 @@ type DropRelationshipArgs struct {
|
||||
Relationship string `json:"relationship"`
|
||||
}
|
||||
|
||||
type SetTableCustomization struct {
|
||||
Type string `json:"type"`
|
||||
Args SetTableCustomizationArgs `json:"args"`
|
||||
}
|
||||
|
||||
type SetTableCustomizationArgs struct {
|
||||
Source string `json:"source"`
|
||||
Table Table `json:"table"`
|
||||
Configuration Configuration `json:"configuration"`
|
||||
}
|
||||
|
||||
func applyTableCustomization(
|
||||
ctx context.Context,
|
||||
url, hasuraSecret string,
|
||||
table TrackTable,
|
||||
) error {
|
||||
customization := SetTableCustomization{
|
||||
Type: "pg_set_table_customization",
|
||||
Args: SetTableCustomizationArgs{
|
||||
Source: table.Args.Source,
|
||||
Table: table.Args.Table,
|
||||
Configuration: table.Args.Configuration,
|
||||
},
|
||||
}
|
||||
|
||||
return postMetadata(ctx, url, hasuraSecret, customization)
|
||||
}
|
||||
|
||||
func applyObjectRelationships(
|
||||
ctx context.Context,
|
||||
url, hasuraSecret string,
|
||||
table TrackTable,
|
||||
) error {
|
||||
for _, rel := range table.Args.ObjectRelationships {
|
||||
relationship := CreateObjectRelationship{
|
||||
Type: "pg_create_object_relationship",
|
||||
Args: CreateObjectRelationshipArgs{
|
||||
Source: table.Args.Source,
|
||||
Table: table.Args.Table,
|
||||
Name: rel.Name,
|
||||
Using: CreateObjectRelationshipUsing{
|
||||
ForeignKeyConstraintOn: func() []string {
|
||||
// Handle both string and array cases
|
||||
switch v := rel.Using.ForeignKeyConstraintOn.(type) {
|
||||
case string:
|
||||
return []string{v}
|
||||
case []string:
|
||||
return v
|
||||
default:
|
||||
return []string{}
|
||||
}
|
||||
}(),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if err := postMetadata(ctx, url, hasuraSecret, relationship); err != nil {
|
||||
var metaErr *metadataError
|
||||
if ok := errors.As(err, &metaErr); ok && metaErr.Code() == errorCodeAlreadyExists {
|
||||
continue // Skip if relationship already exists
|
||||
}
|
||||
|
||||
return fmt.Errorf(
|
||||
"problem creating object relationship %s for table %s.%s: %w",
|
||||
rel.Name,
|
||||
table.Args.Table.Schema,
|
||||
table.Args.Table.Name,
|
||||
err,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func applyArrayRelationships(
|
||||
ctx context.Context,
|
||||
url, hasuraSecret string,
|
||||
table TrackTable,
|
||||
) error {
|
||||
for _, rel := range table.Args.ArrayRelationships {
|
||||
relationship := CreateArrayRelationship{
|
||||
Type: "pg_create_array_relationship",
|
||||
Args: CreateArrayRelationshipArgs{
|
||||
Source: table.Args.Source,
|
||||
Table: table.Args.Table,
|
||||
Name: rel.Name,
|
||||
Using: CreateArrayRelationshipUsing{
|
||||
ForeignKeyConstraintOn: rel.Using.ForeignKeyConstraintOn,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if err := postMetadata(ctx, url, hasuraSecret, relationship); err != nil {
|
||||
var metaErr *metadataError
|
||||
if ok := errors.As(err, &metaErr); ok && metaErr.Code() == errorCodeAlreadyExists {
|
||||
continue // Skip if relationship already exists
|
||||
}
|
||||
|
||||
return fmt.Errorf(
|
||||
"problem creating array relationship %s for table %s.%s: %w",
|
||||
rel.Name,
|
||||
table.Args.Table.Schema,
|
||||
table.Args.Table.Name,
|
||||
err,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ApplyHasuraMetadata( //nolint: funlen,maintidx
|
||||
ctx context.Context,
|
||||
url, hasuraSecret string,
|
||||
) error {
|
||||
authTables := []TrackTable{
|
||||
{
|
||||
{ //nolint:exhaustruct
|
||||
Type: "pg_track_table",
|
||||
Args: PgTrackTableArgs{
|
||||
Args: PgTrackTableArgs{ //nolint:exhaustruct
|
||||
Source: hasuraDBName,
|
||||
Table: Table{
|
||||
Schema: "auth",
|
||||
@@ -184,8 +337,9 @@ func ApplyHasuraMetadata( //nolint: funlen,maintidx
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: "pg_track_table",
|
||||
Args: PgTrackTableArgs{
|
||||
Type: "pg_track_table",
|
||||
IsEnum: true,
|
||||
Args: PgTrackTableArgs{ //nolint:exhaustruct
|
||||
Source: hasuraDBName,
|
||||
Table: Table{
|
||||
Schema: "auth",
|
||||
@@ -209,11 +363,25 @@ func ApplyHasuraMetadata( //nolint: funlen,maintidx
|
||||
"comment": "comment",
|
||||
},
|
||||
},
|
||||
ArrayRelationships: []ArrayRelationshipConfig{
|
||||
{
|
||||
Name: "refreshTokens",
|
||||
Using: ArrayRelationshipConfigUsing{
|
||||
ForeignKeyConstraintOn: ForeignKeyConstraintOn{
|
||||
Table: Table{
|
||||
Schema: "auth",
|
||||
Name: "refresh_tokens",
|
||||
},
|
||||
Columns: []string{"type"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
{ //nolint:exhaustruct
|
||||
Type: "pg_track_table",
|
||||
Args: PgTrackTableArgs{
|
||||
Args: PgTrackTableArgs{ //nolint:exhaustruct
|
||||
Source: hasuraDBName,
|
||||
Table: Table{
|
||||
Schema: "auth",
|
||||
@@ -239,11 +407,19 @@ func ApplyHasuraMetadata( //nolint: funlen,maintidx
|
||||
"user_id": "userId",
|
||||
},
|
||||
},
|
||||
ObjectRelationships: []ObjectRelationshipConfig{
|
||||
{
|
||||
Name: "user",
|
||||
Using: ObjectRelationshipConfigUsing{
|
||||
ForeignKeyConstraintOn: "user_id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
{ //nolint:exhaustruct
|
||||
Type: "pg_track_table",
|
||||
Args: PgTrackTableArgs{
|
||||
Args: PgTrackTableArgs{ //nolint:exhaustruct
|
||||
Source: hasuraDBName,
|
||||
Table: Table{
|
||||
Schema: "auth",
|
||||
@@ -266,11 +442,37 @@ func ApplyHasuraMetadata( //nolint: funlen,maintidx
|
||||
"role": "role",
|
||||
},
|
||||
},
|
||||
ArrayRelationships: []ArrayRelationshipConfig{
|
||||
{
|
||||
Name: "userRoles",
|
||||
Using: ArrayRelationshipConfigUsing{
|
||||
ForeignKeyConstraintOn: ForeignKeyConstraintOn{
|
||||
Table: Table{
|
||||
Schema: "auth",
|
||||
Name: "user_roles",
|
||||
},
|
||||
Columns: []string{"role"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "usersByDefaultRole",
|
||||
Using: ArrayRelationshipConfigUsing{
|
||||
ForeignKeyConstraintOn: ForeignKeyConstraintOn{
|
||||
Table: Table{
|
||||
Schema: "auth",
|
||||
Name: "users",
|
||||
},
|
||||
Columns: []string{"default_role"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
{ //nolint:exhaustruct
|
||||
Type: "pg_track_table",
|
||||
Args: PgTrackTableArgs{
|
||||
Args: PgTrackTableArgs{ //nolint:exhaustruct
|
||||
Source: hasuraDBName,
|
||||
Table: Table{
|
||||
Schema: "auth",
|
||||
@@ -300,11 +502,25 @@ func ApplyHasuraMetadata( //nolint: funlen,maintidx
|
||||
"provider_user_id": "providerUserId",
|
||||
},
|
||||
},
|
||||
ObjectRelationships: []ObjectRelationshipConfig{
|
||||
{
|
||||
Name: "user",
|
||||
Using: ObjectRelationshipConfigUsing{
|
||||
ForeignKeyConstraintOn: "user_id",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "provider",
|
||||
Using: ObjectRelationshipConfigUsing{
|
||||
ForeignKeyConstraintOn: "provider_id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
{ //nolint:exhaustruct
|
||||
Type: "pg_track_table",
|
||||
Args: PgTrackTableArgs{
|
||||
Args: PgTrackTableArgs{ //nolint:exhaustruct
|
||||
Source: hasuraDBName,
|
||||
Table: Table{
|
||||
Schema: "auth",
|
||||
@@ -330,9 +546,23 @@ func ApplyHasuraMetadata( //nolint: funlen,maintidx
|
||||
"role": "role",
|
||||
},
|
||||
},
|
||||
ObjectRelationships: []ObjectRelationshipConfig{
|
||||
{
|
||||
Name: "user",
|
||||
Using: ObjectRelationshipConfigUsing{
|
||||
ForeignKeyConstraintOn: "user_id",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "roleByRole",
|
||||
Using: ObjectRelationshipConfigUsing{
|
||||
ForeignKeyConstraintOn: "role",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
{ //nolint:exhaustruct
|
||||
Type: "pg_track_table",
|
||||
Args: PgTrackTableArgs{
|
||||
Source: hasuraDBName,
|
||||
@@ -380,11 +610,69 @@ func ApplyHasuraMetadata( //nolint: funlen,maintidx
|
||||
"webauthn_current_challenge": "currentChallenge",
|
||||
},
|
||||
},
|
||||
ObjectRelationships: []ObjectRelationshipConfig{
|
||||
{
|
||||
Name: "defaultRoleByRole",
|
||||
Using: ObjectRelationshipConfigUsing{
|
||||
ForeignKeyConstraintOn: "default_role",
|
||||
},
|
||||
},
|
||||
},
|
||||
ArrayRelationships: []ArrayRelationshipConfig{
|
||||
{
|
||||
Name: "userProviders",
|
||||
Using: ArrayRelationshipConfigUsing{
|
||||
ForeignKeyConstraintOn: ForeignKeyConstraintOn{
|
||||
Table: Table{
|
||||
Schema: "auth",
|
||||
Name: "user_providers",
|
||||
},
|
||||
Columns: []string{"user_id"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "roles",
|
||||
Using: ArrayRelationshipConfigUsing{
|
||||
ForeignKeyConstraintOn: ForeignKeyConstraintOn{
|
||||
Table: Table{
|
||||
Schema: "auth",
|
||||
Name: "user_roles",
|
||||
},
|
||||
Columns: []string{"user_id"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "refreshTokens",
|
||||
Using: ArrayRelationshipConfigUsing{
|
||||
ForeignKeyConstraintOn: ForeignKeyConstraintOn{
|
||||
Table: Table{
|
||||
Schema: "auth",
|
||||
Name: "refresh_tokens",
|
||||
},
|
||||
Columns: []string{"user_id"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "securityKeys",
|
||||
Using: ArrayRelationshipConfigUsing{
|
||||
ForeignKeyConstraintOn: ForeignKeyConstraintOn{
|
||||
Table: Table{
|
||||
Schema: "auth",
|
||||
Name: "user_security_keys",
|
||||
},
|
||||
Columns: []string{"user_id"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
{ //nolint:exhaustruct
|
||||
Type: "pg_track_table",
|
||||
Args: PgTrackTableArgs{
|
||||
Args: PgTrackTableArgs{ //nolint:exhaustruct
|
||||
Source: hasuraDBName,
|
||||
Table: Table{
|
||||
Schema: "auth",
|
||||
@@ -407,11 +695,25 @@ func ApplyHasuraMetadata( //nolint: funlen,maintidx
|
||||
"id": "id",
|
||||
},
|
||||
},
|
||||
ArrayRelationships: []ArrayRelationshipConfig{
|
||||
{
|
||||
Name: "userProviders",
|
||||
Using: ArrayRelationshipConfigUsing{
|
||||
ForeignKeyConstraintOn: ForeignKeyConstraintOn{
|
||||
Table: Table{
|
||||
Schema: "auth",
|
||||
Name: "user_providers",
|
||||
},
|
||||
Columns: []string{"provider_id"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
{ //nolint:exhaustruct
|
||||
Type: "pg_track_table",
|
||||
Args: PgTrackTableArgs{
|
||||
Args: PgTrackTableArgs{ //nolint:exhaustruct
|
||||
Source: hasuraDBName,
|
||||
Table: Table{
|
||||
Schema: "auth",
|
||||
@@ -437,15 +739,49 @@ func ApplyHasuraMetadata( //nolint: funlen,maintidx
|
||||
"credential_public_key": "credentialPublicKey",
|
||||
},
|
||||
},
|
||||
ObjectRelationships: []ObjectRelationshipConfig{
|
||||
{
|
||||
Name: "user",
|
||||
Using: ObjectRelationshipConfigUsing{
|
||||
ForeignKeyConstraintOn: "user_id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Track each table (will skip if already tracked due to existing error handling)
|
||||
for _, table := range authTables {
|
||||
if err := postMetadata(ctx, url, hasuraSecret, table); err != nil {
|
||||
return fmt.Errorf("problem adding metadata for table %s.%s: %w",
|
||||
table.Args.Table.Schema, table.Args.Table.Name, err)
|
||||
err := postMetadata(ctx, url, hasuraSecret, table)
|
||||
if err != nil {
|
||||
var metaErr *metadataError
|
||||
if ok := errors.As(err, &metaErr); ok && metaErr.Code() == errorCodeAlreadyTracked {
|
||||
if err := applyTableCustomization(ctx, url, hasuraSecret, table); err != nil {
|
||||
return fmt.Errorf(
|
||||
"problem updating customization for table %s.%s: %w",
|
||||
table.Args.Table.Schema,
|
||||
table.Args.Table.Name,
|
||||
err,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf(
|
||||
"problem adding metadata for table %s.%s: %w",
|
||||
table.Args.Table.Schema,
|
||||
table.Args.Table.Name,
|
||||
err,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, table := range authTables {
|
||||
if err := applyObjectRelationships(ctx, url, hasuraSecret, table); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := applyArrayRelationships(ctx, url, hasuraSecret, table); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ func ptr[T any](v T) *T {
|
||||
return &v
|
||||
}
|
||||
|
||||
func deptr[T any](v *T) T { //nolint:ireturn,nolintlint
|
||||
func deptr[T any](v *T) T { //nolint:ireturn
|
||||
if v == nil {
|
||||
var zero T
|
||||
return zero
|
||||
|
||||
@@ -43,15 +43,13 @@ func (f *FakeProvider) Exchange(
|
||||
switch code {
|
||||
case "valid-code-1":
|
||||
return &oauth2.Token{ //nolint:exhaustruct
|
||||
AccessToken: "valid-accesstoken-1",
|
||||
RefreshToken: "valid-refreshtoken-1",
|
||||
TokenType: "Bearer",
|
||||
AccessToken: "valid-accesstoken-1",
|
||||
TokenType: "Bearer",
|
||||
}, nil
|
||||
case "valid-code-empty-email":
|
||||
return &oauth2.Token{ //nolint:exhaustruct
|
||||
AccessToken: "valid-accesstoken-empty-email",
|
||||
RefreshToken: "valid-refreshtoken-empty-email",
|
||||
TokenType: "Bearer",
|
||||
AccessToken: "valid-accesstoken-empty-email",
|
||||
TokenType: "Bearer",
|
||||
}, nil
|
||||
default:
|
||||
return nil, errors.New("invalid code") //nolint:err113
|
||||
|
||||
Reference in New Issue
Block a user