mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-09 06:55:47 +01:00
add anonymous mode for webclient / change footer and redirects if user is anonymous / add login button if user is anonymous
This commit is contained in:
@@ -35,6 +35,7 @@ import reducer, {
|
||||
getLoginFailure,
|
||||
getLogoutFailure,
|
||||
getMe,
|
||||
isAnonymous,
|
||||
isAuthenticated,
|
||||
isFetchMePending,
|
||||
isLoginPending,
|
||||
@@ -117,7 +118,7 @@ describe("auth actions", () => {
|
||||
fetchMock.postOnce("/api/v2/auth/access_token", {
|
||||
body: {
|
||||
cookie: true,
|
||||
grant_type: "password",
|
||||
grantType: "password",
|
||||
username: "tricia",
|
||||
password: "secret123"
|
||||
},
|
||||
@@ -349,23 +350,6 @@ describe("auth selectors", () => {
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false if me exist and login Link does exist", () => {
|
||||
expect(
|
||||
isAuthenticated({
|
||||
auth: {
|
||||
me
|
||||
},
|
||||
indexResources: {
|
||||
links: {
|
||||
login: {
|
||||
href: "login.href"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("should return me", () => {
|
||||
expect(
|
||||
getMe({
|
||||
@@ -500,3 +484,8 @@ describe("auth selectors", () => {
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("should check if current user is anonymous", () => {
|
||||
expect(isAnonymous({ name: "_anonymous", displayName: "Anon", _links: [], groups: [], mail: "" })).toBeTruthy();
|
||||
expect(isAnonymous({ name: "scmadmin", displayName: "SCM Admin", _links: [], groups: [], mail: "" })).toBeFalsy();
|
||||
});
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
import { Me } from "@scm-manager/ui-types";
|
||||
import { Link, Me } from "@scm-manager/ui-types";
|
||||
import * as types from "./types";
|
||||
|
||||
import { apiClient, UnauthorizedError } from "@scm-manager/ui-components";
|
||||
@@ -32,9 +32,9 @@ import {
|
||||
callFetchIndexResources,
|
||||
fetchIndexResources,
|
||||
fetchIndexResourcesPending,
|
||||
fetchIndexResourcesSuccess,
|
||||
getLoginLink
|
||||
fetchIndexResourcesSuccess, getLoginLink
|
||||
} from "./indexResource";
|
||||
import { AnyAction } from "redux";
|
||||
|
||||
// Action
|
||||
|
||||
@@ -61,7 +61,7 @@ const initialState = {};
|
||||
|
||||
export default function reducer(
|
||||
state: object = initialState,
|
||||
action: object = {
|
||||
action: AnyAction = {
|
||||
type: "UNKNOWN"
|
||||
}
|
||||
) {
|
||||
@@ -174,23 +174,23 @@ const callFetchMe = (link: string): Promise<Me> => {
|
||||
};
|
||||
|
||||
export const login = (loginLink: string, username: string, password: string) => {
|
||||
const login_data = {
|
||||
const loginData = {
|
||||
cookie: true,
|
||||
grant_type: "password",
|
||||
grantType: "password",
|
||||
username,
|
||||
password
|
||||
};
|
||||
return function(dispatch: any) {
|
||||
dispatch(loginPending());
|
||||
return apiClient
|
||||
.post(loginLink, login_data)
|
||||
.post(loginLink, loginData)
|
||||
.then(() => {
|
||||
dispatch(fetchIndexResourcesPending());
|
||||
return callFetchIndexResources();
|
||||
})
|
||||
.then(response => {
|
||||
dispatch(fetchIndexResourcesSuccess(response));
|
||||
const meLink = response._links.me.href;
|
||||
const meLink = (response._links.me as Link).href;
|
||||
return callFetchMe(meLink);
|
||||
})
|
||||
.then(me => {
|
||||
@@ -256,17 +256,17 @@ export const logout = (link: string) => {
|
||||
// selectors
|
||||
|
||||
const stateAuth = (state: object): object => {
|
||||
// @ts-ignore Right types for redux not available
|
||||
return state.auth || {};
|
||||
};
|
||||
|
||||
export const isAuthenticated = (state: object) => {
|
||||
if (state.auth.me && !getLoginLink(state)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
// @ts-ignore Right types for redux not available
|
||||
return !!((state.auth.me && !getLoginLink(state)) || isAnonymous(state.auth.me));
|
||||
};
|
||||
|
||||
export const getMe = (state: object): Me => {
|
||||
// @ts-ignore Right types for redux not available
|
||||
return stateAuth(state).me;
|
||||
};
|
||||
|
||||
@@ -295,5 +295,12 @@ export const getLogoutFailure = (state: object) => {
|
||||
};
|
||||
|
||||
export const isRedirecting = (state: object) => {
|
||||
// @ts-ignore Right types for redux not available
|
||||
return !!stateAuth(state).redirecting;
|
||||
};
|
||||
|
||||
// Helper methods
|
||||
|
||||
export const isAnonymous = (me: Me) => {
|
||||
return me?.name === "_anonymous";
|
||||
};
|
||||
|
||||
@@ -40,6 +40,7 @@ function removeAllEntriesOfIdentifierFromState(state: object, payload: any, iden
|
||||
const newState = {};
|
||||
for (const failureType in state) {
|
||||
if (failureType !== identifier && !failureType.startsWith(identifier)) {
|
||||
// @ts-ignore Right types not available
|
||||
newState[failureType] = state[failureType];
|
||||
}
|
||||
}
|
||||
@@ -50,6 +51,7 @@ function removeFromState(state: object, identifier: string) {
|
||||
const newState = {};
|
||||
for (const failureType in state) {
|
||||
if (failureType !== identifier) {
|
||||
// @ts-ignore Right types not available
|
||||
newState[failureType] = state[failureType];
|
||||
}
|
||||
}
|
||||
@@ -90,11 +92,13 @@ export default function reducer(
|
||||
}
|
||||
|
||||
export function getFailure(state: object, actionType: string, itemId?: string | number) {
|
||||
// @ts-ignore Right types not available
|
||||
if (state.failure) {
|
||||
let identifier = actionType;
|
||||
if (itemId) {
|
||||
identifier += "/" + itemId;
|
||||
}
|
||||
// @ts-ignore Right types not available
|
||||
return state.failure[identifier];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,23 +111,29 @@ export function getFetchIndexResourcesFailure(state: object) {
|
||||
}
|
||||
|
||||
export function getLinks(state: object) {
|
||||
// @ts-ignore Right types not available
|
||||
return state.indexResources.links;
|
||||
}
|
||||
|
||||
export function getLink(state: object, name: string) {
|
||||
// @ts-ignore Right types not available
|
||||
if (state.indexResources.links && state.indexResources.links[name]) {
|
||||
// @ts-ignore Right types not available
|
||||
return state.indexResources.links[name].href;
|
||||
}
|
||||
}
|
||||
|
||||
export function getLinkCollection(state: object, name: string): Link[] {
|
||||
// @ts-ignore Right types not available
|
||||
if (state.indexResources.links && state.indexResources.links[name]) {
|
||||
// @ts-ignore Right types not available
|
||||
return state.indexResources.links[name];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
export function getAppVersion(state: object) {
|
||||
// @ts-ignore Right types not available
|
||||
return state.indexResources.version;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ function removeFromState(state: object, identifier: string) {
|
||||
const newState = {};
|
||||
for (const childType in state) {
|
||||
if (childType !== identifier) {
|
||||
// @ts-ignore Right types not available
|
||||
newState[childType] = state[childType];
|
||||
}
|
||||
}
|
||||
@@ -42,6 +43,7 @@ function removeAllEntriesOfIdentifierFromState(state: object, payload: any, iden
|
||||
const newState = {};
|
||||
for (const childType in state) {
|
||||
if (childType !== identifier && !childType.startsWith(identifier)) {
|
||||
// @ts-ignore Right types not available
|
||||
newState[childType] = state[childType];
|
||||
}
|
||||
}
|
||||
@@ -92,6 +94,7 @@ export function isPending(state: object, actionType: string, itemId?: string | n
|
||||
if (itemId) {
|
||||
type += "/" + itemId;
|
||||
}
|
||||
// @ts-ignore Right types not available
|
||||
if (state.pending && state.pending[type]) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user