mirror of
https://github.com/pocket-id/pocket-id.git
synced 2026-09-18 08:59:03 +02:00
fix: explicitly set SameSite to Lax for cookies
This commit is contained in:
@@ -1,28 +1,34 @@
|
||||
package cookie
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func AddAccessTokenCookie(c *gin.Context, maxAgeInSeconds int, token string) {
|
||||
c.SetCookie(AccessTokenCookieName, token, maxAgeInSeconds, "/", "", true, true)
|
||||
addCookie(c, AccessTokenCookieName, token, maxAgeInSeconds, "/")
|
||||
}
|
||||
|
||||
func AddSessionIdCookie(c *gin.Context, maxAgeInSeconds int, sessionID string) {
|
||||
c.SetCookie(SessionIdCookieName, sessionID, maxAgeInSeconds, "/", "", true, true)
|
||||
addCookie(c, SessionIdCookieName, sessionID, maxAgeInSeconds, "/")
|
||||
}
|
||||
|
||||
func AddDeviceTokenCookie(c *gin.Context, deviceToken string) {
|
||||
c.SetCookie(DeviceTokenCookieName, deviceToken, int(15*time.Minute.Seconds()), "/api/one-time-access-token", "", true, true)
|
||||
addCookie(c, DeviceTokenCookieName, deviceToken, int(15*time.Minute.Seconds()), "/api/one-time-access-token")
|
||||
}
|
||||
|
||||
func AddDeviceLoginTokenCookie(c *gin.Context, requestID, deviceToken string) {
|
||||
path := "/api/device-login/requests/" + requestID + "/exchange"
|
||||
c.SetCookie(DeviceLoginTokenCookieName, deviceToken, int(15*time.Minute.Seconds()), path, "", true, true)
|
||||
addCookie(c, DeviceLoginTokenCookieName, deviceToken, int(15*time.Minute.Seconds()), path)
|
||||
}
|
||||
|
||||
func AddReauthenticationTokenCookie(c *gin.Context, reauthenticationToken string) {
|
||||
c.SetCookie(ReauthenticationTokenCookieName, reauthenticationToken, int(3*time.Minute.Seconds()), "/", "", true, true)
|
||||
addCookie(c, ReauthenticationTokenCookieName, reauthenticationToken, int(3*time.Minute.Seconds()), "/")
|
||||
}
|
||||
|
||||
func addCookie(c *gin.Context, name, value string, maxAge int, path string) {
|
||||
c.SetSameSite(http.SameSiteLaxMode)
|
||||
c.SetCookie(name, value, maxAge, path, "", true, true)
|
||||
}
|
||||
|
||||
@@ -32,6 +32,51 @@ test('Authorize existing client', async ({ page }) => {
|
||||
);
|
||||
});
|
||||
|
||||
test('Authorize existing client with POST while signed in', async ({ page }, testInfo) => {
|
||||
const oidcClient = oidcClients.nextcloud;
|
||||
const formFields = Array.from(createUrlParams(oidcClient));
|
||||
const authorizeURL = new URL('/authorize', testInfo.project.use.baseURL).toString();
|
||||
const clientPageURL = new URL('/post-authorize-test', oidcClient.callbackUrl).toString();
|
||||
|
||||
await page.route(clientPageURL, async (route) => {
|
||||
await route.fulfill({ status: 200, contentType: 'text/html', body: '<!doctype html>' });
|
||||
});
|
||||
await page.goto(clientPageURL);
|
||||
|
||||
const authorizeRequestPromise = page.waitForRequest(
|
||||
(request) => request.method() === 'POST' && new URL(request.url()).pathname === '/authorize'
|
||||
);
|
||||
await expectCallbackRedirect(page, oidcClient.callbackUrl, async () => {
|
||||
// Create and submit a form with the OIDC parameters to simulate a POST request to the /authorize endpoint
|
||||
await page.evaluate(
|
||||
({ fields, target }) => {
|
||||
const doc = (globalThis as any).document;
|
||||
const form = doc.createElement('form');
|
||||
form.method = 'POST';
|
||||
form.action = target;
|
||||
|
||||
for (const [name, value] of fields) {
|
||||
const input = doc.createElement('input');
|
||||
input.type = 'hidden';
|
||||
input.name = name;
|
||||
input.value = value;
|
||||
form.append(input);
|
||||
}
|
||||
|
||||
doc.body.append(form);
|
||||
form.submit();
|
||||
},
|
||||
{ fields: formFields, target: authorizeURL }
|
||||
);
|
||||
|
||||
// Since the access token isn't sent with the POST request because of SameSite cookie restrictions,
|
||||
// /authorize thinks the user is not signed in and shows the login page.
|
||||
// The interaction page has the access token so the user just needs to click "Sign in" to continue the flow.
|
||||
await page.getByRole('button', { name: 'Sign in' }).click();
|
||||
});
|
||||
await authorizeRequestPromise;
|
||||
});
|
||||
|
||||
test('Authorize existing client while not signed in', async ({ page }) => {
|
||||
const oidcClient = oidcClients.nextcloud;
|
||||
const urlParams = createUrlParams(oidcClient);
|
||||
|
||||
Reference in New Issue
Block a user