1
0
Fork 0
mirror of https://github.com/plankanban/planka.git synced 2025-08-10 07:55:27 +02:00

Merge branch 'plankanban:master' into master

This commit is contained in:
NavyStack 2023-12-11 06:26:50 +09:00 committed by GitHub
commit a67b6767bf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 97 additions and 55 deletions

View file

@ -35,7 +35,7 @@ jobs:
done done
- name: Run chart-releaser for stable - name: Run chart-releaser for stable
uses: helm/chart-releaser-action@v1.5.0 uses: helm/chart-releaser-action@v1.6.0
with: with:
charts_dir: charts charts_dir: charts
mark_as_latest: false mark_as_latest: false

View file

@ -1,5 +1,5 @@
# Planka # Planka
#### Elegant open source project tracking #### Elegant open source project tracking.
![David (path)](https://img.shields.io/github/package-json/v/plankanban/planka) ![Docker Pulls](https://img.shields.io/docker/pulls/meltyshev/planka) ![GitHub](https://img.shields.io/github/license/plankanban/planka) ![David (path)](https://img.shields.io/github/package-json/v/plankanban/planka) ![Docker Pulls](https://img.shields.io/docker/pulls/meltyshev/planka) ![GitHub](https://img.shields.io/github/license/plankanban/planka)
@ -20,9 +20,7 @@
## How to deploy Planka ## How to deploy Planka
There are many ways to install Planka There are many ways to install Planka, [check them out](https://docs.planka.cloud/docs/intro).
[Check them out](https://docs.planka.cloud/docs/intro)
For configuration, please see the [configuration section](https://docs.planka.cloud/docs/category/configuration). For configuration, please see the [configuration section](https://docs.planka.cloud/docs/category/configuration).

View file

@ -15,13 +15,13 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes # This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version. # to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/) # Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.11 version: 0.1.12
# This is the version number of the application being deployed. This version number should be # This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to # incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using. # follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes. # It is recommended to use it with quotes.
appVersion: "1.15.0" appVersion: "1.15.1"
dependencies: dependencies:
- alias: postgresql - alias: postgresql

View file

@ -1 +1 @@
REACT_APP_VERSION=1.15.0 REACT_APP_VERSION=1.15.1

View file

@ -14,24 +14,45 @@ export function* handleSocketReconnect() {
yield put(actions.handleSocketReconnect.fetchCore(currentUserId, boardId)); yield put(actions.handleSocketReconnect.fetchCore(currentUserId, boardId));
const { let user;
user, let board;
board, let users;
users, let projects;
projects, let projectManagers;
projectManagers, let boards;
boards, let boardMemberships;
boardMemberships, let labels;
labels, let lists;
lists, let cards;
cards, let cardMemberships;
cardMemberships, let cardLabels;
cardLabels, let tasks;
tasks, let attachments;
attachments, let activities;
activities, let notifications;
notifications,
} = yield call(requests.fetchCore); // TODO: handle error try {
({
user,
board,
users,
projects,
projectManagers,
boards,
boardMemberships,
labels,
lists,
cards,
cardMemberships,
cardLabels,
tasks,
attachments,
activities,
notifications,
} = yield call(requests.fetchCore));
} catch (error) {
return;
}
yield put( yield put(
actions.handleSocketReconnect( actions.handleSocketReconnect(

View file

@ -32,15 +32,29 @@ export function* authenticate(data) {
export function* authenticateUsingOidc() { export function* authenticateUsingOidc() {
const oidcConfig = yield select(selectors.selectOidcConfig); const oidcConfig = yield select(selectors.selectOidcConfig);
const state = nanoid();
window.sessionStorage.setItem('oidc-state', state);
const nonce = nanoid(); const nonce = nanoid();
window.sessionStorage.setItem('oidc-nonce', nonce); window.sessionStorage.setItem('oidc-nonce', nonce);
window.location.href = `${oidcConfig.authorizationUrl}&nonce=${encodeURIComponent(nonce)}`;
let redirectUrl = `${oidcConfig.authorizationUrl}`;
redirectUrl += `&state=${encodeURIComponent(state)}`;
redirectUrl += `&nonce=${encodeURIComponent(nonce)}`;
window.location.href = redirectUrl;
} }
export function* authenticateUsingOidcCallback() { export function* authenticateUsingOidcCallback() {
// https://github.com/plankanban/planka/issues/511#issuecomment-1771385639 // https://github.com/plankanban/planka/issues/511#issuecomment-1771385639
const params = new URLSearchParams(window.location.hash.substring(1) || window.location.search); const params = new URLSearchParams(window.location.hash.substring(1) || window.location.search);
const state = window.sessionStorage.getItem('oidc-state');
window.sessionStorage.removeItem('oidc-state');
const nonce = window.sessionStorage.getItem('oidc-nonce');
window.sessionStorage.removeItem('oidc-nonce');
yield put(replace(Paths.LOGIN)); yield put(replace(Paths.LOGIN));
if (params.get('error') !== null) { if (params.get('error') !== null) {
@ -54,7 +68,23 @@ export function* authenticateUsingOidcCallback() {
return; return;
} }
const nonce = window.sessionStorage.getItem('oidc-nonce'); const code = params.get('code');
if (code === null) {
yield put(
actions.authenticateUsingOidc.failure(new Error('Invalid OIDC response: no code parameter')),
);
return;
}
if (params.get('state') !== state) {
yield put(
actions.authenticateUsingOidc.failure(
new Error('Unable to process OIDC response: state mismatch'),
),
);
return;
}
if (nonce === null) { if (nonce === null) {
yield put( yield put(
actions.authenticateUsingOidc.failure( actions.authenticateUsingOidc.failure(
@ -64,31 +94,19 @@ export function* authenticateUsingOidcCallback() {
return; return;
} }
const code = params.get('code'); let accessToken;
if (code === null) { try {
yield put( ({ item: accessToken } = yield call(api.exchangeForAccessTokenUsingOidc, {
actions.authenticateUsingOidc.failure(new Error('Invalid OIDC response: no code parameter')), code,
); nonce,
}));
} catch (error) {
yield put(actions.authenticateUsingOidc.failure(error));
return; return;
} }
window.sessionStorage.removeItem('oidc-nonce'); yield call(setAccessToken, accessToken);
yield put(actions.authenticateUsingOidc.success(accessToken));
if (code !== null) {
let accessToken;
try {
({ item: accessToken } = yield call(api.exchangeForAccessTokenUsingOidc, {
code,
nonce,
}));
} catch (error) {
yield put(actions.authenticateUsingOidc.failure(error));
return;
}
yield call(setAccessToken, accessToken);
yield put(actions.authenticateUsingOidc.success(accessToken));
}
} }
export function* clearAuthenticateError() { export function* clearAuthenticateError() {

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{ {
"name": "planka", "name": "planka",
"version": "1.15.0", "version": "1.15.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "planka", "name": "planka",
"version": "1.15.0", "version": "1.15.1",
"hasInstallScript": true, "hasInstallScript": true,
"license": "AGPL-3.0", "license": "AGPL-3.0",
"dependencies": { "dependencies": {

View file

@ -1,6 +1,6 @@
{ {
"name": "planka", "name": "planka",
"version": "1.15.0", "version": "1.15.1",
"private": true, "private": true,
"homepage": "https://plankanban.github.io/planka", "homepage": "https://plankanban.github.io/planka",
"repository": { "repository": {

View file

@ -24,8 +24,13 @@ module.exports = {
try { try {
const tokenSet = await client.callback( const tokenSet = await client.callback(
sails.config.custom.oidcRedirectUri, sails.config.custom.oidcRedirectUri,
{ code: inputs.code }, {
{ nonce: inputs.nonce }, iss: sails.config.custom.oidcIssuer,
code: inputs.code,
},
{
nonce: inputs.nonce,
},
); );
userInfo = await client.userinfo(tokenSet); userInfo = await client.userinfo(tokenSet);
} catch (e) { } catch (e) {