mirror of
https://github.com/ApfelTeeSaft/R2-Explorer.git
synced 2026-08-26 19:33:39 +00:00
added register page
This commit is contained in:
+33
-2
@@ -1,3 +1,5 @@
|
||||
import { S3Client } from '@aws-sdk/client-s3'
|
||||
|
||||
function JsonResponse (json, status = 200, headers = {}) {
|
||||
return new Response(JSON.stringify(json), {
|
||||
headers: {
|
||||
@@ -7,8 +9,37 @@ function JsonResponse (json, status = 200, headers = {}) {
|
||||
'access-control-allow-methods': '*',
|
||||
...headers
|
||||
},
|
||||
status: status
|
||||
status
|
||||
})
|
||||
}
|
||||
|
||||
export { JsonResponse }
|
||||
function getS3 (accountId, accessToken, secretToken) {
|
||||
return new S3Client({
|
||||
region: 'auto',
|
||||
endpoint: `https://${accountId}.r2.cloudflarestorage.com`,
|
||||
credentials: {
|
||||
|
||||
accessKeyId: `${accessToken}`,
|
||||
secretAccessKey: `${secretToken}`
|
||||
},
|
||||
accessKeyId: `${accessToken}`,
|
||||
secretAccessKey: `${secretToken}`,
|
||||
s3DisableBodySigning: false,
|
||||
s3ForcePathStyle: true,
|
||||
maxRetries: 2
|
||||
})
|
||||
}
|
||||
|
||||
async function getS3ForEmail (env, email) {
|
||||
let data = await env.WEB_DRIVE.get(email)
|
||||
console.log(data)
|
||||
if (!data) {
|
||||
return null
|
||||
}
|
||||
|
||||
data = JSON.parse(data)
|
||||
|
||||
return getS3(data.accountId, data.accessToken, data.secretToken)
|
||||
}
|
||||
|
||||
export { JsonResponse, getS3, getS3ForEmail }
|
||||
|
||||
@@ -4,6 +4,7 @@ import { PutObjectCommand } from '@aws-sdk/client-s3'
|
||||
async function createFolder (request, env, context) {
|
||||
const body = await request.json()
|
||||
const { s3Client } = context
|
||||
if (s3Client === null) return JsonResponse('unauthorized', 401)
|
||||
const { disk } = request.params
|
||||
console.log(body)
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import { DeleteObjectCommand } from '@aws-sdk/client-s3'
|
||||
async function deleteObject (request, env, context) {
|
||||
const body = await request.json()
|
||||
const { s3Client } = context
|
||||
if (s3Client === null) return JsonResponse('unauthorized', 401)
|
||||
const { disk } = request.params
|
||||
|
||||
const { name } = body
|
||||
|
||||
@@ -5,6 +5,7 @@ import { getSignedUrl } from '@aws-sdk/s3-request-presigner'
|
||||
async function getDownloadUrl (request, env, context) {
|
||||
const body = await request.json()
|
||||
const { s3Client } = context
|
||||
if (s3Client === null) return JsonResponse('unauthorized', 401)
|
||||
const { disk } = request.params
|
||||
|
||||
const { name } = body
|
||||
|
||||
@@ -5,6 +5,7 @@ import { getSignedUrl } from '@aws-sdk/s3-request-presigner'
|
||||
async function getUploadUrl (request, env, context) {
|
||||
const body = await request.json()
|
||||
const { s3Client } = context
|
||||
if (s3Client === null) return JsonResponse('unauthorized', 401)
|
||||
const { disk } = request.params
|
||||
|
||||
const { name } = body
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { JsonResponse } from './core'
|
||||
|
||||
async function isRegisted (request, env, context) {
|
||||
return JsonResponse({ result: context.s3Client !== null })
|
||||
}
|
||||
|
||||
export { isRegisted }
|
||||
@@ -3,6 +3,7 @@ import { ListObjectsV2Command } from '@aws-sdk/client-s3'
|
||||
|
||||
async function listContents (request, env, context) {
|
||||
const { s3Client } = context
|
||||
if (s3Client === null) return JsonResponse('unauthorized', 401)
|
||||
const { disk } = request.params
|
||||
const { path } = request.query || ''
|
||||
|
||||
|
||||
@@ -3,10 +3,12 @@ import { ListBucketsCommand } from '@aws-sdk/client-s3'
|
||||
|
||||
async function listDisks (request, env, context) {
|
||||
const { s3Client } = context
|
||||
if (s3Client === null) return JsonResponse('unauthorized', 401)
|
||||
|
||||
const email = request.headers.get('Cf-Access-Authenticated-User-Email')
|
||||
const data = await s3Client.send(new ListBucketsCommand({}))
|
||||
|
||||
return JsonResponse(data, data.$metadata.httpStatusCode)
|
||||
return JsonResponse({ user: email, ...data }, data.$metadata.httpStatusCode)
|
||||
}
|
||||
|
||||
export { listDisks }
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { getS3, JsonResponse } from './core'
|
||||
import { ListBucketsCommand } from '@aws-sdk/client-s3'
|
||||
|
||||
async function registerEmail (request, env, context) {
|
||||
const email = request.headers.get('Cf-Access-Authenticated-User-Email') || '[email protected]'
|
||||
const body = await request.json()
|
||||
const { accountId, accessToken, secretToken } = body
|
||||
|
||||
const s3Client = getS3(accountId, accessToken, secretToken)
|
||||
console.log(body)
|
||||
// Test the credentials
|
||||
try {
|
||||
await s3Client.send(new ListBucketsCommand({}))
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
return JsonResponse({ result: 'unauthorized' }, 401)
|
||||
}
|
||||
|
||||
await env.WEB_DRIVE.put(email, JSON.stringify({
|
||||
accountId, accessToken, secretToken
|
||||
}))
|
||||
|
||||
return JsonResponse({ result: 'success' })
|
||||
}
|
||||
|
||||
export { registerEmail }
|
||||
@@ -4,6 +4,7 @@ import { CopyObjectCommand, DeleteObjectCommand } from '@aws-sdk/client-s3'
|
||||
async function renameObject (request, env, context) {
|
||||
const body = await request.json()
|
||||
const { s3Client } = context
|
||||
if (s3Client === null) return JsonResponse('unauthorized', 401)
|
||||
const { disk } = request.params
|
||||
|
||||
const { path } = body
|
||||
|
||||
@@ -4,6 +4,7 @@ import { PutObjectCommand } from '@aws-sdk/client-s3'
|
||||
async function uploadFiles (request, env, context) {
|
||||
const form = await request.formData()
|
||||
const { s3Client } = context
|
||||
if (s3Client === null) return JsonResponse('unauthorized', 401)
|
||||
const { disk } = request.params
|
||||
|
||||
// const path = form.get('path')
|
||||
|
||||
@@ -4,10 +4,7 @@ const config = {
|
||||
'access-control-allow-headers': '*',
|
||||
'access-control-allow-methods': '*',
|
||||
'timing-allow-origin': '*'
|
||||
},
|
||||
accountid: '0983f9c21d0167d8d677be145016932e',
|
||||
access_key_id: '112326db443e709a2e6ea23bc2af7754',
|
||||
access_key_secret: 'e6892b8890a2e4d889eecf903bf8e476fa2f6d3f460f3286684c7d9dd39cfb47'
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
|
||||
+7
-15
@@ -1,6 +1,5 @@
|
||||
import { Router } from 'itty-router'
|
||||
import { config } from './config'
|
||||
import { S3Client } from '@aws-sdk/client-s3'
|
||||
import { listDisks } from './api/listDisks'
|
||||
import { listContents } from './api/listContents'
|
||||
import { getDownloadUrl } from './api/getDownloadUrl'
|
||||
@@ -8,9 +7,15 @@ import { uploadFiles } from './api/uploadFiles'
|
||||
import { createFolder } from './api/createFolder'
|
||||
import { deleteObject } from './api/deleteObject'
|
||||
import { renameObject } from './api/renameObject'
|
||||
import { registerEmail } from './api/register'
|
||||
import { isRegisted } from './api/isRegisted'
|
||||
import { getS3ForEmail } from './api/core'
|
||||
|
||||
const router = Router()
|
||||
|
||||
router.get('/api/is-registed', isRegisted)
|
||||
router.post('/api/register', registerEmail)
|
||||
|
||||
router.get('/api/disks', listDisks)
|
||||
router.get('/api/disks/:disk', listContents)
|
||||
router.post('/api/disks/:disk/rename', renameObject)
|
||||
@@ -33,20 +38,7 @@ router.all('*', () => new Response('404, not found!', { status: 404 }))
|
||||
|
||||
export default {
|
||||
async fetch (request, env, context) {
|
||||
const s3Client = new S3Client({
|
||||
region: 'auto',
|
||||
endpoint: `https://${config.accountid}.r2.cloudflarestorage.com`,
|
||||
credentials: {
|
||||
|
||||
accessKeyId: `${config.access_key_id}`,
|
||||
secretAccessKey: `${config.access_key_secret}`
|
||||
},
|
||||
accessKeyId: `${config.access_key_id}`,
|
||||
secretAccessKey: `${config.access_key_secret}`,
|
||||
s3DisableBodySigning: false,
|
||||
s3ForcePathStyle: true,
|
||||
maxRetries: 2
|
||||
})
|
||||
const s3Client = await getS3ForEmail(env, request.headers.get('Cf-Access-Authenticated-User-Email') || '[email protected]')
|
||||
|
||||
return router
|
||||
.handle(request, env, { ...context, s3Client })
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
name = "Drive Backend"
|
||||
name = "drive"
|
||||
main = "src/index.js"
|
||||
compatibility_date = "2022-06-21"
|
||||
|
||||
kv_namespaces = [
|
||||
{ binding = "WEB_DRIVE", id = "4355f4de9a624466867c8a2c1dce32df", preview_id = "a4d4a08e61cc4ce884f4869f67378c7a" }
|
||||
]
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
<ul class="list-unstyled topnav-menu float-end mb-0">
|
||||
|
||||
<li class="dropdown notification-list topbar-dropdown">
|
||||
<a class="nav-link dropdown-toggle nav-user me-0 waves-effect waves-light" data-bs-toggle="dropdown" href="#"
|
||||
<a v-if="$store.user && $store.user.email" class="nav-link dropdown-toggle nav-user me-0 waves-effect waves-light" data-bs-toggle="dropdown" href="#"
|
||||
role="button" aria-haspopup="false" aria-expanded="false">
|
||||
<span class="pro-user-name ms-1">
|
||||
Username <i class="mdi mdi-chevron-down"></i>
|
||||
{{$store.user.email}} <i class="mdi mdi-chevron-down"></i>
|
||||
</span>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-end profile-dropdown ">
|
||||
@@ -20,11 +20,11 @@
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dropdown notification-list">
|
||||
<a href="javascript:void(0);" class="nav-link right-bar-toggle waves-effect waves-light">
|
||||
<i class="bi bi-asterisk"></i>
|
||||
</a>
|
||||
</li>
|
||||
<!-- <li class="dropdown notification-list">-->
|
||||
<!-- <a href="javascript:void(0);" class="nav-link right-bar-toggle waves-effect waves-light">-->
|
||||
<!-- <i class="bi bi-asterisk"></i>-->
|
||||
<!-- </a>-->
|
||||
<!-- </li>-->
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -25,5 +25,3 @@ app.use(router)
|
||||
app.use(VueToast)
|
||||
|
||||
app.mount('#app')
|
||||
|
||||
store.dispatch('loadUserDisks')
|
||||
|
||||
+2
-2
@@ -3,12 +3,12 @@ import HomeView from '../views/HomeView.vue'
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
path: '/explorer',
|
||||
name: 'home',
|
||||
component: HomeView
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
path: '/',
|
||||
name: 'login',
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (about.[hash].js) for this route
|
||||
|
||||
@@ -65,6 +65,7 @@ import Swal from 'sweetalert2'
|
||||
import Gallery from '@/components/Gallery'
|
||||
import DragAndDrop from '@/components/DragAndDrop'
|
||||
import repo from '@/repo'
|
||||
|
||||
export default {
|
||||
components: { DragAndDrop, Gallery },
|
||||
methods: {
|
||||
@@ -96,6 +97,9 @@ export default {
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.$store.dispatch('loadUserDisks')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
+82
-3
@@ -1,10 +1,43 @@
|
||||
<template>
|
||||
<!-- start page title -->
|
||||
<div class="row">
|
||||
<!-- Right Sidebar -->
|
||||
<div class="col-12">
|
||||
<div class="page-title-box">
|
||||
<div class="page-title-right">
|
||||
|
||||
</div>
|
||||
<!-- <h4 class="page-title">File Manager</h4>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end page title -->
|
||||
|
||||
<div class="row">
|
||||
|
||||
<!-- Right Sidebar -->
|
||||
<div class="col-6 mx-auto">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
|
||||
<h3>Please enter your R2 tokens to continue</h3>
|
||||
|
||||
<div>
|
||||
<div class="form-group">
|
||||
<label class="form-label mt-4">CF Account id</label>
|
||||
<input v-model="account_id" type="text" class="form-control" placeholder="Account id">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label mt-4">CF R2 Access token</label>
|
||||
<input v-model="access_token" type="text" class="form-control" placeholder="Access token">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label mt-4">CF R2 Secret token</label>
|
||||
<input v-model="secret_token" type="text" class="form-control" placeholder="Secret token">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button @click="register" type="button" class="btn btn-primary mt-3">Save</button>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div> <!-- end card -->
|
||||
@@ -14,10 +47,56 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import repo from '@/repository'
|
||||
|
||||
import axios from 'axios'
|
||||
|
||||
export default {
|
||||
beforeMount () {
|
||||
data () {
|
||||
return {
|
||||
account_id: null,
|
||||
access_token: null,
|
||||
secret_token: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
register () {
|
||||
if (!this.account_id || !this.access_token || !this.secret_token) return null
|
||||
|
||||
const self = this
|
||||
|
||||
axios.post('/api/register', {
|
||||
accountId: this.account_id,
|
||||
accessToken: this.access_token,
|
||||
secretToken: this.secret_token
|
||||
}).then((data) => {
|
||||
if (data.status === 200) {
|
||||
this.$toast.open({
|
||||
message: 'Credentials Saved, redirecting you...',
|
||||
type: 'success'
|
||||
})
|
||||
setTimeout(function () {
|
||||
self.$router.push({ name: 'home' })
|
||||
}, 2000)
|
||||
} else {
|
||||
console.log(data)
|
||||
}
|
||||
}).catch(error => {
|
||||
if (error.response.status === 401) {
|
||||
this.$toast.open({
|
||||
message: 'Invalid Credentials',
|
||||
type: 'error'
|
||||
})
|
||||
} else {
|
||||
console.log(error)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
async beforeCreate () {
|
||||
const response = await axios.get('/api/is-registed')
|
||||
if (response.data.result === true) {
|
||||
this.$router.push({ name: 'home' })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user