diff --git a/api/graphql/auth/auth.go b/api/graphql/auth/auth.go
index 4c82ba9a..90aa085d 100644
--- a/api/graphql/auth/auth.go
+++ b/api/graphql/auth/auth.go
@@ -27,31 +27,24 @@ func Middleware(db *sql.DB) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- bearer := r.Header.Get("Authorization")
- if bearer == "" {
- next.ServeHTTP(w, r)
- return
+ if tokenCookie, err := r.Cookie("auth-token"); err == nil {
+ log.Println("Found auth-token cookie")
+ user, err := models.VerifyTokenAndGetUser(db, tokenCookie.Value)
+ if err != nil {
+ log.Printf("Invalid token: %s\n", err)
+ http.Error(w, "invalid authorization token", http.StatusForbidden)
+ return
+ }
+
+ // put it in context
+ ctx := context.WithValue(r.Context(), userCtxKey, user)
+
+ // and call the next with our new context
+ r = r.WithContext(ctx)
+ } else {
+ log.Println("Did not find auth-token cookie")
}
- token, err := TokenFromBearer(&bearer)
- if err != nil {
- log.Printf("Invalid bearer format: %s\n", bearer)
- http.Error(w, "Invalid authorization header format", http.StatusBadRequest)
- return
- }
-
- user, err := models.VerifyTokenAndGetUser(db, *token)
- if err != nil {
- log.Printf("Invalid token: %s\n", err)
- http.Error(w, "Invalid authorization token", http.StatusForbidden)
- return
- }
-
- // put it in context
- ctx := context.WithValue(r.Context(), userCtxKey, user)
-
- // and call the next with our new context
- r = r.WithContext(ctx)
next.ServeHTTP(w, r)
})
}
diff --git a/api/routes/authenticate_media.go b/api/routes/authenticate_media.go
new file mode 100644
index 00000000..7b707c9e
--- /dev/null
+++ b/api/routes/authenticate_media.go
@@ -0,0 +1,79 @@
+package routes
+
+import (
+ "database/sql"
+ "net/http"
+
+ "github.com/viktorstrate/photoview/api/graphql/auth"
+ "github.com/viktorstrate/photoview/api/graphql/models"
+ "golang.org/x/crypto/bcrypt"
+)
+
+func authenticateMedia(media *models.Media, db *sql.DB, r *http.Request) (success bool, responseMessage string, responseStatus int, errorMessage error) {
+ user := auth.UserFromContext(r.Context())
+
+ if user != nil {
+ row := db.QueryRow("SELECT owner_id FROM album WHERE album.album_id = ?", media.AlbumId)
+ var owner_id int
+
+ if err := row.Scan(&owner_id); err != nil {
+ return false, "internal server error", http.StatusInternalServerError, err
+ }
+
+ if owner_id != user.UserID {
+ return false, "invalid credentials", http.StatusForbidden, nil
+ }
+ } else {
+ // Check if photo is authorized with a share token
+ token := r.URL.Query().Get("token")
+ if token == "" {
+ return false, "unauthorized", http.StatusForbidden, nil
+ }
+
+ row := db.QueryRow("SELECT * FROM share_token WHERE value = ?", token)
+
+ shareToken, err := models.NewShareTokenFromRow(row)
+ if err != nil {
+ return false, "internal server error", http.StatusInternalServerError, err
+ }
+
+ // Validate share token password, if set
+ if shareToken.Password != nil {
+ tokenPassword := r.Header.Get("TokenPassword")
+
+ if err := bcrypt.CompareHashAndPassword([]byte(*shareToken.Password), []byte(tokenPassword)); err != nil {
+ if err == bcrypt.ErrMismatchedHashAndPassword {
+ return false, "unauthorized", http.StatusForbidden, nil
+ } else {
+ return false, "internal server error", http.StatusInternalServerError, err
+ }
+ }
+ }
+
+ if shareToken.AlbumID != nil && media.AlbumId != *shareToken.AlbumID {
+ // Check child albums
+ row := db.QueryRow(`
+ WITH recursive child_albums AS (
+ SELECT * FROM album WHERE parent_album = ?
+ UNION ALL
+ SELECT child.* FROM album child JOIN child_albums parent ON parent.album_id = child.parent_album
+ )
+ SELECT * FROM child_albums WHERE album_id = ?
+ `, *shareToken.AlbumID, media.AlbumId)
+
+ _, err := models.NewAlbumFromRow(row)
+ if err != nil {
+ if err == sql.ErrNoRows {
+ return false, "unauthorized", http.StatusForbidden, nil
+ }
+ return false, "internal server error", http.StatusInternalServerError, err
+ }
+ }
+
+ if shareToken.MediaID != nil && media.MediaID != *shareToken.MediaID {
+ return false, "unauthorized", http.StatusForbidden, nil
+ }
+ }
+
+ return true, "success", http.StatusAccepted, nil
+}
diff --git a/api/routes/photos.go b/api/routes/photos.go
index d418fb81..6c75857c 100644
--- a/api/routes/photos.go
+++ b/api/routes/photos.go
@@ -11,9 +11,7 @@ import (
"strconv"
"github.com/gorilla/mux"
- "golang.org/x/crypto/bcrypt"
- "github.com/viktorstrate/photoview/api/graphql/auth"
"github.com/viktorstrate/photoview/api/graphql/models"
"github.com/viktorstrate/photoview/api/scanner"
)
@@ -43,90 +41,13 @@ func RegisterPhotoRoutes(db *sql.DB, router *mux.Router) {
w.Write([]byte("internal server error"))
}
- user := auth.UserFromContext(r.Context())
- if user != nil {
- row := db.QueryRow("SELECT owner_id FROM album WHERE album.album_id = ?", media.AlbumId)
- var owner_id int
-
- if err := row.Scan(&owner_id); err != nil {
- log.Printf("WARN: %s", err)
- w.WriteHeader(http.StatusInternalServerError)
- w.Write([]byte("internal server error"))
- return
- }
-
- if owner_id != user.UserID {
- w.WriteHeader(http.StatusForbidden)
- w.Write([]byte("invalid credentials"))
- return
- }
- } else {
- // Check if photo is authorized with a share token
- token := r.URL.Query().Get("token")
- if token == "" {
- w.WriteHeader(http.StatusForbidden)
- w.Write([]byte("unauthorized"))
- return
- }
-
- row := db.QueryRow("SELECT * FROM share_token WHERE value = ?", token)
-
- shareToken, err := models.NewShareTokenFromRow(row)
+ if success, response, status, err := authenticateMedia(media, db, r); !success {
if err != nil {
- log.Printf("WARN: %s", err)
- w.WriteHeader(http.StatusInternalServerError)
- w.Write([]byte("internal server error"))
- return
+ log.Printf("WARN: error authenticating photo: %s\n", err)
}
-
- // Validate share token password, if set
- if shareToken.Password != nil {
- tokenPassword := r.Header.Get("TokenPassword")
-
- if err := bcrypt.CompareHashAndPassword([]byte(*shareToken.Password), []byte(tokenPassword)); err != nil {
- if err == bcrypt.ErrMismatchedHashAndPassword {
- w.WriteHeader(http.StatusForbidden)
- w.Write([]byte("unauthorized"))
- return
- } else {
- w.WriteHeader(http.StatusInternalServerError)
- w.Write([]byte("internal server error"))
- return
- }
- }
- }
-
- if shareToken.AlbumID != nil && media.AlbumId != *shareToken.AlbumID {
- // Check child albums
- row := db.QueryRow(`
- WITH recursive child_albums AS (
- SELECT * FROM album WHERE parent_album = ?
- UNION ALL
- SELECT child.* FROM album child JOIN child_albums parent ON parent.album_id = child.parent_album
- )
- SELECT * FROM child_albums WHERE album_id = ?
- `, *shareToken.AlbumID, media.AlbumId)
-
- _, err := models.NewAlbumFromRow(row)
- if err != nil {
- if err == sql.ErrNoRows {
- w.WriteHeader(http.StatusForbidden)
- w.Write([]byte("unauthorized"))
- return
- }
- log.Printf("WARN: %s", err)
- w.WriteHeader(http.StatusInternalServerError)
- w.Write([]byte("internal server error"))
- return
- }
- }
-
- if shareToken.MediaID != nil && media_id != *shareToken.MediaID {
- w.WriteHeader(http.StatusForbidden)
- w.Write([]byte("unauthorized"))
- return
- }
-
+ w.WriteHeader(status)
+ w.Write([]byte(response))
+ return
}
var cachedPath string
diff --git a/api/routes/videos.go b/api/routes/videos.go
index f4f05fc1..240cfc1e 100644
--- a/api/routes/videos.go
+++ b/api/routes/videos.go
@@ -38,6 +38,16 @@ func RegisterVideoRoutes(db *sql.DB, router *mux.Router) {
}
// TODO: Make sure user is authorized to access video
+ if success, response, status, err := authenticateMedia(media, db, r); !success {
+ if err != nil {
+ log.Printf("WARN: error authenticating video: %s\n", err)
+ }
+ w.WriteHeader(status)
+ w.Write([]byte(response))
+ return
+ }
+
+ log.Printf("Video cookies: %d", len(r.Cookies()))
var cachedPath string
diff --git a/api/server/cors_middleware.go b/api/server/cors_middleware.go
index 007ee380..419e0f52 100644
--- a/api/server/cors_middleware.go
+++ b/api/server/cors_middleware.go
@@ -18,6 +18,7 @@ func CORSMiddleware(devMode bool) mux.MiddlewareFunc {
w.Header().Set("Access-Control-Allow-Methods", strings.Join(methods, ","))
w.Header().Set("Access-Control-Allow-Headers", strings.Join(headers, ","))
+ w.Header().Set("Access-Control-Allow-Credentials", "true")
w.Header().Set("Access-Control-Expose-Headers", "content-length")
endpoint := utils.ApiEndpointUrl()
diff --git a/ui/src/AuthorizedRoute.js b/ui/src/AuthorizedRoute.js
index 967c7c1e..ca9c75f4 100644
--- a/ui/src/AuthorizedRoute.js
+++ b/ui/src/AuthorizedRoute.js
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
import { Route, Redirect } from 'react-router-dom'
import gql from 'graphql-tag'
import { Query } from 'react-apollo'
+import { authToken } from './authentication'
const adminQuery = gql`
query adminQuery {
@@ -13,13 +14,13 @@ const adminQuery = gql`
`
export const Authorized = ({ children }) => {
- const token = localStorage.getItem('token')
+ const token = authToken()
return token ? children : null
}
const AuthorizedRoute = ({ component: Component, admin = false, ...props }) => {
- const token = localStorage.getItem('token')
+ const token = authToken()
let unauthorizedRedirect = null
if (!token) {
diff --git a/ui/src/Pages/LoginPage/InitialSetupPage.js b/ui/src/Pages/LoginPage/InitialSetupPage.js
index 07b07ac2..be15f7e1 100644
--- a/ui/src/Pages/LoginPage/InitialSetupPage.js
+++ b/ui/src/Pages/LoginPage/InitialSetupPage.js
@@ -6,6 +6,7 @@ import { Button, Form, Message, Header } from 'semantic-ui-react'
import { Container } from './LoginPage'
import { checkInitialSetupQuery, login } from './loginUtilFunctions'
+import { authToken } from '../../authentication'
const initialSetupMutation = gql`
mutation InitialSetup(
@@ -53,7 +54,7 @@ class InitialSetupPage extends Component {
}
render() {
- if (localStorage.getItem('token')) {
+ if (authToken()) {
return
}
diff --git a/ui/src/Pages/LoginPage/LoginPage.js b/ui/src/Pages/LoginPage/LoginPage.js
index 270766c5..f7abbf20 100644
--- a/ui/src/Pages/LoginPage/LoginPage.js
+++ b/ui/src/Pages/LoginPage/LoginPage.js
@@ -11,6 +11,7 @@ import {
Header,
} from 'semantic-ui-react'
import { checkInitialSetupQuery, login } from './loginUtilFunctions'
+import { authToken } from '../../authentication'
import logoPath from '../../assets/photoview-logo.svg'
@@ -69,7 +70,7 @@ class LoginPage extends Component {
}
render() {
- if (localStorage.getItem('token')) {
+ if (authToken()) {
return
}
diff --git a/ui/src/Pages/LoginPage/loginUtilFunctions.js b/ui/src/Pages/LoginPage/loginUtilFunctions.js
index 8a112630..8903f40c 100644
--- a/ui/src/Pages/LoginPage/loginUtilFunctions.js
+++ b/ui/src/Pages/LoginPage/loginUtilFunctions.js
@@ -1,4 +1,5 @@
import gql from 'graphql-tag'
+import { saveTokenCookie } from '../../authentication'
export const checkInitialSetupQuery = gql`
query CheckInitialSetup {
@@ -9,6 +10,6 @@ export const checkInitialSetupQuery = gql`
`
export function login(token) {
- localStorage.setItem('token', token)
+ saveTokenCookie(token)
window.location = '/'
}
diff --git a/ui/src/Pages/SharePage/MediaSharePage.js b/ui/src/Pages/SharePage/MediaSharePage.js
index 96209e69..197fb250 100644
--- a/ui/src/Pages/SharePage/MediaSharePage.js
+++ b/ui/src/Pages/SharePage/MediaSharePage.js
@@ -30,7 +30,12 @@ const MediaView = ({ media }) => {
if (media.type == 'video') {
return (
-
+
)
diff --git a/ui/src/Routes.js b/ui/src/Routes.js
index 8ce867c8..63a568a3 100644
--- a/ui/src/Routes.js
+++ b/ui/src/Routes.js
@@ -3,6 +3,7 @@ import { Route, Switch, Redirect } from 'react-router-dom'
import { Loader } from 'semantic-ui-react'
import Layout from './Layout'
+import { clearTokenCookie } from './authentication'
const AlbumsPage = React.lazy(() => import('./Pages/AllAlbumsPage/AlbumsPage'))
const AlbumPage = React.lazy(() => import('./Pages/AlbumPage/AlbumPage'))
@@ -33,7 +34,7 @@ class Routes extends React.Component {
{() => {
- localStorage.removeItem('token')
+ clearTokenCookie()
location.href = '/'
}}
diff --git a/ui/src/apolloClient.js b/ui/src/apolloClient.js
index a9253ab6..5cdd372e 100644
--- a/ui/src/apolloClient.js
+++ b/ui/src/apolloClient.js
@@ -8,14 +8,15 @@ import { ApolloLink, split } from 'apollo-link'
import { getMainDefinition } from 'apollo-utilities'
import { MessageState } from './components/messages/Messages'
import urlJoin from 'url-join'
+import { clearTokenCookie } from './authentication'
-const GRAPHQL_ENDPOINT = process.env.API_ENDPOINT
+export const GRAPHQL_ENDPOINT = process.env.API_ENDPOINT
? urlJoin(process.env.API_ENDPOINT, '/graphql')
: urlJoin(location.origin, '/api/graphql')
const httpLink = new HttpLink({
uri: GRAPHQL_ENDPOINT,
- credentials: 'same-origin',
+ credentials: 'include',
})
console.log('GRAPHQL ENDPOINT', GRAPHQL_ENDPOINT)
@@ -27,13 +28,7 @@ websocketUri.protocol = apiProtocol === 'https:' ? 'wss:' : 'ws:'
const wsLink = new WebSocketLink({
uri: websocketUri,
- credentials: 'same-origin',
- options: {
- reconnect: true,
- connectionParams: {
- Authorization: `Bearer ${localStorage.getItem('token')}`,
- },
- },
+ credentials: 'include',
})
const link = split(
@@ -76,7 +71,7 @@ const linkError = onError(({ graphQLErrors, networkError }) => {
if (networkError) {
console.log(`[Network error]: ${JSON.stringify(networkError)}`)
- localStorage.removeItem('token')
+ clearTokenCookie()
const errors = networkError.result.errors
@@ -106,20 +101,9 @@ const linkError = onError(({ graphQLErrors, networkError }) => {
}
})
-const authLink = setContext((_, { headers }) => {
- // get the authentication token from local storage if it exists
- const token = localStorage.getItem('token')
- // return the headers to the context so httpLink can read them
- return {
- headers: {
- ...headers,
- authorization: token ? `Bearer ${token}` : '',
- },
- }
-})
-
const client = new ApolloClient({
- link: ApolloLink.from([linkError, authLink.concat(link)]),
+ // link: ApolloLink.from([linkError, authLink.concat(link)]),
+ link: ApolloLink.from([linkError, link]),
cache: new InMemoryCache(),
})
diff --git a/ui/src/authentication.js b/ui/src/authentication.js
new file mode 100644
index 00000000..bfa2c422
--- /dev/null
+++ b/ui/src/authentication.js
@@ -0,0 +1,14 @@
+export function saveTokenCookie(token) {
+ const maxAge = 14 * 24 * 60 * 60
+
+ document.cookie = `auth-token=${token} ;max-age=${maxAge} ;path=/ ;sameSite=Lax`
+}
+
+export function clearTokenCookie() {
+ document.cookie = 'auth-token= ;max-age=0'
+}
+
+export function authToken() {
+ const match = document.cookie.match(/auth-token=([\d\w]+)/)
+ return match && match[1]
+}
diff --git a/ui/src/components/AlbumTitle.js b/ui/src/components/AlbumTitle.js
index 8679545f..2e58dcf5 100644
--- a/ui/src/components/AlbumTitle.js
+++ b/ui/src/components/AlbumTitle.js
@@ -8,6 +8,7 @@ import { SidebarContext } from './sidebar/Sidebar'
import AlbumSidebar from './sidebar/AlbumSidebar'
import gql from 'graphql-tag'
import { useLazyQuery } from '@apollo/react-hooks'
+import { authToken } from '../authentication'
const Header = styled.h1`
margin: 24px 0 8px 0 !important;
@@ -55,7 +56,7 @@ const AlbumTitle = ({ album, disableLink = false }) => {
useEffect(() => {
if (!album) return
- if (localStorage.getItem('token') && disableLink == true) {
+ if (authToken() && disableLink == true) {
fetchPath({
variables: {
id: album.id,
@@ -93,7 +94,7 @@ const AlbumTitle = ({ album, disableLink = false }) => {
{breadcrumbSections}
{title}
- {localStorage.getItem('token') && (
+ {authToken() && (
{
updateSidebar()
diff --git a/ui/src/components/header/Header.js b/ui/src/components/header/Header.js
index 4db37ef6..b7cb2a31 100644
--- a/ui/src/components/header/Header.js
+++ b/ui/src/components/header/Header.js
@@ -3,6 +3,7 @@ import styled from 'styled-components'
import SearchBar from './Searchbar'
import logoPath from '../../assets/photoview-logo.svg'
+import { authToken } from '../../authentication'
const Container = styled.div`
height: 60px;
@@ -40,7 +41,7 @@ const Header = () => (
Photoview
- {localStorage.getItem('token') ? : null}
+ {authToken() ? : null}
)
diff --git a/ui/src/components/messages/Messages.js b/ui/src/components/messages/Messages.js
index a2f9bab2..60bbead6 100644
--- a/ui/src/components/messages/Messages.js
+++ b/ui/src/components/messages/Messages.js
@@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react'
import { useTransition, animated } from 'react-spring'
import styled from 'styled-components'
import { Message } from 'semantic-ui-react'
+import { authToken } from '../../authentication'
import MessageProgress from './MessageProgress'
import SubscriptionsHook from './SubscriptionsHook'
@@ -124,7 +125,7 @@ const Messages = () => {
)
})}
- {localStorage.getItem('token') && (
+ {authToken() && (
)}
diff --git a/ui/src/components/messages/SubscriptionsHook.js b/ui/src/components/messages/SubscriptionsHook.js
index f37670d4..e5f54e41 100644
--- a/ui/src/components/messages/SubscriptionsHook.js
+++ b/ui/src/components/messages/SubscriptionsHook.js
@@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react'
import PropTypes from 'prop-types'
import { useSubscription } from 'react-apollo'
import gql from 'graphql-tag'
+import { authToken } from '../../authentication'
const notificationSubscription = gql`
subscription notificationSubscription {
@@ -21,7 +22,7 @@ const notificationSubscription = gql`
let messageTimeoutHandles = new Map()
const SubscriptionsHook = ({ messages, setMessages }) => {
- if (!localStorage.getItem('token')) {
+ if (!authToken()) {
return null
}
diff --git a/ui/src/components/photoGallery/ProtectedImage.js b/ui/src/components/photoGallery/ProtectedImage.js
index bf2b6e93..a9194a8d 100644
--- a/ui/src/components/photoGallery/ProtectedImage.js
+++ b/ui/src/components/photoGallery/ProtectedImage.js
@@ -1,91 +1,91 @@
import React, { useEffect, useState } from 'react'
import PropTypes from 'prop-types'
-let imageCache = {}
+// let imageCache = {}
-export async function fetchProtectedImage(
- src,
- { signal, headers: customHeaders } = { signal: null, headers: null }
-) {
- if (src) {
- if (imageCache[src]) {
- return imageCache[src]
- }
+// export async function fetchProtectedImage(
+// src,
+// { signal, headers: customHeaders } = { signal: null, headers: null }
+// ) {
+// if (src) {
+// if (imageCache[src]) {
+// return imageCache[src]
+// }
- let headers = {
- ...customHeaders,
- }
- if (localStorage.getItem('token')) {
- headers['Authorization'] = `Bearer ${localStorage.getItem('token')}`
- }
+// let headers = {
+// ...customHeaders,
+// }
+// if (localStorage.getItem('token')) {
+// headers['Authorization'] = `Bearer ${localStorage.getItem('token')}`
+// }
- let image = await fetch(src, {
- headers,
- signal,
- })
+// let image = await fetch(src, {
+// headers,
+// signal,
+// })
- image = await image.blob()
- const url = URL.createObjectURL(image)
+// image = await image.blob()
+// const url = URL.createObjectURL(image)
- // eslint-disable-next-line require-atomic-updates
- imageCache[src] = url
+// // eslint-disable-next-line require-atomic-updates
+// imageCache[src] = url
- return url
- }
-}
+// return url
+// }
+// }
/**
* An image that needs a authorization header to load
*/
const ProtectedImage = ({ src, ...props }) => {
- const [imgSrc, setImgSrc] = useState(null)
+ // const [imgSrc, setImgSrc] = useState(null)
- useEffect(() => {
- if (imageCache[src]) return
+ // useEffect(() => {
+ // if (imageCache[src]) return
- const fetchController = new AbortController()
- let canceled = false
+ // const fetchController = new AbortController()
+ // let canceled = false
- setImgSrc('')
+ // setImgSrc('')
- const imgUrl = new URL(src)
- const fetchHeaders = {}
+ // const imgUrl = new URL(src)
+ // const fetchHeaders = {}
- if (localStorage.getItem('token') == null) {
- // Get share token if not authorized
+ // if (localStorage.getItem('token') == null) {
+ // // Get share token if not authorized
- const tokenRegex = location.pathname.match(/^\/share\/([\d\w]+)(\/?.*)$/)
- if (tokenRegex) {
- const token = tokenRegex[1]
- imgUrl.searchParams.set('token', token)
+ // const tokenRegex = location.pathname.match(/^\/share\/([\d\w]+)(\/?.*)$/)
+ // if (tokenRegex) {
+ // const token = tokenRegex[1]
+ // imgUrl.searchParams.set('token', token)
- const tokenPassword = sessionStorage.getItem(`share-token-pw-${token}`)
- if (tokenPassword) {
- fetchHeaders['TokenPassword'] = tokenPassword
- }
- }
- }
+ // const tokenPassword = sessionStorage.getItem(`share-token-pw-${token}`)
+ // if (tokenPassword) {
+ // fetchHeaders['TokenPassword'] = tokenPassword
+ // }
+ // }
+ // }
- fetchProtectedImage(imgUrl.href, {
- signal: fetchController.signal,
- headers: fetchHeaders,
- })
- .then(newSrc => {
- if (!canceled) {
- setImgSrc(newSrc)
- }
- })
- .catch(error => {
- console.log('Fetch image error', error.message)
- })
+ // fetchProtectedImage(imgUrl.href, {
+ // signal: fetchController.signal,
+ // headers: fetchHeaders,
+ // })
+ // .then(newSrc => {
+ // if (!canceled) {
+ // setImgSrc(newSrc)
+ // }
+ // })
+ // .catch(error => {
+ // console.log('Fetch image error', error.message)
+ // })
- return function cleanup() {
- canceled = true
- fetchController.abort()
- }
- }, [src])
+ // return function cleanup() {
+ // canceled = true
+ // fetchController.abort()
+ // }
+ // }, [src])
- return
+ return
}
ProtectedImage.propTypes = {
diff --git a/ui/src/components/photoGallery/presentView/PresentMedia.js b/ui/src/components/photoGallery/presentView/PresentMedia.js
index e1947c55..4fa55e20 100644
--- a/ui/src/components/photoGallery/presentView/PresentMedia.js
+++ b/ui/src/components/photoGallery/presentView/PresentMedia.js
@@ -41,7 +41,12 @@ const PresentMedia = ({ media, imageLoaded, ...otherProps }) => {
if (media.type == 'video') {
return (
-
+
diff --git a/ui/src/components/sidebar/MediaSidebar.js b/ui/src/components/sidebar/MediaSidebar.js
index de9e1193..da44bbeb 100644
--- a/ui/src/components/sidebar/MediaSidebar.js
+++ b/ui/src/components/sidebar/MediaSidebar.js
@@ -7,6 +7,7 @@ import SidebarItem from './SidebarItem'
import ProtectedImage from '../photoGallery/ProtectedImage'
import SidebarShare from './Sharing'
import SidebarDownload from './SidebarDownload'
+import { authToken } from '../../authentication'
const mediaQuery = gql`
query sidebarPhoto($id: Int!) {
@@ -87,7 +88,12 @@ const PreviewMedia = ({ media, previewImage }) => {
if (media.type == 'video') {
return (
-
+
)
@@ -225,7 +231,7 @@ const MediaSidebar = ({ media, hidePreview }) => {
const [loadMedia, { loading, error, data }] = useLazyQuery(mediaQuery)
useEffect(() => {
- if (media != null && localStorage.getItem('token')) {
+ if (media != null && authToken()) {
loadMedia({
variables: {
id: media.id,
@@ -236,7 +242,7 @@ const MediaSidebar = ({ media, hidePreview }) => {
if (!media) return null
- if (!localStorage.getItem('token')) {
+ if (!authToken()) {
return
}
diff --git a/ui/src/components/sidebar/Sharing.js b/ui/src/components/sidebar/Sharing.js
index a36541e8..3b0793d2 100644
--- a/ui/src/components/sidebar/Sharing.js
+++ b/ui/src/components/sidebar/Sharing.js
@@ -11,6 +11,7 @@ import {
Icon,
} from 'semantic-ui-react'
import copy from 'copy-to-clipboard'
+import { authToken } from '../../authentication'
const sharePhotoQuery = gql`
query sidbarGetPhotoShares($id: Int!) {
@@ -218,7 +219,7 @@ ShareItemMoreDropdown.propTypes = {
const SidebarShare = ({ photo, album }) => {
if ((!photo || !photo.id) && (!album || !album.id)) return null
- if (!localStorage.getItem('token')) return null
+ if (!authToken()) return null
const isPhoto = !!photo
const id = isPhoto ? photo.id : album.id
diff --git a/ui/src/components/sidebar/SidebarDownload.js b/ui/src/components/sidebar/SidebarDownload.js
index 406e8202..71ce882e 100644
--- a/ui/src/components/sidebar/SidebarDownload.js
+++ b/ui/src/components/sidebar/SidebarDownload.js
@@ -6,6 +6,7 @@ import { MessageState } from '../messages/Messages'
import { useLazyQuery } from 'react-apollo'
import gql from 'graphql-tag'
import download from 'downloadjs'
+import { authToken } from '../../authentication'
const downloadQuery = gql`
query sidebarDownloadQuery($mediaId: Int!) {
@@ -30,22 +31,22 @@ function formatBytes(bytes) {
const downloadPhoto = async url => {
const imgUrl = new URL(url)
- let headers = {
- Authorization: `Bearer ${localStorage.getItem('token')}`,
- }
+ // let headers = {
+ // Authorization: `Bearer ${localStorage.getItem('token')}`,
+ // }
- if (localStorage.getItem('token') == null) {
+ if (authToken() == null) {
// Get share token if not authorized
const token = location.pathname.match(/^\/share\/([\d\w]+)(\/?.*)$/)
if (token) {
imgUrl.searchParams.set('token', token[1])
}
- headers = {}
+ // headers = {}
}
const response = await fetch(imgUrl.href, {
- headers,
+ // headers,
})
const totalBytes = Number(response.headers.get('content-length'))