about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSamuel Newman <mozzius@protonmail.com>2024-08-07 16:56:12 +0100
committerGitHub <noreply@github.com>2024-08-07 16:56:12 +0100
commitb701e8c68c1122bf138575804af41260ec1c436d (patch)
tree24b2f5d9b1241293627a972c542a62050ed63f88
parent753a2334082d279b504e164a1f50c0b0a8169f2b (diff)
downloadvoidsky-b701e8c68c1122bf138575804af41260ec1c436d.tar.zst
[Video] Authed video upload (#4885)
* add service auth call

* update API package

---------

Co-authored-by: Samuel Newman <10959775+mozzius@users.noreply.github.com>
-rw-r--r--package.json2
-rw-r--r--src/state/queries/video/video-upload.ts26
-rw-r--r--src/state/queries/video/video-upload.web.ts22
-rw-r--r--yarn.lock8
4 files changed, 42 insertions, 16 deletions
diff --git a/package.json b/package.json
index 3d053bc83..faeee448c 100644
--- a/package.json
+++ b/package.json
@@ -52,7 +52,7 @@
     "open-analyzer": "EXPO_PUBLIC_OPEN_ANALYZER=1 yarn build-web"
   },
   "dependencies": {
-    "@atproto/api": "^0.12.26",
+    "@atproto/api": "0.12.29",
     "@bam.tech/react-native-image-resizer": "^3.0.4",
     "@braintree/sanitize-url": "^6.0.2",
     "@discord/bottom-sheet": "bluesky-social/react-native-bottom-sheet",
diff --git a/src/state/queries/video/video-upload.ts b/src/state/queries/video/video-upload.ts
index 4d7f7995c..cf741b251 100644
--- a/src/state/queries/video/video-upload.ts
+++ b/src/state/queries/video/video-upload.ts
@@ -2,10 +2,11 @@ import {createUploadTask, FileSystemUploadType} from 'expo-file-system'
 import {useMutation} from '@tanstack/react-query'
 import {nanoid} from 'nanoid/non-secure'
 
-import {CompressedVideo} from 'lib/media/video/compress'
-import {UploadVideoResponse} from 'lib/media/video/types'
-import {createVideoEndpointUrl} from 'state/queries/video/util'
-import {useSession} from 'state/session'
+import {CompressedVideo} from '#/lib/media/video/compress'
+import {UploadVideoResponse} from '#/lib/media/video/types'
+import {createVideoEndpointUrl} from '#/state/queries/video/util'
+import {useAgent, useSession} from '#/state/session'
+
 const UPLOAD_HEADER = process.env.EXPO_PUBLIC_VIDEO_HEADER ?? ''
 
 export const useUploadVideoMutation = ({
@@ -18,6 +19,7 @@ export const useUploadVideoMutation = ({
   setProgress: (progress: number) => void
 }) => {
   const {currentAccount} = useSession()
+  const agent = useAgent()
 
   return useMutation({
     mutationFn: async (video: CompressedVideo) => {
@@ -26,6 +28,17 @@ export const useUploadVideoMutation = ({
         name: `${nanoid(12)}.mp4`, // @TODO what are we limiting this to?
       })
 
+      // a logged-in agent should have this set, but we'll check just in case
+      if (!agent.pdsUrl) {
+        throw new Error('Agent does not have a PDS URL')
+      }
+
+      const {data: serviceAuth} =
+        await agent.api.com.atproto.server.getServiceAuth({
+          aud: `did:web:${agent.pdsUrl.hostname}`,
+          lxm: 'com.atproto.repo.uploadBlob',
+        })
+
       const uploadTask = createUploadTask(
         uri,
         video.uri,
@@ -33,13 +46,12 @@ export const useUploadVideoMutation = ({
           headers: {
             'dev-key': UPLOAD_HEADER,
             'content-type': 'video/mp4', // @TODO same question here. does the compression step always output mp4?
+            Authorization: `Bearer ${serviceAuth.token}`,
           },
           httpMethod: 'POST',
           uploadType: FileSystemUploadType.BINARY_CONTENT,
         },
-        p => {
-          setProgress(p.totalBytesSent / p.totalBytesExpectedToSend)
-        },
+        p => setProgress(p.totalBytesSent / p.totalBytesExpectedToSend),
       )
       const res = await uploadTask.uploadAsync()
 
diff --git a/src/state/queries/video/video-upload.web.ts b/src/state/queries/video/video-upload.web.ts
index b5b9e93bf..b9b0bacfa 100644
--- a/src/state/queries/video/video-upload.web.ts
+++ b/src/state/queries/video/video-upload.web.ts
@@ -1,10 +1,11 @@
 import {useMutation} from '@tanstack/react-query'
 import {nanoid} from 'nanoid/non-secure'
 
-import {CompressedVideo} from 'lib/media/video/compress'
-import {UploadVideoResponse} from 'lib/media/video/types'
-import {createVideoEndpointUrl} from 'state/queries/video/util'
-import {useSession} from 'state/session'
+import {CompressedVideo} from '#/lib/media/video/compress'
+import {UploadVideoResponse} from '#/lib/media/video/types'
+import {createVideoEndpointUrl} from '#/state/queries/video/util'
+import {useAgent, useSession} from '#/state/session'
+
 const UPLOAD_HEADER = process.env.EXPO_PUBLIC_VIDEO_HEADER ?? ''
 
 export const useUploadVideoMutation = ({
@@ -17,6 +18,7 @@ export const useUploadVideoMutation = ({
   setProgress: (progress: number) => void
 }) => {
   const {currentAccount} = useSession()
+  const agent = useAgent()
 
   return useMutation({
     mutationFn: async (video: CompressedVideo) => {
@@ -25,6 +27,17 @@ export const useUploadVideoMutation = ({
         name: `${nanoid(12)}.mp4`, // @TODO what are we limiting this to?
       })
 
+      // a logged-in agent should have this set, but we'll check just in case
+      if (!agent.pdsUrl) {
+        throw new Error('Agent does not have a PDS URL')
+      }
+
+      const {data: serviceAuth} =
+        await agent.api.com.atproto.server.getServiceAuth({
+          aud: `did:web:${agent.pdsUrl.hostname}`,
+          lxm: 'com.atproto.repo.uploadBlob',
+        })
+
       const bytes = await fetch(video.uri).then(res => res.arrayBuffer())
 
       const xhr = new XMLHttpRequest()
@@ -53,6 +66,7 @@ export const useUploadVideoMutation = ({
         xhr.setRequestHeader('Content-Type', 'video/mp4') // @TODO how we we set the proper content type?
         // @TODO remove this header for prod
         xhr.setRequestHeader('dev-key', UPLOAD_HEADER)
+        xhr.setRequestHeader('Authorization', `Bearer ${serviceAuth.token}`)
         xhr.send(bytes)
       })) as UploadVideoResponse
 
diff --git a/yarn.lock b/yarn.lock
index 6fa880512..16547aa3a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -34,10 +34,10 @@
     jsonpointer "^5.0.0"
     leven "^3.1.0"
 
-"@atproto/api@^0.12.26":
-  version "0.12.26"
-  resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.12.26.tgz#940888466522cc9ff8c03d8164dc39221b29d9ca"
-  integrity sha512-RH0ymOGbDfT8IL8eNzzY+hwtyTgknHfkzUVqRd0sstNblvTf8WGpDR2FSTveiiMR3OpVO6zG8fRYVzBfmY1+pA==
+"@atproto/api@0.12.29":
+  version "0.12.29"
+  resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.12.29.tgz#95a19202c2f0eec4c955909685be11009ba9b9a1"
+  integrity sha512-PyzPLjGWR0qNOMrmj3Nt3N5NuuANSgOk/33Bu3j+rFjjPrHvk9CI6iQPU6zuDaDCoyOTRJRafw8X/aMQw+ilgw==
   dependencies:
     "@atproto/common-web" "^0.3.0"
     "@atproto/lexicon" "^0.4.0"