\r\n});\r\n\r\nexport const AppContextProvider: React.FC = ({ children }) => {\r\n const [app, dispatch] = useReducer(appReducer, INITIAL_APP_STATE);\r\n\r\n return {children};\r\n};\r\n","import React from 'react';\r\n\r\nexport const Posts = [\r\n {\r\n Title: 'Secure keys and secrets in legacy projects',\r\n Date: '2022-04-23',\r\n Content:\r\n <>\r\n These days as we rely more on technology every day it is important to keep your apps secure from the outside. With that in mind it is important that developers also are aware and up to date on security measures.
\r\n One way to secure keys using Azure is with Key Vaults. Using Key Vaults we can store our keys and secrets in Azure instead of in our code and control who can access these.
\r\n But using these tools with legacy projects that have not been updated is not always easy, one example where this becomes a problem is with old .NET projects.
\r\n If it is not currently possible to upgrade the project to the latest framework we are still able to get the Key Vault funcationality in .NET Framework 4.7.2 projects.
\r\n This solution is only for projects that can not be upgraded past .NET Framework 4.8 as there are better solutions for newer frameworks.
\r\n
\r\n Following these steps we can take advantage of Azure Key Vault on older .NET Framework projects:
\r\n
\r\n 1) Upgrade your project target framework to .NET Framework 4.7.2
or bigger.
\r\n
\r\n 2) Install Microsoft.Configuration.ConfigurationBuilders.Azure
Nuget package.
\r\n
\r\n 3) In your App.config add your KeyVault Name to the configBuilders.
\r\n
\r\n 4) In your config file add configBuilders='AzureKeyVault'
to your AppSettings and/or ConnectionString container tag and replace the value with a dummy value.
\r\n
\r\n 5) After that all you need to do is set up a KeyVault in Azure and add your secrets, make sure all your key vault secret names match your config names and configure the KeyVault with appropriate Access settings so that your app and/or user can authenticate to the KeyVault and read the secrets.
\r\n >\r\n }\r\n];","import React, { useEffect, useContext, useCallback, useState } from 'react';\r\nimport styled from '@emotion/styled';\r\nimport { Projects } from './Projects';\r\nimport { Skills } from './Skills';\r\nimport { WebAppOverlay } from '../components/overlays/WebAppOverlay';\r\nimport { AppContext } from '../context/AppContextProvider';\r\nimport { AppAction } from '../reducers/AppReducer';\r\nimport gitHub from '../img/icons/GitHub-Mark-64px.png';\r\nimport linkedIn from '../img/icons/linked-in-logo.png';\r\nimport { useTranslation } from '../hooks/useTranslations';\r\nimport { translations } from './translations.i18n';\r\nimport { Header } from '../components/header/header';\r\nimport { Footer } from '../components/footer/Footer';\r\nimport { Posts } from './BlogPosts';\r\n\r\nconst Container = styled.div(({ theme }) => ({\r\n display: 'flex',\r\n margin: 'auto',\r\n flexDirection: 'row',\r\n maxWidth: '100%',\r\n height: '100%',\r\n maxHeight: '100%',\r\n\r\n [theme.breakpoints.mobileAndLower]: {\r\n flexDirection: 'column',\r\n }\r\n}));\r\n\r\nconst Left = styled.div(({ theme }) => ({\r\n display: 'flex',\r\n backgroundColor: '#181818',\r\n width: '35%',\r\n height: '100vh',\r\n color: '#fff',\r\n padding: '0.5em 1em 0.5em 0.5em',\r\n justifyContent: 'end',\r\n overflow: 'hidden',\r\n\r\n [theme.breakpoints.mobileAndLower]: {\r\n maxHeight: '100px',\r\n width: '100%',\r\n }\r\n}));\r\n\r\nconst LeftContainer = styled.div(({ theme }) => ({\r\n display: 'flex',\r\n flexDirection: 'column',\r\n minWidth: '30%',\r\n margin: '200px 0.5em 0 0.5em',\r\n width: '100%',\r\n textAlign: 'right',\r\n\r\n 'ul': {\r\n listStyle: 'none',\r\n padding: 0,\r\n marginTop: 0,\r\n\r\n 'li': {\r\n marginTop: '1em',\r\n\r\n '&:hover': {\r\n cursor: 'pointer',\r\n textDecoration: 'underline',\r\n fontWeight: 'bold'\r\n }\r\n }\r\n },\r\n\r\n [theme.breakpoints.tabletAndLower]: {\r\n marginTop: '100px'\r\n },\r\n\r\n [theme.breakpoints.mobileAndLower]: {\r\n marginTop: '50px',\r\n margin: '0 0.5em 0 0.5em',\r\n flexDirection: 'row',\r\n\r\n 'ul': {\r\n display: 'flex',\r\n margin: 'auto',\r\n\r\n 'li': {\r\n margin: 'auto',\r\n\r\n '&:not(:first-of-type)': {\r\n paddingLeft: '1em'\r\n }\r\n }\r\n }\r\n },\r\n}));\r\n\r\nconst Right = styled.div(({ theme }) => ({\r\n display: 'flex',\r\n width: '65%',\r\n height: '100vh',\r\n color: '#181818',\r\n padding: '0.5em 0.5em 0.5em 1em',\r\n justifyContent: 'start',\r\n overflowY: 'auto',\r\n\r\n [theme.breakpoints.mobileAndLower]: {\r\n width: '100%',\r\n overflowY: 'initial'\r\n },\r\n}));\r\n\r\nconst RightContainer = styled.div(({ theme }) => ({\r\n display: 'flex',\r\n flexDirection: 'column',\r\n minWidth: '30%',\r\n textAlign: 'left',\r\n padding: '0 0.5em 0 0',\r\n marginTop: '200px',\r\n width: '100%',\r\n\r\n 'p': {\r\n margin: 0\r\n },\r\n\r\n [theme.breakpoints.tabletAndLower]: {\r\n marginTop: '100px'\r\n },\r\n\r\n [theme.breakpoints.mobileAndLower]: {\r\n marginTop: '0',\r\n\r\n h1: {\r\n position: 'absolute',\r\n color: '#fff',\r\n top: '3em',\r\n left: '2.8em',\r\n fontSize: '1em'\r\n }\r\n },\r\n}));\r\n\r\nconst TextContainer = styled.div({\r\n margin: '1em 0 0 0',\r\n padding: 0,\r\n\r\n 'h2': {\r\n borderBottom: '1px solid black'\r\n },\r\n\r\n 'h3': {\r\n marginBottom: '0.5em'\r\n }\r\n});\r\n\r\nconst Content = styled.div({\r\n\r\n});\r\n\r\nconst Links = styled.div({\r\n width: 'fit-content',\r\n paddingTop: '1em',\r\n paddingBottom: '1em',\r\n\r\n '> a': {\r\n padding: '1em',\r\n\r\n '&:first-of-type': {\r\n paddingLeft: 0\r\n },\r\n\r\n img: {\r\n borderRadius: '50%',\r\n }\r\n }\r\n});\r\n\r\nconst BlogContainer = styled.div({\r\n display: 'flex',\r\n maxWidth: '100%',\r\n});\r\n\r\nconst BlogList = styled.div({\r\n display: 'flex',\r\n flexDirection: 'column',\r\n maxWidth: '100%'\r\n});\r\n\r\nconst BlogItem = styled.div({\r\n paddingBottom: '1.5em',\r\n borderBottom: '1px solid black',\r\n marginBottom: '1.5em',\r\n\r\n h1: {\r\n position: 'relative',\r\n color: 'black',\r\n fontSize: '1.2em',\r\n top: 0,\r\n left: 0,\r\n marginBottom: 0,\r\n },\r\n h2: {\r\n fontSize: '0.8em',\r\n marginTop: 0,\r\n fontWeight: 'normal',\r\n fontStyle: 'italic',\r\n borderBottom: 'none'\r\n },\r\n});\r\n\r\nconst BlogContent = styled.div({\r\n p: {\r\n i: {\r\n fontSize: '0.8em'\r\n }\r\n },\r\n code: {\r\n fontFamily: 'monospace',\r\n fontSize: '1em',\r\n backgroundColor: '#f1f1f1',\r\n paddingLeft: '0.3em',\r\n paddingRight: '0.3em',\r\n },\r\n img: {\r\n margin: '0.3em 0.5em 0.3em 0.5em',\r\n maxWidth: '100%',\r\n height: 'auto'\r\n }\r\n});\r\n\r\nexport const Homepage: React.FC = () => {\r\n const t = useTranslation(translations);\r\n const { app, dispatch } = useContext(AppContext);\r\n const [contentType, setContentType] = useState(0);\r\n\r\n const handleShowProject = useCallback(() => {\r\n if (app.showProjectOverlay && app.activeProject !== '') {\r\n dispatch({ type: AppAction.SetActiveProject, payload: '' });\r\n }\r\n\r\n dispatch({ type: AppAction.SetShowProjectOverlay, payload: !app.showProjectOverlay });\r\n }, [app.activeProject, app.showProjectOverlay, dispatch]);\r\n\r\n useEffect(() => {\r\n if (app.activeProject !== '' && !app.showProjectOverlay) {\r\n handleShowProject();\r\n }\r\n }, [handleShowProject, app.activeProject, app.showProjectOverlay]);\r\n\r\n const GetPosts = () => {\r\n return Posts.map(x =>\r\n \r\n {x.Title}
\r\n {x.Date}
\r\n {x.Content}\r\n \r\n )\r\n }\r\n\r\n const showContent = () => {\r\n switch (contentType) {\r\n case 0: {\r\n return <>\r\n \r\n I am a full-stack developer currently working in C# and ReactJS in the Fintech industry.
\r\n My key goals are mostly focused on being mobile friendly, having a simple to navigate UI and reusability of code and components.
\r\n \r\n \r\n Socials
\r\n Feel free to contact me on either LinkedIn or Email: pontusdev@gmail.com
\r\n \r\n \r\n \r\n
\r\n \r\n \r\n
\r\n \r\n \r\n \r\n Thoughts & Things
\r\n \r\n \r\n {GetPosts()}\r\n \r\n \r\n \r\n >\r\n }\r\n case 1: {\r\n return \r\n }\r\n case 2: {\r\n return \r\n }\r\n case 3: {\r\n return \r\n I am a full-stack developer currently working in C# and ReactJS in the Fintech industry.
\r\n My key goals are mostly focused on being mobile friendly, having a simple to navigate UI and reusability of code and components.
\r\n \r\n }\r\n default: {\r\n return \r\n }\r\n }\r\n }\r\n\r\n return (\r\n <>\r\n {/* */}\r\n \r\n \r\n \r\n \r\n Pontus
\r\n \r\n - setContentType(0)}>HOME
\r\n - setContentType(1)}>PROJECTS
\r\n - setContentType(2)}>SKILLS
\r\n {/* - setContentType(3)}>ABOUT
*/}\r\n
\r\n \r\n \r\n \r\n \r\n Johansson
\r\n \r\n {showContent()}\r\n \r\n \r\n \r\n {/* {app.showProjectOverlay && }\r\n \r\n */}\r\n \r\n \r\n {/* */}\r\n >\r\n );\r\n};\r\n","export const setCookie = (cname: string, cvalue: string, exdays: number) => {\r\n var d = new Date();\r\n d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));\r\n var expires = \"expires=\" + d.toUTCString();\r\n document.cookie = cname + \"=\" + cvalue + \";\" + expires + \";path=/\";\r\n}\r\n\r\nexport const getCookie = (cname: string) => {\r\n var name = cname + \"=\";\r\n var decodedCookie = decodeURIComponent(document.cookie);\r\n var ca = decodedCookie.split(';');\r\n for (var i = 0; i < ca.length; i++) {\r\n var c = ca[i];\r\n while (c.charAt(0) === ' ') {\r\n c = c.substring(1);\r\n }\r\n if (c.indexOf(name) === 0) {\r\n return c.substring(name.length, c.length);\r\n }\r\n }\r\n return \"\";\r\n}","import React, { useState } from 'react';\r\nimport styled from '@emotion/styled';\r\nimport { ActionButton } from '../buttons/ActionButton';\r\nimport { setCookie } from '../../hooks/useCookies';\r\n\r\nconst Container = styled.div(({ theme }) => ({\r\n position: 'fixed',\r\n bottom: 0,\r\n width: '100%',\r\n zIndex: 150,\r\n height: 'auto',\r\n backgroundColor: '#fff',\r\n}));\r\n\r\nconst CookiesText = styled.p(({ theme }) => ({\r\n marginBottom: 0\r\n}));\r\n\r\nconst ButtonContainer = styled.div(({ theme }) => ({\r\n display: 'flex',\r\n flexDirection: 'row',\r\n justifyContent: 'center',\r\n '> div': {\r\n marginTop: 10,\r\n },\r\n button: {\r\n marginRight: 20,\r\n },\r\n}));\r\n\r\nexport const Cookies: React.FC = () => {\r\n const [show, setShow] = useState(true);\r\n\r\n const setCookies = (show: boolean) => {\r\n setCookie(\"terms\", show ? \"true\" : \"false\", 365);\r\n setShow(false);\r\n }\r\n\r\n return show ? (\r\n \r\n This website might use cookies to store information and improve your user experiences. Please accept cookies usage for the full experience.\r\n \r\n setCookies(true)}>Accept\r\n setCookies(false)}>Reject\r\n \r\n \r\n ) : <>>;\r\n};\r\n","import React, { useContext, useState, useEffect } from 'react';\r\nimport './App.css';\r\nimport styled from '@emotion/styled';\r\nimport { AppConfigContext, AppConfigContextProvider } from './config/AppConfigContext';\r\nimport { ILocaleContext, LocaleContext } from './context/locale-context';\r\nimport { useLocalStorage } from './hooks/useLocalstorage';\r\nimport { Homepage } from './screens/Homepage';\r\nimport { AppContextProvider } from './context/AppContextProvider';\r\nimport bg from './img/backgrounds/dark_stripes.png';\r\nimport { Cookies } from './components/cookies/Cookies';\r\nimport { getCookie, setCookie } from './hooks/useCookies';\r\n\r\nconst AppContainer = styled.div<{}>(({ theme }) => ({\r\n textAlign: 'center',\r\n minHeight: '100vh',\r\n color: theme.colors.dark,\r\n minWidth: 350,\r\n backgroundColor: '#fff'\r\n}));\r\n\r\nconst App: React.FC = () => {\r\n const appConfigContext = useContext(AppConfigContext);\r\n const [activeLocale, setActiveLocale] = useLocalStorage('activeLocale', appConfigContext.i18n.activeLocale);\r\n const [locales] = useState(appConfigContext.i18n.availableLocales);\r\n const [terms, setTerms] = useState(getCookie(\"terms\"));\r\n\r\n const localeContext: ILocaleContext = {\r\n activeLocale,\r\n locales,\r\n changeLocale: (locale: string) => {\r\n setActiveLocale(locale);\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n window.document.documentElement.lang = activeLocale;\r\n }, [activeLocale]);\r\n\r\n useEffect(() => {\r\n setTerms(getCookie(\"terms\"));\r\n\r\n if (terms === undefined || terms === \"\") {\r\n setCookie(\"terms\", \"false\", 365);\r\n }\r\n }, [terms]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n {(terms === undefined || terms === \"false\") && }\r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nexport default App;\r\n","import { useState } from 'react';\r\n\r\ntype ILocalStorageValue = boolean | number | object | string | null;\r\ntype UseLocalStorage = [any, (value: any) => void];\r\n\r\ninterface ILocalStorageHook {\r\n (key: string, initialValue: ILocalStorageValue): UseLocalStorage;\r\n}\r\n\r\nexport const useLocalStorage: ILocalStorageHook = (key, initialValue) => {\r\n const [storedValue, setStoredValue] = useState(() => {\r\n try {\r\n const item = window.localStorage.getItem(key);\r\n\r\n return item ? JSON.parse(item) : initialValue;\r\n } catch (error) {\r\n return initialValue;\r\n }\r\n });\r\n\r\n const setValue = (value: any) => {\r\n try {\r\n const valueToStore = value instanceof Function ? value(storedValue) : value;\r\n\r\n setStoredValue(valueToStore);\r\n\r\n window.localStorage.setItem(key, JSON.stringify(valueToStore));\r\n } catch (error) {\r\n console.log(error);\r\n }\r\n };\r\n\r\n return [storedValue, setValue];\r\n};\r\n","// This optional code is used to register a service worker.\r\n// register() is not called by default.\r\n\r\n// This lets the app load faster on subsequent visits in production, and gives\r\n// it offline capabilities. However, it also means that developers (and users)\r\n// will only see deployed updates on subsequent visits to a page, after all the\r\n// existing tabs open on the page have been closed, since previously cached\r\n// resources are updated in the background.\r\n\r\n// To learn more about the benefits of this model and instructions on how to\r\n// opt-in, read https://bit.ly/CRA-PWA\r\n\r\nconst isLocalhost = Boolean(\r\n window.location.hostname === 'localhost' ||\r\n // [::1] is the IPv6 localhost address.\r\n window.location.hostname === '[::1]' ||\r\n // 127.0.0.1/8 is considered localhost for IPv4.\r\n window.location.hostname.match(\r\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\r\n )\r\n);\r\n\r\ntype Config = {\r\n onSuccess?: (registration: ServiceWorkerRegistration) => void;\r\n onUpdate?: (registration: ServiceWorkerRegistration) => void;\r\n};\r\n\r\nexport function register(config?: Config) {\r\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\r\n // The URL constructor is available in all browsers that support SW.\r\n const publicUrl = new URL(\r\n (process as { env: { [key: string]: string } }).env.PUBLIC_URL,\r\n window.location.href\r\n );\r\n if (publicUrl.origin !== window.location.origin) {\r\n // Our service worker won't work if PUBLIC_URL is on a different origin\r\n // from what our page is served on. This might happen if a CDN is used to\r\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\r\n return;\r\n }\r\n\r\n window.addEventListener('load', () => {\r\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\r\n\r\n if (isLocalhost) {\r\n // This is running on localhost. Let's check if a service worker still exists or not.\r\n checkValidServiceWorker(swUrl, config);\r\n\r\n // Add some additional logging to localhost, pointing developers to the\r\n // service worker/PWA documentation.\r\n navigator.serviceWorker.ready.then(() => {\r\n console.log(\r\n 'This web app is being served cache-first by a service ' +\r\n 'worker. To learn more, visit https://bit.ly/CRA-PWA'\r\n );\r\n });\r\n } else {\r\n // Is not localhost. Just register service worker\r\n registerValidSW(swUrl, config);\r\n }\r\n });\r\n }\r\n}\r\n\r\nfunction registerValidSW(swUrl: string, config?: Config) {\r\n navigator.serviceWorker\r\n .register(swUrl)\r\n .then(registration => {\r\n registration.onupdatefound = () => {\r\n const installingWorker = registration.installing;\r\n if (installingWorker == null) {\r\n return;\r\n }\r\n installingWorker.onstatechange = () => {\r\n if (installingWorker.state === 'installed') {\r\n if (navigator.serviceWorker.controller) {\r\n // At this point, the updated precached content has been fetched,\r\n // but the previous service worker will still serve the older\r\n // content until all client tabs are closed.\r\n console.log(\r\n 'New content is available and will be used when all ' +\r\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\r\n );\r\n\r\n // Execute callback\r\n if (config && config.onUpdate) {\r\n config.onUpdate(registration);\r\n }\r\n } else {\r\n // At this point, everything has been precached.\r\n // It's the perfect time to display a\r\n // \"Content is cached for offline use.\" message.\r\n console.log('Content is cached for offline use.');\r\n\r\n // Execute callback\r\n if (config && config.onSuccess) {\r\n config.onSuccess(registration);\r\n }\r\n }\r\n }\r\n };\r\n };\r\n })\r\n .catch(error => {\r\n console.error('Error during service worker registration:', error);\r\n });\r\n}\r\n\r\nfunction checkValidServiceWorker(swUrl: string, config?: Config) {\r\n // Check if the service worker can be found. If it can't reload the page.\r\n fetch(swUrl)\r\n .then(response => {\r\n // Ensure service worker exists, and that we really are getting a JS file.\r\n const contentType = response.headers.get('content-type');\r\n if (\r\n response.status === 404 ||\r\n (contentType != null && contentType.indexOf('javascript') === -1)\r\n ) {\r\n // No service worker found. Probably a different app. Reload the page.\r\n navigator.serviceWorker.ready.then(registration => {\r\n registration.unregister().then(() => {\r\n window.location.reload();\r\n });\r\n });\r\n } else {\r\n // Service worker found. Proceed as normal.\r\n registerValidSW(swUrl, config);\r\n }\r\n })\r\n .catch(() => {\r\n console.log(\r\n 'No internet connection found. App is running in offline mode.'\r\n );\r\n });\r\n}\r\n\r\nexport function unregister() {\r\n if ('serviceWorker' in navigator) {\r\n navigator.serviceWorker.ready.then(registration => {\r\n registration.unregister();\r\n });\r\n }\r\n}\r\n","export const colors = {\r\n dark: '#090a0a',\r\n background: '#0e0f0f',\r\n lighter: '#1d2121',\r\n light: '#293333',\r\n white: '#fff',\r\n orange: '#e06900',\r\n pink: '#bf009f',\r\n red: '#700d0d',\r\n green: '#139c23',\r\n yellow: '#e8d507',\r\n gold: '#bf9d2e',\r\n grey: '#8080803d'\r\n};\r\n\r\nexport const breakpoints = {\r\n tabletAndLower: '@media only screen and (max-width: 800px)',\r\n mobileAndLower: '@media only screen and (max-width: 500px)'\r\n};\r\n","import React from 'react';\r\nimport ReactDOM from 'react-dom';\r\nimport './index.css';\r\nimport App from './App';\r\nimport * as serviceWorker from './serviceWorker';\r\nimport { Theme } from './config/theme';\r\nimport * as mainTheme from './config/main';\r\nimport { ThemeProvider } from 'emotion-theming';\r\n\r\ninterface IProps {\r\n theme?: Theme;\r\n}\r\n\r\nconst MainApp: React.FC = ({ theme = mainTheme }) => (\r\n \r\n \r\n \r\n);\r\n\r\nReactDOM.render(, document.getElementById('root'));\r\n\r\n// If you want your app to work offline and load faster, you can change\r\n// unregister() to register() below. Note this comes with some pitfalls.\r\n// Learn more about service workers: https://bit.ly/CRA-PWA\r\nserviceWorker.unregister();\r\n"],"sourceRoot":""}