├── server ├── echo ├── .cache │ └── .keep ├── src │ ├── api │ │ ├── FolderApi.js │ │ └── FileApi.js │ ├── test │ │ └── setup.js │ ├── config │ │ └── config.js │ ├── models │ │ ├── apiModel.js │ │ ├── user.js │ │ └── settings.js │ ├── middleware │ │ ├── check-auth.js │ │ └── checkFileAccess.js │ ├── routes │ │ ├── user.js │ │ └── apiRouter.js │ ├── lib │ │ ├── text-image.js │ │ └── download.js │ └── app.js ├── .eslintrc.js ├── nodemon.json ├── .gitignore ├── thirdParty │ ├── flash.svg │ ├── fireworks.svg │ ├── audition.svg │ ├── file.svg │ ├── dreamweaver.svg │ ├── illustrator.svg │ ├── indesign.svg │ ├── prelude.svg │ ├── effects.svg │ ├── premiere.svg │ ├── bridge.svg │ ├── ai.svg │ ├── tiff.svg │ ├── avi.svg │ ├── txt.svg │ ├── gif.svg │ ├── exe.svg │ ├── html.svg │ ├── zip.svg │ ├── python.svg │ ├── search.svg │ ├── ico.svg │ ├── xml.svg │ ├── fla.svg │ ├── log.svg │ ├── xls.svg │ ├── iso.svg │ ├── apk.svg │ ├── ps.svg │ ├── ppt.svg │ ├── csv.svg │ ├── pdf.svg │ ├── jpg.svg │ ├── eps.svg │ ├── svg.svg │ ├── cad.svg │ ├── sql.svg │ ├── mp4.svg │ ├── batch.svg │ ├── doc.svg │ ├── raw.svg │ ├── xlsx.svg │ ├── dwg.svg │ ├── css.svg │ ├── pptx.svg │ ├── pub.svg │ ├── mp3.svg │ ├── photoshop.svg │ ├── pps.svg │ ├── rar.svg │ ├── docx.svg │ └── bmp.svg └── package.json ├── src ├── views │ ├── Open.vue │ ├── PageNotFound.vue │ ├── Signup.vue │ ├── Home.vue │ ├── Auth.vue │ └── Test.vue ├── app │ ├── apps │ │ ├── VueDAPI │ │ │ ├── dapi.js │ │ │ ├── index.js │ │ │ └── DropboxAuthService.js │ │ ├── Google.js │ │ └── VueGAPI │ │ │ ├── gapi.js │ │ │ └── index.js │ ├── Config.js │ ├── User.js │ ├── Service.js │ ├── Event.js │ └── Auth.js ├── components │ ├── Account │ │ └── Account.vue │ ├── Browser │ │ ├── NavBar │ │ │ └── item │ │ │ │ └── Toolbar.vue │ │ ├── QuickUpload │ │ │ └── QuickUpload.vue │ │ └── InfoBar │ │ │ └── InfoBar.vue │ ├── Model │ │ ├── Model.vue │ │ ├── Preview │ │ │ └── item │ │ │ │ ├── FileText.vue │ │ │ │ ├── Video.vue │ │ │ │ ├── Audio.vue │ │ │ │ └── Image.vue │ │ ├── CreateFolder │ │ │ └── CreateNewFolderModel.vue │ │ ├── Rename │ │ │ └── RenameModel.vue │ │ └── ConfirmDelete │ │ │ └── ConfirmDeleteModel.vue │ └── Tool │ │ ├── Alert.vue │ │ └── OnlineState.vue ├── styles │ ├── components │ │ ├── _media-menu.scss │ │ ├── _media-toolbar.scss │ │ └── _media-tree.scss │ └── mediamanager.scss ├── assets │ ├── loding.gif │ └── profile.png ├── store │ ├── plugins │ │ └── persistedstate.js │ ├── store.js │ ├── getters.js │ ├── state.js │ └── mutation-types.js ├── App.vue ├── router.js ├── registerServiceWorker.js ├── routers │ └── routers.js └── main.js ├── PULL_REQUEST_TEMPLATE.md ├── _config.yml ├── public ├── robots.txt ├── favicon.ico ├── img │ └── icons │ │ ├── icon-96x96.png │ │ ├── icon-128x128.png │ │ ├── icon-144x144.png │ │ ├── icon-192x192.png │ │ ├── icon-384x384.png │ │ └── icon-512x512.png ├── manifest.json └── index.html ├── .browserslistrc ├── .env ├── tests ├── unit │ ├── .eslintrc.js │ ├── example.spec.js │ └── electron.spec.js └── e2e │ ├── .eslintrc.js │ ├── support │ ├── index.js │ └── commands.js │ ├── specs │ └── test.js │ └── plugins │ └── index.js ├── docs └── images │ ├── logo.png │ └── pre.gif ├── postcss.config.js ├── cypress.json ├── babel.config.js ├── greenkeeper.json ├── .travis.yml ├── .editorconfig ├── CONTRIBUTING.md ├── vue.config.js ├── .eslintrc.js ├── .gitignore ├── jest.config.js ├── .github └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── README.md └── package.json /server/echo: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/Open.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /server/.cache/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /server/src/api/FolderApi.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /server/src/test/setup.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/apps/VueDAPI/dapi.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/app/apps/VueDAPI/index.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /src/components/Account/Account.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/styles/components/_media-menu.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/apps/VueDAPI/DropboxAuthService.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/Browser/NavBar/item/Toolbar.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not ie <= 8 4 | -------------------------------------------------------------------------------- /server/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: 'airbnb-base', 3 | }; 4 | -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | VUE_APP_SECRET=C_MW5rCdAz36_3QCXFUECqwjl4qqFTKp113T8bHg 2 | VUE_APP_DEBUG=true 3 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyDrive/drive/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /tests/unit/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | jest: true 4 | } 5 | } -------------------------------------------------------------------------------- /docs/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyDrive/drive/HEAD/docs/images/logo.png -------------------------------------------------------------------------------- /docs/images/pre.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyDrive/drive/HEAD/docs/images/pre.gif -------------------------------------------------------------------------------- /src/assets/loding.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyDrive/drive/HEAD/src/assets/loding.gif -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/assets/profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyDrive/drive/HEAD/src/assets/profile.png -------------------------------------------------------------------------------- /cypress.json: -------------------------------------------------------------------------------- 1 | { 2 | "pluginsFile": "tests/e2e/plugins/index.js", 3 | "projectId": "krtcvb" 4 | } 5 | -------------------------------------------------------------------------------- /public/img/icons/icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyDrive/drive/HEAD/public/img/icons/icon-96x96.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app', 4 | '@babel/preset-env' 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /public/img/icons/icon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyDrive/drive/HEAD/public/img/icons/icon-128x128.png -------------------------------------------------------------------------------- /public/img/icons/icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyDrive/drive/HEAD/public/img/icons/icon-144x144.png -------------------------------------------------------------------------------- /public/img/icons/icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyDrive/drive/HEAD/public/img/icons/icon-192x192.png -------------------------------------------------------------------------------- /public/img/icons/icon-384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyDrive/drive/HEAD/public/img/icons/icon-384x384.png -------------------------------------------------------------------------------- /public/img/icons/icon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyDrive/drive/HEAD/public/img/icons/icon-512x512.png -------------------------------------------------------------------------------- /server/src/config/config.js: -------------------------------------------------------------------------------- 1 | class Config { 2 | 3 | constructor() { 4 | this.app = ''; 5 | } 6 | 7 | } 8 | 9 | module.exports = new Config(); 10 | -------------------------------------------------------------------------------- /greenkeeper.json: -------------------------------------------------------------------------------- 1 | { 2 | "groups": { 3 | "default": { 4 | "packages": [ 5 | "package.json", 6 | "server/package.json" 7 | ] 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/e2e/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | 'cypress' 4 | ], 5 | env: { 6 | mocha: true, 7 | 'cypress/globals': true 8 | }, 9 | rules: { 10 | strict: 'off' 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/styles/mediamanager.scss: -------------------------------------------------------------------------------- 1 | // Imports 2 | @import "variables"; 3 | 4 | // Components 5 | @import "components/media-player"; 6 | @import "components/media-browser"; 7 | @import "components/media-toolbar"; 8 | // @import "components/media-tree"; 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | dist: trusty 3 | language: node_js 4 | node_js: 5 | - '10' 6 | before_install: 7 | - if [[ `npm -v` != 5* ]]; then npm install --unsafe-perm --verbose -g npm@5; fi 8 | install: 9 | - npm install 10 | notifications: 11 | email: false 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [server/**.js] 13 | indent_style = space 14 | indent_size = 2 15 | -------------------------------------------------------------------------------- /server/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "MONGO_ATLAS_PW": "CTdYB4jqX6uovW7O", 4 | "JWT_KEY": "secret", 5 | "BASE_PATH": "./uploads", 6 | "NODE_ENV": "production", 7 | "PORT": "3344", 8 | "CSRFTOKEN": "C_MW5rCdAz36_3QCXFUECqwjl4qqFTKp113T8bHg" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing to this repository, please first discuss the change you wish to make via issue, 4 | email, or any other method with the owners of this repository before making a change. 5 | 6 | Please note we have a code of conduct, please follow it in all your interactions with the project. 7 | -------------------------------------------------------------------------------- /src/store/plugins/persistedstate.js: -------------------------------------------------------------------------------- 1 | // The options for persisting state 2 | export const persistedStateOptions = { 3 | key: 'mediamanager', 4 | paths: [ 5 | 'selectedDirectory', 6 | 'showInfoBar', 7 | 'view', 8 | 'token', 9 | 'isUserLoggedIn', 10 | 'settings', 11 | ], 12 | storage: window.sessionStorage, 13 | }; 14 | -------------------------------------------------------------------------------- /src/views/PageNotFound.vue: -------------------------------------------------------------------------------- 1 | 9 | 16 | 17 | -------------------------------------------------------------------------------- /src/views/Signup.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 18 | -------------------------------------------------------------------------------- /tests/unit/example.spec.js: -------------------------------------------------------------------------------- 1 | import { shallowMount } from '@vue/test-utils' 2 | import HelloWorld from '@/components/HelloWorld.vue' 3 | 4 | describe('HelloWorld.vue', () => { 5 | it('renders props.msg when passed', () => { 6 | const msg = 'new message' 7 | const wrapper = shallowMount(HelloWorld, { 8 | propsData: { msg } 9 | }) 10 | expect(wrapper.text()).toMatch(msg) 11 | }) 12 | }) 13 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | module.exports = { 3 | outputDir: path.resolve(__dirname, './server/src/app/'), 4 | pwa: { 5 | name: 'Media Manager', 6 | themeColor: '#9013FE', 7 | msTileColor: '#50E3C2' 8 | }, 9 | devServer: { 10 | proxy: "http://localhost:3344" 11 | }, 12 | pluginOptions: { 13 | electronBuilder: { 14 | outputDir: 'build' 15 | } 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /src/app/apps/Google.js: -------------------------------------------------------------------------------- 1 | import VueGAPI from './VueGAPI' 2 | 3 | function plugin (Vue, clientConfig) { 4 | Vue.use(VueGAPI, clientConfig) 5 | } 6 | 7 | // Install by default if using the script tag 8 | if (typeof window !== 'undefined' && window.Vue) { 9 | window.Vue.use(plugin) 10 | } 11 | 12 | export default plugin 13 | const version = '__VERSION__' 14 | // Export all components too 15 | export { 16 | version 17 | } 18 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | 'extends': [ 7 | 'plugin:vue/essential', 8 | 'eslint:recommended' 9 | ], 10 | rules: { 11 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 12 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' 13 | }, 14 | parserOptions: { 15 | parser: 'babel-eslint' 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | /build 5 | 6 | /tests/e2e/videos/ 7 | /tests/e2e/screenshots/ 8 | 9 | # local env files 10 | .env.local 11 | .env.*.local 12 | 13 | # Log files 14 | npm-debug.log* 15 | yarn-debug.log* 16 | yarn-error.log* 17 | 18 | # Editor directories and files 19 | .idea 20 | .vscode 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw* 26 | 27 | #Electron-builder output 28 | /dist_electron 29 | -------------------------------------------------------------------------------- /server/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | /.cache/* 5 | /uploads/* 6 | /public 7 | /src/app 8 | 9 | /tests/e2e/videos/ 10 | /tests/e2e/screenshots/ 11 | 12 | # local env files 13 | .env.local 14 | .env.*.local 15 | 16 | # Log files 17 | npm-debug.log* 18 | yarn-debug.log* 19 | yarn-error.log* 20 | 21 | # Editor directories and files 22 | .idea 23 | .vscode 24 | *.suo 25 | *.ntvs* 26 | *.njsproj 27 | *.sln 28 | *.sw* 29 | -------------------------------------------------------------------------------- /server/src/models/apiModel.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const Schemas = mongoose.Schema; 4 | 5 | // Create recents Schema & model 6 | 7 | const RecentSchema = new Schemas({ 8 | recentId: { 9 | type: String, 10 | required: [true, 'Recent filed is required.'], 11 | }, 12 | date: { 13 | type: Date, 14 | default: Date.now, 15 | }, 16 | }); 17 | 18 | const recents = mongoose.model('recents', RecentSchema); 19 | 20 | module.exports = recents; 21 | -------------------------------------------------------------------------------- /server/src/middleware/check-auth.js: -------------------------------------------------------------------------------- 1 | const jwt = require('jsonwebtoken'); 2 | const _ = require('underscore'); 3 | 4 | module.exports = (req, res, next) => { 5 | try { 6 | const token = req.headers.authorization.split(' ')[1]; 7 | const decoded = jwt.verify(token, process.env.JWT_KEY); 8 | req.userData = decoded; 9 | next(); 10 | } catch (error) { 11 | return res.status(401).json({ 12 | message: 'Auth failed', 13 | }); 14 | } 15 | return true; 16 | }; 17 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Lazy Drive", 3 | "short_name": "lazydrive", 4 | "icons": [ 5 | { 6 | "src": "./img/icons/icon-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "./img/icons/icon-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "start_url": "./index.html", 17 | "display": "standalone", 18 | "background_color": "#1889F6", 19 | "theme_color": "#4DBA87" 20 | } 21 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 19 | -------------------------------------------------------------------------------- /server/src/routes/user.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | 3 | const router = express.Router(); 4 | 5 | const UserController = require('../controllers/user'); 6 | const checkAuth = require('../middleware/check-auth'); 7 | 8 | router.post('/signup', UserController.user_signup); 9 | 10 | router.post('/login', UserController.user_login); 11 | 12 | router.post('/settings', checkAuth, UserController.user_settings); 13 | 14 | router.delete('/:userId', checkAuth, UserController.user_delete); 15 | 16 | module.exports = router; 17 | -------------------------------------------------------------------------------- /src/components/Model/Model.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 20 | -------------------------------------------------------------------------------- /server/src/api/FileApi.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Classes and Inheritance 4 | */ 5 | class Polygon { 6 | constructor(height, width) { 7 | this.name = 'Polygon'; 8 | this.height = height; 9 | this.width = width; 10 | } 11 | 12 | sayName() { 13 | console.log('Hi, I am a', this.name + '.'); 14 | } 15 | } 16 | 17 | class Square extends Polygon { 18 | constructor(length=10) { 19 | super(length, length); 20 | this.name = 'Square'; 21 | } 22 | 23 | get area() { 24 | return this.height * this.width; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/app/Config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * User . 3 | */ 4 | class Config { 5 | 6 | /** 7 | * User constructor 8 | */ 9 | constructor() { 10 | this.BASE_URL = 'http://172.16.187.238'; 11 | this.proxyPort = process.env.PORT ? process.env.PORT : 3344; 12 | this.redirectPort = process.env.NODE_ENV === 'production' ? process.env.PORT ? process.env.PORT : 3344 : 8080; 13 | this.settings = { 14 | dropbox: { 15 | 16 | }, 17 | google: { 18 | 19 | } 20 | } 21 | } 22 | } 23 | 24 | export let config = new Config(); 25 | -------------------------------------------------------------------------------- /src/app/User.js: -------------------------------------------------------------------------------- 1 | import * as jwt_decode from "jwt-decode"; 2 | import * as mediaManagerStorage from './Storage' 3 | 4 | /** 5 | * User . 6 | */ 7 | class User { 8 | 9 | /** 10 | * User constructor 11 | */ 12 | constructor() { 13 | this.token = mediaManagerStorage.cookies.get('token'); 14 | this.userData = this.getTokenData(); 15 | } 16 | 17 | getTokenData() { 18 | try { 19 | return jwt_decode(this.token); 20 | } catch (Error) { 21 | return null; 22 | } 23 | } 24 | } 25 | 26 | export let user = new User(); 27 | -------------------------------------------------------------------------------- /src/store/store.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import state from './state'; 4 | import * as getters from './getters'; 5 | import * as actions from './actions'; 6 | import mutations from './mutations'; 7 | import createPersistedState from 'vuex-persistedstate' 8 | import {persistedStateOptions} from "./plugins/persistedstate"; 9 | 10 | Vue.use(Vuex) 11 | 12 | export default new Vuex.Store({ 13 | state, 14 | getters, 15 | actions, 16 | mutations, 17 | plugins: [createPersistedState(persistedStateOptions)], 18 | strict: false 19 | }) 20 | -------------------------------------------------------------------------------- /src/app/Service.js: -------------------------------------------------------------------------------- 1 | import store from '@/store/store' 2 | import DropboxApi from './apps/Dropbox' 3 | import GoogleApi from './apps/Google' 4 | import { 5 | config 6 | } from './Config' 7 | 8 | /** 9 | * services 10 | */ 11 | class Services { 12 | 13 | /** 14 | * Store constructor 15 | */ 16 | constructor() { 17 | const dropboxAccessToken = store.state.settings.dropbox.accessToken; 18 | this.dropbox = new DropboxApi(dropboxAccessToken, config.redirectPort); 19 | this.google = GoogleApi; 20 | } 21 | 22 | } 23 | 24 | 25 | export let service = new Services(); 26 | -------------------------------------------------------------------------------- /src/app/Event.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | 3 | /** 4 | * Media Event bus. 5 | */ 6 | export default class Event { 7 | 8 | /** 9 | * Media Event constructor 10 | */ 11 | constructor() { 12 | this.vue = new Vue(); 13 | } 14 | 15 | /** 16 | * Fire an event 17 | * @param event 18 | * @param data 19 | */ 20 | fire(event, data = null) { 21 | this.vue.$emit(event, data); 22 | } 23 | 24 | /** 25 | * Listen to events 26 | * @param event 27 | * @param callback 28 | */ 29 | listen(event, callback) { 30 | this.vue.$on(event, callback); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleFileExtensions: [ 3 | 'js', 4 | 'jsx', 5 | 'json', 6 | 'vue' 7 | ], 8 | transform: { 9 | '^.+\\.vue$': 'vue-jest', 10 | '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub', 11 | '^.+\\.jsx?$': 'babel-jest' 12 | }, 13 | moduleNameMapper: { 14 | '^@/(.*)$': '/src/$1' 15 | }, 16 | snapshotSerializers: [ 17 | 'jest-serializer-vue' 18 | ], 19 | testMatch: [ 20 | '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' 21 | ], 22 | testURL: 'http://localhost/' 23 | } 24 | -------------------------------------------------------------------------------- /server/src/models/user.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const userSchema = mongoose.Schema({ 4 | name: { 5 | type: String, 6 | require: true, 7 | }, 8 | email: { 9 | type: String, 10 | required: true, 11 | unique: true, 12 | match: /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/, 13 | }, 14 | password: { 15 | type: String, 16 | required: true, 17 | }, 18 | date: { 19 | type: Date, 20 | default: Date.now, 21 | }, 22 | }); 23 | 24 | module.exports = mongoose.model('user', userSchema); 25 | -------------------------------------------------------------------------------- /server/src/models/settings.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const settings = mongoose.Schema({ 4 | uid: { 5 | type: String, 6 | require: true, 7 | }, 8 | email: { 9 | type: String, 10 | required: true, 11 | unique: true, 12 | match: /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/, 13 | }, 14 | settings: { 15 | type: Object, 16 | required: true, 17 | }, 18 | date: { 19 | type: Date, 20 | default: Date.now, 21 | }, 22 | }); 23 | 24 | module.exports = mongoose.model('settings', settings); 25 | -------------------------------------------------------------------------------- /src/app/apps/VueGAPI/gapi.js: -------------------------------------------------------------------------------- 1 | function loadGAPIScript (gapiUrl) { 2 | return new Promise(function (resolve) { 3 | var script = document.createElement('script') 4 | script.src = gapiUrl 5 | script.onreadystatechange = script.onload = function () { 6 | var interval = setInterval(function () { 7 | if (!script.readyState || /loaded|complete/.test(script.readyState)) { 8 | clearInterval(interval) 9 | resolve() 10 | } 11 | }, 100) 12 | } 13 | document.getElementsByTagName('head')[0].appendChild(script) 14 | }) 15 | } 16 | export const gapiPromise = loadGAPIScript('https://apis.google.com/js/api.js') 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /tests/e2e/support/index.js: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/index.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | // Import commands.js using ES2015 syntax: 17 | import './commands' 18 | 19 | // Alternatively you can use CommonJS syntax: 20 | // require('./commands') 21 | -------------------------------------------------------------------------------- /tests/e2e/specs/test.js: -------------------------------------------------------------------------------- 1 | // https://docs.cypress.io/api/introduction/api.html 2 | 3 | describe('Test Home Page', () => { 4 | it('Visits the app root url', () => { 5 | cy.visit('/') 6 | cy.contains('Media Manager') 7 | cy.get('.media-home') 8 | cy.get('.media-toolbar') 9 | cy.get('#media-navbar') 10 | cy.get('#media-content') 11 | cy.get('#media-tool') 12 | cy.get('#media-settings ') 13 | cy.get('#media-tool') 14 | cy.get('#media-rename') 15 | cy.get('#media-confirm-model ') 16 | cy.get('#media-create-folder') 17 | cy.get('#media-online') 18 | }) 19 | }) 20 | 21 | describe('Test About', () => { 22 | it('Visits the app about url', () => { 23 | cy.visit('#/about') 24 | cy.contains('This is an about page') 25 | }) 26 | }) 27 | -------------------------------------------------------------------------------- /src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 38 | -------------------------------------------------------------------------------- /src/app/Auth.js: -------------------------------------------------------------------------------- 1 | // import Api from '@/services/Api' 2 | import * as mediaManagerStorage from './Storage.js' 3 | 4 | export const services = { 5 | 6 | /** 7 | * Get the contents of a directory from the server 8 | * @returns {Promise} 9 | */ 10 | loggedIn() { 11 | if ((mediaManagerStorage.cookies.get('email') !== '' && mediaManagerStorage.cookies.get('email') !== null) && 12 | (mediaManagerStorage.cookies.get('token') !== '' && mediaManagerStorage.cookies.get('token') !== null)) { 13 | return true; 14 | } else { 15 | return false; 16 | } 17 | }, 18 | 19 | /** 20 | * Get the contents of a directory from the server 21 | * @returns {Promise} 22 | */ 23 | logout() { 24 | mediaManagerStorage.cookies.destroy('email'); 25 | mediaManagerStorage.cookies.destroy('token'); 26 | return true; 27 | }, 28 | } 29 | -------------------------------------------------------------------------------- /tests/unit/electron.spec.js: -------------------------------------------------------------------------------- 1 | const { testWithSpectron } = require('vue-cli-plugin-electron-builder') 2 | jest.setTimeout(50000) 3 | 4 | test('Window Loads Properly', async () => { 5 | // Wait for dev server to start 6 | const { app, stopServe } = await testWithSpectron() 7 | const win = app.browserWindow 8 | const client = app.client 9 | 10 | // Window was created 11 | expect(await client.getWindowCount()).toBe(1) 12 | // It is not minimized 13 | expect(await win.isMinimized()).toBe(false) 14 | // Window is visible 15 | expect(await win.isVisible()).toBe(true) 16 | // Size is correct 17 | const { width, height } = await win.getBounds() 18 | expect(width).toBeGreaterThan(0) 19 | expect(height).toBeGreaterThan(0) 20 | // App is loaded properly 21 | expect( 22 | /Welcome to Your Vue\.js (\+ TypeScript )?App/.test( 23 | await client.getHTML('#app') 24 | ) 25 | ).toBe(true) 26 | 27 | await stopServe() 28 | }) 29 | -------------------------------------------------------------------------------- /tests/e2e/support/commands.js: -------------------------------------------------------------------------------- 1 | // *********************************************** 2 | // This example commands.js shows you how to 3 | // create various custom commands and overwrite 4 | // existing commands. 5 | // 6 | // For more comprehensive examples of custom 7 | // commands please read more here: 8 | // https://on.cypress.io/custom-commands 9 | // *********************************************** 10 | // 11 | // 12 | // -- This is a parent command -- 13 | // Cypress.Commands.add("login", (email, password) => { ... }) 14 | // 15 | // 16 | // -- This is a child command -- 17 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) 18 | // 19 | // 20 | // -- This is a dual command -- 21 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) 22 | // 23 | // 24 | // -- This is will overwrite an existing command -- 25 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) 26 | -------------------------------------------------------------------------------- /src/router.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | import Routers from './routers/routers' 4 | import { 5 | api 6 | } from "./app/Api"; 7 | 8 | Vue.use(Router) 9 | 10 | const router = new Router({ 11 | mode: 'history', 12 | routes: Routers 13 | }) 14 | 15 | router.beforeEach((to, from, next) => { 16 | if (to.matched.some(record => record.meta.requiresAuth)) { 17 | const loggedIn = api.auth.loggedIn(); 18 | 19 | if (!loggedIn) { 20 | if (to.name != 'login' && to.name != 'signup') { 21 | next({ 22 | path: '/login', 23 | query: { 24 | redirect: to.fullPath 25 | } 26 | }) 27 | } else { 28 | next() 29 | } 30 | } else if (to.name == 'login' || to.name == 'signup') { 31 | next({ 32 | path: '/', 33 | }) 34 | } else { 35 | next() 36 | } 37 | } else { 38 | next() 39 | } 40 | }) 41 | 42 | export default router; 43 | -------------------------------------------------------------------------------- /tests/e2e/plugins/index.js: -------------------------------------------------------------------------------- 1 | // https://docs.cypress.io/guides/guides/plugins-guide.html 2 | 3 | // if you need a custom webpack configuration you can uncomment the following import 4 | // and then use the `file:preprocessor` event 5 | // as explained in the cypress docs 6 | // https://docs.cypress.io/api/plugins/preprocessors-api.html#Examples 7 | 8 | // /* eslint-disable import/no-extraneous-dependencies, global-require */ 9 | // const webpack = require('@cypress/webpack-preprocessor') 10 | 11 | module.exports = (on, config) => { 12 | // on('file:preprocessor', webpack({ 13 | // webpackOptions: require('@vue/cli-service/webpack.config'), 14 | // watchOptions: {} 15 | // })) 16 | 17 | return Object.assign({}, config, { 18 | fixturesFolder: 'tests/e2e/fixtures', 19 | integrationFolder: 'tests/e2e/specs', 20 | screenshotsFolder: 'tests/e2e/screenshots', 21 | videosFolder: 'tests/e2e/videos', 22 | supportFile: 'tests/e2e/support/index.js' 23 | }) 24 | } 25 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /src/registerServiceWorker.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | 3 | import { register } from 'register-service-worker' 4 | 5 | if (process.env.NODE_ENV === 'production') { 6 | register(`${process.env.BASE_URL}service-worker.js`, { 7 | ready () { 8 | console.log( 9 | 'App is being served from cache by a service worker.\n' + 10 | 'For more details, visit https://goo.gl/AFskqB' 11 | ) 12 | }, 13 | registered () { 14 | console.log('Service worker has been registered.') 15 | }, 16 | cached () { 17 | console.log('Content has been cached for offline use.') 18 | }, 19 | updatefound () { 20 | console.log('New content is downloading.') 21 | }, 22 | updated () { 23 | console.log('New content is available; please refresh.') 24 | }, 25 | offline () { 26 | console.log('No internet connection found. App is running in offline mode.') 27 | }, 28 | error (error) { 29 | console.error('Error during service worker registration:', error) 30 | } 31 | }) 32 | } 33 | -------------------------------------------------------------------------------- /server/src/middleware/checkFileAccess.js: -------------------------------------------------------------------------------- 1 | const jwt = require('jsonwebtoken'); 2 | const _ = require('underscore'); 3 | 4 | module.exports = (req, res, next) => { 5 | try { 6 | const cookies = {}; 7 | _(req.headers.cookie.split(';')) 8 | .chain() 9 | .map(m => m.replace(/^\s+/, '').replace(/\s+$/, '')) 10 | .each((c) => { 11 | const arr = c.split('='); 12 | const key = arr[0]; 13 | let value = null; 14 | const size = _.size(arr); 15 | if (size > 1) { 16 | value = arr.slice(1).join(''); 17 | } 18 | cookies[key] = value; 19 | }); 20 | 21 | const { 22 | token, 23 | } = cookies; 24 | const decoded = jwt.verify(token, process.env.JWT_KEY); 25 | req.userData = decoded; 26 | next(); 27 | } catch (error) { 28 | try { 29 | const token = req.headers.authorization.split(' ')[1]; 30 | const decoded = jwt.verify(token, process.env.JWT_KEY); 31 | req.userData = decoded; 32 | next(); 33 | } catch (err) { 34 | return res.status(401).json({ 35 | message: 'You are not authorized.', 36 | }); 37 | } 38 | } 39 | return true; 40 | }; 41 | -------------------------------------------------------------------------------- /server/thirdParty/flash.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /server/thirdParty/fireworks.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Lazy Drive 19 | 20 | 21 | 22 | 26 |
27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/components/Browser/QuickUpload/QuickUpload.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 53 | -------------------------------------------------------------------------------- /src/store/getters.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Get the currently selected directory 3 | * @param state 4 | * @returns {*} 5 | */ 6 | // export const getSelectedDirectory = (state) => { 7 | // return state.directories.find(directory => (directory.path === state.selectedDirectory)); 8 | // } 9 | 10 | /** 11 | * Get the sudirectories of the currently selected directory 12 | * @param state 13 | * @param getters 14 | * @returns {Array|directories|{/}|computed.directories|*|Object} 15 | */ 16 | // export const getSelectedDirectoryDirectories = (state) => { 17 | // return state.directories.filter( 18 | // directory => (directory.directory === state.selectedDirectory) 19 | // ); 20 | // } 21 | 22 | /** 23 | * Get the files of the currently selected directory 24 | * @param state 25 | * @param getters 26 | * @returns {Array|files|{}|FileList|*} 27 | */ 28 | // export const getSelectedDirectoryFiles = (state) => { 29 | // console.log(state) 30 | // state.contents.files.forEach(function(element) { 31 | // console.log(element); 32 | // }); 33 | // } 34 | 35 | /** 36 | * Whether or not all items of the current directory are selected 37 | * @param state 38 | * @param getters 39 | * @returns Array 40 | */ 41 | // export const getSelectedDirectoryContents = (state, getters) => { 42 | 43 | // return [ 44 | // ...getters.getSelectedDirectoryDirectories, 45 | // ...getters.getSelectedDirectoryFiles, 46 | // ]; 47 | // } 48 | -------------------------------------------------------------------------------- /server/thirdParty/audition.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 12 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/views/Auth.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 55 | -------------------------------------------------------------------------------- /src/components/Tool/Alert.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 57 | -------------------------------------------------------------------------------- /server/thirdParty/file.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/components/Model/Preview/item/FileText.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 49 | -------------------------------------------------------------------------------- /src/routers/routers.js: -------------------------------------------------------------------------------- 1 | // route level code-splitting 2 | // this generates a separate chunk (about.[hash].js) for this route 3 | // which is lazy-loaded when the route is visited. 4 | 5 | export default [{ 6 | path: '/', 7 | name: 'home', 8 | component: () => import('./../views/Home.vue') 9 | }, 10 | { 11 | path: '/drive/u/:adapter/:path/:dir?', 12 | name: 'my-drive', 13 | component: () => import('./../views/myDrive.vue'), 14 | meta: { 15 | requiresAuth: true 16 | } 17 | }, 18 | { 19 | path: '/login', 20 | name: 'login', 21 | component: () => import('./../views/Home.vue'), 22 | meta: { 23 | requiresAuth: true 24 | } 25 | }, 26 | { 27 | path: '/auth', 28 | name: 'auth', 29 | component: () => import('./../views/Auth.vue'), 30 | }, 31 | { 32 | path: '/signup', 33 | name: 'signup', 34 | component: () => import('./../views/Signup.vue'), 35 | meta: { 36 | requiresAuth: true 37 | } 38 | }, 39 | { 40 | path: '/test', 41 | name: 'test', 42 | component: () => import('./../views/Test.vue') 43 | }, 44 | { 45 | path: '/drive/open', 46 | name: 'open', 47 | component: () => import('./../views/Open.vue') 48 | }, 49 | { 50 | path: "/PageNotFound", 51 | name: 'NotFound', 52 | component: () => import('./../views/PageNotFound.vue'), 53 | }, 54 | { 55 | path: "*", 56 | name: 'PageNotFound', 57 | component: () => import('./../views/PageNotFound.vue'), 58 | } 59 | ] 60 | -------------------------------------------------------------------------------- /server/thirdParty/dreamweaver.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /server/thirdParty/illustrator.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/components/Tool/OnlineState.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 58 | -------------------------------------------------------------------------------- /src/views/Test.vue: -------------------------------------------------------------------------------- 1 | 23 | 56 | 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 |

6 | License 7 | Chat 8 | 9 | Greenkeeper badge 10 |

11 | 12 |

Lazy Drive

13 | 14 | > For sample you can use [**master**](https://github.com/lazyDrive/drive/tree/master) branch which is not perfect yet but better than this. 15 | 16 | Demo 17 | 18 | > **Note:** This loopback branch is under development because of addition of new UI, Loopback,Docker, Micro service and many more cool new features but, this was managed my small community :( LAMO Its me only :P 19 | 20 | **Lazy Drive** is an **opensource** project. Contributions are welcome 21 | 22 | **Road Map** 23 | 1. Add Auth system 24 | 2. Improve UI 25 | 3. Improve Server 26 | 4. Add redis 27 | 5. File Indexing 28 | 6. Zero Knowledge Encryption 29 | 7. Deploy 30 | 8. Make distributed server. 31 | 32 | - Fork the repo and star it :star: 33 | - Open issues :boom: 34 | - Raise PRs for issues :raised_hand: 35 | - Help on documentation :page_facing_up: 36 | 37 |

38 | 39 |

40 | 41 | 42 | Copyright (c) 2019, Lazy Drive [Lazy Drive](http://github.com/lazyDrive/) 43 | -------------------------------------------------------------------------------- /server/thirdParty/indesign.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /server/thirdParty/prelude.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /server/thirdParty/effects.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 12 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/components/Model/CreateFolder/CreateNewFolderModel.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 50 | 56 | -------------------------------------------------------------------------------- /src/components/Model/Preview/item/Video.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 63 | -------------------------------------------------------------------------------- /server/thirdParty/premiere.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 15 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/components/Model/Preview/item/Audio.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 65 | -------------------------------------------------------------------------------- /server/thirdParty/bridge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 15 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /server/thirdParty/ai.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/store/state.js: -------------------------------------------------------------------------------- 1 | // The initial state 2 | export default { 3 | // The loaded files 4 | contents: [], 5 | // Files loaded limit 6 | loadLimit: 30, 7 | // Settings 8 | settings: { 9 | dropbox: { 10 | 11 | }, 12 | google: { 13 | 14 | } 15 | }, 16 | // The currently selected items 17 | selectedItems: [], 18 | // The currently selected items 19 | uploadItems: [], 20 | // View 21 | view: 'grid', 22 | // The currently selected items 23 | uploadItemsMenu: [], 24 | // The currently selected items 25 | diskLoaded: [], 26 | // The currently selected dir 27 | selectedDirectory: 'my-drive', 28 | // The state of confirm delete model 29 | showConfirmDeleteModal: false, 30 | // The state of create folder model 31 | showCreateFolderModal: false, 32 | // The state of showUploadMenu 33 | showUploadMenu: false, 34 | // The state of preview model 35 | showPreviewModal: false, 36 | // The state of share model 37 | showShareModal: false, 38 | // The state of model 39 | showRenameModal: false, 40 | // The state of settings 41 | showSettings: false, 42 | // The state of file menu 43 | showMenu: { 44 | state: false, 45 | x: 0, 46 | y: 0 47 | }, 48 | // The state of x in settings 49 | showToolModal: false, 50 | // The state of the infobar 51 | showInfoBar: false, 52 | // The snackbar 53 | showsnackbar: { 54 | state: false, 55 | data: '', 56 | color: 'default', 57 | time: 6000 58 | }, 59 | // The snackbar 60 | previewItem: null, 61 | // The backdrop 62 | modelBackdrop: false, 63 | // The loading state 64 | isLoading: false, 65 | // The loading state 66 | isUploading: false, 67 | // Is mobile 68 | isMobile: false, 69 | // Token 70 | token: '', 71 | // Select all files 72 | selectAllFile: false, 73 | // Select all files 74 | selectAll: false, 75 | // Select all folders 76 | selectAllFolder: false, 77 | // Islogged in 78 | isUserLoggedIn: false, 79 | // The Search Query 80 | search: '', 81 | } 82 | -------------------------------------------------------------------------------- /server/thirdParty/tiff.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/components/Model/Preview/item/Image.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 75 | -------------------------------------------------------------------------------- /server/src/lib/text-image.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | /** 4 | * Decode base64 string to buffer. 5 | * 6 | * @param {String} base64Str string 7 | * @return {Object} Image object with image type and data buffer. 8 | * @public 9 | */ 10 | function decodeBase64Image(base64Str) { 11 | const matches = base64Str.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/); 12 | const image = {}; 13 | if (!matches || matches.length !== 3) { 14 | throw new Error('Invalid base64 string'); 15 | } 16 | 17 | // eslint-disable-next-line prefer-destructuring 18 | image.type = matches[1]; 19 | // eslint-disable-next-line no-buffer-constructor 20 | image.data = new Buffer(matches[2], 'base64'); 21 | 22 | return image; 23 | } 24 | 25 | 26 | /** 27 | * Change base64Str to image and write image file with 28 | the specified file name to the specified file path. 29 | * @param {String} base64 string (mandatory) 30 | * @param {String} file path e.g. /opt/temp/uploads/ (mandatory) 31 | * @return {Object} optionsObj holds image type, image filename, debug e.g.{'fileName':fileName, 'type':type,'debug':true} (optional) 32 | * @public 33 | */ 34 | function base64ToImage(base64Str, path, optionalObj) { 35 | if (!base64Str || !path) { 36 | throw new Error('Missing mandatory arguments base64 string and/or path string'); 37 | } 38 | 39 | const optionalObj = optionalObj || {}; 40 | const imageBuffer = decodeBase64Image(base64Str); 41 | let imageType = optionalObj.type || imageBuffer.type || 'png'; 42 | let fileName = optionalObj.fileName || `img-${Date.now()}`; 43 | fileName = `${fileName}`; 44 | 45 | if (fileName.indexOf('.') === -1) { 46 | imageType = imageType.replace('image/', ''); 47 | fileName = `${fileName}.${imageType}`; 48 | } 49 | 50 | const abs = path + fileName; 51 | fs.writeFile(abs, imageBuffer.data, 'base64', (err) => { 52 | if (err && optionalObj.debug) { 53 | console.log('File image write error', err); 54 | } 55 | }); 56 | return { 57 | imageType, 58 | fileName, 59 | }; 60 | } 61 | 62 | /** 63 | * Module exports. 64 | * @public 65 | */ 66 | module.exports = base64ToImage; 67 | -------------------------------------------------------------------------------- /server/thirdParty/avi.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /server/thirdParty/txt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/components/Model/Rename/RenameModel.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 69 | 75 | -------------------------------------------------------------------------------- /server/thirdParty/gif.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/components/Browser/InfoBar/InfoBar.vue: -------------------------------------------------------------------------------- 1 | 33 | 34 | 74 | -------------------------------------------------------------------------------- /server/thirdParty/exe.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /server/thirdParty/html.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /server/thirdParty/zip.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/components/Model/ConfirmDelete/ConfirmDeleteModel.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 70 | 71 | 77 | -------------------------------------------------------------------------------- /server/thirdParty/python.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /server/thirdParty/search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | 12 | 14 | 15 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lazy-drive", 3 | "version": "0.1.0", 4 | "private": true, 5 | "description": "

\"Vue

", 6 | "author": "Anurag Kumar (anu1601cs)", 7 | "scripts": { 8 | "serve": "vue-cli-service serve", 9 | "build": "vue-cli-service build", 10 | "lint": "vue-cli-service lint", 11 | "test:e2e": "vue-cli-service test:e2e", 12 | "test:unit": "vue-cli-service test:unit" 13 | }, 14 | "dependencies": { 15 | "axios": "^0.19.0", 16 | "babel-polyfill": "^6.26.0", 17 | "debug": "^4.1.1", 18 | "dropbox": "^4.0.16", 19 | "file-saver": "^2.0.1", 20 | "isomorphic-fetch": "^2.2.1", 21 | "jwt-decode": "^2.2.0", 22 | "lodash": "^4.17.11", 23 | "material-design-icons-iconfont": "^5.0.1", 24 | "register-service-worker": "^1.6.2", 25 | "underscore": "^1.9.1", 26 | "vue": "^2.6.8", 27 | "vue-analytics": "^5.16.2", 28 | "vue-pdf": "^4.0.6", 29 | "vue-router": "^3.0.1", 30 | "vuetify": "1.5.14", 31 | "vuex": "^3.1.0", 32 | "vuex-persistedstate": "^2.5.4" 33 | }, 34 | "devDependencies": { 35 | "@babel/preset-env": "^7.3.4", 36 | "@vue/cli-plugin-babel": "^3.4.1", 37 | "@vue/cli-plugin-e2e-cypress": "^3.4.1", 38 | "@vue/cli-plugin-eslint": "^3.4.1", 39 | "@vue/cli-plugin-pwa": "^3.4.1", 40 | "@vue/cli-plugin-unit-jest": "^3.4.1", 41 | "@vue/cli-service": "^3.4.1", 42 | "@vue/test-utils": "^1.0.0-beta.29", 43 | "babel-core": "7.0.0-bridge.0", 44 | "babel-eslint": "^10.0.1", 45 | "babel-jest": "^24.1.0", 46 | "cypress": "^3.1.5", 47 | "eslint": "^5.14.1", 48 | "eslint-plugin-vue": "^5.2.2", 49 | "less": "^3.0.4", 50 | "less-loader": "^5.0.0", 51 | "node-sass": "^4.12.0", 52 | "sass-loader": "^7.1.0", 53 | "vue-cli-plugin-vuetify": "^0.5.0", 54 | "vue-template-compiler": "^2.6.8" 55 | }, 56 | "bugs": { 57 | "url": "https://github.com/lazyDrive/drive/issues" 58 | }, 59 | "homepage": "https://github.com/lazyDrive/drive", 60 | "keywords": [ 61 | "Media", 62 | "Manager" 63 | ], 64 | "license": "ISC", 65 | "main": "background.js", 66 | "repository": { 67 | "type": "git", 68 | "url": "git+https://github.com/lazyDrive/drive.git" 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /server/thirdParty/ico.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /server/thirdParty/xml.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/app/apps/VueGAPI/index.js: -------------------------------------------------------------------------------- 1 | import { gapiPromise } from './gapi' 2 | import GoogleAuthService from './GoogleAuthService' 3 | 4 | const googleAuthService = new GoogleAuthService() 5 | const { login, logout, isAuthenticated, getUserData, refreshToken, isSignedIn } = googleAuthService 6 | 7 | export default { 8 | install: function (Vue, clientConfig) { 9 | Vue.gapiLoadClientPromise = null 10 | 11 | const resolveAuth2Client = (resolve) => { 12 | // eslint-disable-next-line 13 | gapiPromise.then(_ => { 14 | const gapi = window.gapi 15 | if (!gapi) { 16 | console.error('Failed to load gapi!') 17 | return 18 | } 19 | if (!gapi.auth) { 20 | gapi.load('client:auth2', () => { 21 | Vue.gapiLoadClientPromise = gapi.client 22 | .init(clientConfig) 23 | .then(() => { 24 | console.info('gapi client initialised.') 25 | googleAuthService.authInstance = gapi.auth2.getAuthInstance() 26 | resolve(gapi) 27 | }) 28 | .catch(err => { 29 | if (err.error) { 30 | const error = err.error 31 | console.error( 32 | 'Failed to initialize gapi: %s (status=%s, code=%s)', error.message, error.status, error.code, err) 33 | } 34 | }) 35 | }) 36 | } else { 37 | resolve(gapi) 38 | } 39 | }) 40 | } 41 | 42 | Vue.prototype.$getGapiClient = () => { 43 | return new Promise((resolve, reject) => { 44 | if ( 45 | Vue.gapiLoadClientPromise && 46 | Vue.gapiLoadClientPromise.status === 0 47 | ) { 48 | // promise is being executed 49 | resolve(Vue.gapiLoadClientPromise) 50 | } else { 51 | resolveAuth2Client(resolve, reject) 52 | } 53 | }) 54 | } 55 | 56 | Vue.prototype.$login = () => { 57 | return Vue.prototype.$getGapiClient().then(login) 58 | } 59 | 60 | Vue.prototype.$refreshToken = () => { 61 | return Vue.prototype.$getGapiClient().then(refreshToken) 62 | } 63 | 64 | Vue.prototype.$logout = () => { 65 | return Vue.prototype.$getGapiClient().then(logout) 66 | } 67 | 68 | Vue.prototype.$isAuthenticated = isAuthenticated 69 | 70 | Vue.prototype.$isSignedIn = isSignedIn 71 | 72 | Vue.prototype.$getUserData = getUserData 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /server/thirdParty/fla.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 16 | 17 | 18 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /server/thirdParty/log.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /server/thirdParty/xls.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/styles/components/_media-toolbar.scss: -------------------------------------------------------------------------------- 1 | .media-toolbar { 2 | position: relative; 3 | display: flex; 4 | padding: 0; 5 | background-color: $toolbar-bg; 6 | border-bottom: 1px solid $border-color; 7 | border-radius: $border-radius $border-radius 0 0; 8 | 9 | input { 10 | padding: .375rem .75rem; 11 | color: #495057; 12 | border: 1px solid #ced4da; 13 | } 14 | } 15 | 16 | .media-toolbar-icon { 17 | display: inline-block; 18 | width: $toolbar-icon-width; 19 | font-size: 1.3rem; 20 | line-height: $toolbar-height; 21 | color: #464a4c; 22 | text-align: center; 23 | border-left: 1px solid $border-color; 24 | box-shadow: 1px 0 #fefefe inset; 25 | 26 | &:hover { 27 | background-color: $toolbar-icon-bg-hover; 28 | box-shadow: none; 29 | } 30 | } 31 | 32 | .media-view-icons { 33 | display: flex; 34 | } 35 | 36 | .media-view-icons { 37 | .disabled { 38 | span { 39 | opacity: .3; 40 | } 41 | 42 | &:hover, 43 | span:hover { 44 | cursor: default; 45 | } 46 | } 47 | } 48 | 49 | .media-view-search-input { 50 | display: flex; 51 | align-items: center; 52 | padding: 0 10px; 53 | } 54 | 55 | .media-loader { 56 | position: absolute; 57 | right: 100%; 58 | bottom: 0; 59 | left: 0; 60 | height: $toolbar-loader-height; 61 | background-image: $toolbar-loader-color; 62 | animation: 20s ease 0s normal none 1 running mediaLoader; 63 | animation-fill-mode: forwards; 64 | } 65 | 66 | @keyframes mediaLoader { 67 | from { 68 | right: 100%; 69 | } 70 | 71 | to { 72 | right: 0; 73 | } 74 | } 75 | 76 | .m-over-toolbar { 77 | border-bottom: 1px solid #ced4da !important; 78 | } 79 | 80 | .uploading{ 81 | animation: changeColor 1s infinite; 82 | } 83 | 84 | 85 | @keyframes changeColor { 86 | from { 87 | box-shadow: 0 0 20px 3px #4DD0E1; 88 | } 89 | 90 | to { 91 | box-shadow: 0 0 5px 3px #4DD0E1; 92 | } 93 | } 94 | 95 | .sync{ 96 | animation: syncColor 1.5s infinite ease-in-out; 97 | } 98 | 99 | @keyframes syncColor { 100 | from { 101 | box-shadow: 0 0 10px 3px rgb(77, 225, 126); 102 | } 103 | 104 | to { 105 | box-shadow: 0 0 0px 3px rgb(77, 225, 126); 106 | } 107 | } 108 | 109 | .loading{ 110 | animation: loading 1.5s infinite ease-in-out; 111 | } 112 | 113 | @keyframes loading { 114 | from { 115 | box-shadow: 0 0 10px 3px #4DD0E1; 116 | } 117 | 118 | to { 119 | box-shadow: 0 0 0px 3px #4DD0E1; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /server/src/app.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const bodyParser = require('body-parser'); 3 | const cors = require('cors'); 4 | const morgan = require('morgan'); 5 | const mongoose = require('mongoose'); 6 | const ora = require('ora'); 7 | const compression = require('compression'); 8 | const history = require('connect-history-api-fallback'); 9 | 10 | // import routes 11 | const apiRouter = require('./routes/apiRouter'); 12 | const userRoutes = require('./routes/user'); 13 | 14 | // Start spinner 15 | const spinner = ora('Starting server.').start(); 16 | 17 | // get express app instance 18 | const app = express(); 19 | 20 | // Connect to mongodb 21 | mongoose.connect('mongodb://localhost/ninjago', { 22 | useCreateIndex: true, 23 | useNewUrlParser: true, 24 | }); 25 | mongoose.Promise = global.Promise; 26 | 27 | if (process.env.NODE_ENV === 'production') { 28 | app.use(history({ 29 | rewrites: [{ 30 | from: /^\/api\/.*$/, 31 | to(context) { 32 | return context.parsedUrl.path; 33 | }, 34 | }], 35 | })); 36 | } 37 | app.use(cors()); 38 | app.use(morgan('dev')); 39 | app.use(compression()); 40 | app.use(bodyParser.json({ 41 | limit: '500mb', 42 | })); 43 | app.use(bodyParser.urlencoded({ 44 | limit: '500mb', 45 | extended: true, 46 | })); 47 | 48 | app.use((req, res, next) => { 49 | res.header('Access-Control-Allow-Origin', '*'); 50 | res.header( 51 | 'Access-Control-Allow-Headers', 52 | 'Origin, X-Requested-With, Content-Type, Accept, Authorization', 53 | ); 54 | if (req.method === 'OPTIONS') { 55 | res.header('Access-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE, GET'); 56 | return res.status(200).json({}); 57 | } 58 | 59 | next(); 60 | }); 61 | 62 | // Add routes 63 | app.use('/api', apiRouter); 64 | app.use('/user', userRoutes); 65 | 66 | // Production 67 | if (process.env.NODE_ENV === 'production') { 68 | app.use(express.static(`${__dirname}/app/`)); 69 | app.get(/.*/, (req, res) => res.sendFile(`${__dirname}/app/index.html`)); 70 | } 71 | 72 | app.use((req, res, next) => { 73 | const error = new Error('Not found'); 74 | error.status = 404; 75 | next(error); 76 | }); 77 | 78 | app.use((error, req, res, next) => { 79 | res.status(error.status || 500); 80 | res.json({ 81 | error: { 82 | message: error.message, 83 | }, 84 | }); 85 | next(); 86 | }); 87 | 88 | const port = process.env.PORT || 3344; 89 | 90 | app.listen(port, () => { 91 | spinner.text = `Server running on localhost:${port}`; 92 | spinner.color = 'green'; 93 | spinner.succeed(); 94 | }); 95 | -------------------------------------------------------------------------------- /server/thirdParty/iso.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /server/thirdParty/apk.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import Event from './app/Event' 4 | import Vuetify from 'vuetify' 5 | import router from './router' 6 | import store from './store/store' 7 | import './registerServiceWorker' 8 | import VueAnalytics from 'vue-analytics' 9 | import Browser from '@/components/Browser/Browser' 10 | import File from '@/components/Browser/Items/File' 11 | import InfoBar from '@/components/Browser/InfoBar/InfoBar' 12 | import Folder from '@/components/Browser/Items/Folder' 13 | import Navbar from '@/components/Browser/NavBar/NavBar' 14 | import QuickUpload from '@/components/Browser/QuickUpload/QuickUpload' 15 | import Settings from '@/components/Browser/Settings/Settings' 16 | import UploadMenu from '@/components/Model/UploadMenu/UploadMenu' 17 | import Model from '@/components/Model/Model' 18 | import RenameModel from '@/components/Model/Rename/RenameModel' 19 | import PreviewModel from '@/components/Model/Preview/PreviewModel' 20 | import ConfirmDeleteModel from '@/components/Model/ConfirmDelete/ConfirmDeleteModel' 21 | import CreateNewFolderModel from '@/components/Model/CreateFolder/CreateNewFolderModel' 22 | import Menu from '@/components/Menu/Menu' 23 | import OnlineState from '@/components/Tool/OnlineState' 24 | import Alert from '@/components/Tool/Alert' 25 | 26 | import 'vuetify/dist/vuetify.min.css' 27 | import './styles/mediamanager.scss' 28 | 29 | Vue.use(Vuetify) 30 | Vue.use(VueAnalytics, { 31 | id: 'UA-131081167-1', 32 | router 33 | }) 34 | 35 | // Load components 36 | Vue.component('media-alert', Alert) 37 | Vue.component('media-file', File) 38 | Vue.component('media-folder', Folder) 39 | Vue.component('media-online-state', OnlineState) 40 | Vue.component('media-nav-bar', Navbar) 41 | Vue.component('media-infrobar', InfoBar) 42 | Vue.component('media-quick-upload', QuickUpload) 43 | Vue.component('media-confirm-delete-model', ConfirmDeleteModel) 44 | Vue.component('media-create-folder-model', CreateNewFolderModel) 45 | Vue.component('media-rename-model', RenameModel) 46 | Vue.component('media-settings', Settings) 47 | Vue.component('media-browser', Browser) 48 | Vue.component('media-model', Model) 49 | Vue.component('media-menu', Menu) 50 | Vue.component('media-upload-menu', UploadMenu) 51 | Vue.component('media-preview-model', PreviewModel) 52 | 53 | // Register MediaManager namespace 54 | window.LazyDrive = window.LazyDrive || {}; 55 | // Register the media manager event bus 56 | window.LazyDrive.Event = new Event(); 57 | 58 | Vue.config.productionTip = false 59 | 60 | new Vue({ 61 | router, 62 | store, 63 | render: h => h(App) 64 | }).$mount('#app') 65 | -------------------------------------------------------------------------------- /server/thirdParty/ps.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "description": "Media manager server", 5 | "main": "app.js", 6 | "scripts": { 7 | "start": "./node_modules/nodemon/bin/nodemon.js src/app.js --exec 'node'", 8 | "drive": "./node_modules/nodemon/bin/nodemon.js src/app.js --exec 'node'", 9 | "lint": "./node_modules/.bin/eslint src/**/*.js" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+ssh://git@github.com/anu1601cs/media-manager.git" 14 | }, 15 | "author": "Anurag Kumar (anu1601cs)", 16 | "license": "ISC", 17 | "bugs": { 18 | "url": "https://github.com/anu1601cs/media-manager/issues" 19 | }, 20 | "homepage": "https://github.com/anu1601cs/media-manager#readme", 21 | "dependencies": { 22 | "archiver": "^3.0.0", 23 | "async": "^3.0.1", 24 | "axios": "^0.19.0", 25 | "bcrypt": "^3.0.6", 26 | "body-parser": "^1.18.3", 27 | "compression": "^1.7.3", 28 | "connect-history-api-fallback": "^1.6.0", 29 | "cors": "^2.8.5", 30 | "crypto": "^1.0.1", 31 | "dropbox": "^4.0.15", 32 | "eslint-config-airbnb": "^17.1.0", 33 | "express": "^4.16.4", 34 | "express-mailer": "^0.3.1", 35 | "express-messages": "^1.0.1", 36 | "express-session": "^1.15.6", 37 | "express-validator": "^5.3.1", 38 | "file-type": "^12.0.0", 39 | "fluent-ffmpeg": "^2.1.2", 40 | "fs-extra": "^8.0.1", 41 | "got": "^9.6.0", 42 | "image-size": "^0.7.1", 43 | "imagemin": "^6.1.0", 44 | "imagemin-gifsicle": "^6.0.1", 45 | "imagemin-jpegoptim": "^6.0.0", 46 | "imagemin-jpegtran": "^6.0.0", 47 | "imagemin-mozjpeg": "^8.0.0", 48 | "imagemin-pngquant": "^8.0.0", 49 | "imagemin-webp": "^5.0.0", 50 | "jpegoptim-bin": "^5.1.0", 51 | "jsonwebtoken": "^8.4.0", 52 | "lodash": "^4.17.11", 53 | "lodash.get": "^4.4.2", 54 | "mime-types": "^2.1.21", 55 | "mongodb": "^3.1.13", 56 | "mongojs": "^2.6.0", 57 | "mongoose": "^5.4.7", 58 | "morgan": "^1.9.1", 59 | "multer": "^1.4.1", 60 | "node-stream-zip": "^1.7.0", 61 | "nodemon": "^1.18.9", 62 | "npm": "^6.7.0", 63 | "ora": "^3.0.0", 64 | "passport": "^0.4.0", 65 | "passport-google": "^0.3.0", 66 | "passport-http": "^0.3.0", 67 | "path": "^0.12.7", 68 | "pdf-image": "^2.0.0", 69 | "querystring": "^0.2.0", 70 | "read-chunk": "^3.0.0", 71 | "send": "^0.17.1", 72 | "underscore": "^1.9.1", 73 | "util": "^0.12.0" 74 | }, 75 | "devDependencies": { 76 | "eslint": "^5.12.1", 77 | "eslint-config-airbnb-base": "^13.1.0", 78 | "eslint-plugin-import": "^2.15.0" 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /server/thirdParty/ppt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /server/thirdParty/csv.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /server/thirdParty/pdf.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /server/thirdParty/jpg.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /server/thirdParty/eps.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /server/thirdParty/svg.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /server/thirdParty/cad.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /server/thirdParty/sql.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /server/thirdParty/mp4.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /server/thirdParty/batch.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 11 | 13 | 15 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /server/thirdParty/doc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /server/thirdParty/raw.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /server/thirdParty/xlsx.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/store/mutation-types.js: -------------------------------------------------------------------------------- 1 | // Loading state 2 | export const SET_IS_LOADING = 'SET_IS_LOADING'; 3 | 4 | export const SET_IS_UPLOADING = 'SET_IS_UPLOADING'; 5 | 6 | export const SET_IS_LOADING_MORE = 'SET_IS_LOADING_MORE'; 7 | 8 | // Selecting media items 9 | export const SELECT_DIRECTORY = 'SELECT_DIRECTORY'; 10 | export const SELECT_BROWSER_ITEM = 'SELECT_BROWSER_ITEM'; 11 | export const SELECT_BROWSER_ITEMS = 'SELECT_BROWSER_ITEMS'; 12 | export const UNSELECT_BROWSER_ITEM = 'UNSELECT_BROWSER_ITEM'; 13 | export const UNSELECT_ALL_BROWSER_ITEMS = 'UNSELECT_ALL_BROWSER_ITEMS'; 14 | 15 | // In/Decrease grid item size 16 | export const INCREASE_GRID_SIZE = 'INCREASE_GRID_SIZE'; 17 | export const DECREASE_GRID_SIZE = 'DECREASE_GRID_SIZE'; 18 | 19 | // Api handlers 20 | export const LOAD_CONTENTS_SUCCESS = 'LOAD_CONTENTS_SUCCESS'; 21 | export const LOAD_MORE_CONTENTS_SUCCESS = 'LOAD_MORE_CONTENTS_SUCCESS'; 22 | export const LOAD_FULL_CONTENTS_SUCCESS = 'LOAD_FULL_CONTENTS_SUCCESS'; 23 | export const CREATE_DIRECTORY_SUCCESS = 'CREATE_DIRECTORY_SUCCESS'; 24 | export const UPLOAD_SUCCESS = 'UPLOAD_SUCCESS'; 25 | 26 | // Create folder modal 27 | export const SHOW_CREATE_FOLDER_MODAL = 'SHOW_CREATE_FOLDER_MODAL'; 28 | export const HIDE_CREATE_FOLDER_MODAL = 'HIDE_CREATE_FOLDER_MODAL'; 29 | 30 | // Confirm Delete Modal 31 | export const SHOW_CONFIRM_DELETE_MODAL = 'SHOW_CONFIRM_DELETE_MODAL'; 32 | export const HIDE_CONFIRM_DELETE_MODAL = 'HIDE_CONFIRM_DELETE_MODAL'; 33 | 34 | // Confirm Folder Menu 35 | export const SHOW_MENU = 'SHOW_MENU'; 36 | export const HIDE_MENU = 'HIDE_MENU'; 37 | // Tool Modal 38 | export const SHOW_TOOL_MODAL = 'SHOW_TOOL_MODAL'; 39 | export const HIDE_TOOL_MODAL = 'HIDE_TOOL_MODAL'; 40 | 41 | // Infobar 42 | export const SHOW_INFOBAR = 'SHOW_INFOBAR'; 43 | export const HIDE_INFOBAR = 'HIDE_INFOBAR'; 44 | 45 | // Infobar 46 | export const SHOW_SNACKBAR = 'SHOW_SNACKBAR'; 47 | export const HIDE_SNACKBAR = 'HIDE_SNACKBAR'; 48 | 49 | // Settings 50 | export const SHOW_SETTINGS = 'SHOW_SETTINGS'; 51 | export const HIDE_SETTINGS = 'HIDE_SETTINGS'; 52 | 53 | // Delete items 54 | export const DELETE_SUCCESS = 'DELETE_SUCCESS'; 55 | 56 | // Set settings 57 | export const SET_SETTINGS = 'SET_SETTINGS'; 58 | 59 | // Is mobile 60 | export const IS_MOBILE = 'IS_MOBILE'; 61 | 62 | // List view 63 | export const CHANGE_VIEW = 'CHANGE_VIEW'; 64 | 65 | // Preview modal 66 | export const SHOW_PREVIEW_MODAL = 'SHOW_PREVIEW_MODAL'; 67 | export const HIDE_PREVIEW_MODAL = 'HIDE_PREVIEW_MODAL'; 68 | 69 | // Rename modal 70 | export const SHOW_RENAME_MODAL = 'SHOW_RENAME_MODAL'; 71 | export const HIDE_RENAME_MODAL = 'HIDE_RENAME_MODAL'; 72 | export const RENAME_SUCCESS = 'RENAME_SUCCESS'; 73 | 74 | // Share model 75 | export const SHOW_SHARE_MODAL = 'SHOW_SHARE_MODAL'; 76 | export const HIDE_SHARE_MODAL = 'HIDE_SHARE_MODAL'; 77 | // Search Query 78 | export const SET_SEARCH_QUERY = 'SET_SEARCH_QUERY'; 79 | -------------------------------------------------------------------------------- /server/thirdParty/dwg.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/styles/components/_media-tree.scss: -------------------------------------------------------------------------------- 1 | /* Media Tree */ 2 | 3 | ul.media-tree { 4 | padding: 0 0 5px; 5 | margin: 0; 6 | overflow-x: visible; 7 | list-style: none; 8 | ul { 9 | margin-left: 2px; 10 | } 11 | &:empty { 12 | display: none; 13 | } 14 | } 15 | 16 | .media-disk { 17 | margin-bottom: 10px; 18 | } 19 | 20 | .media-drive { 21 | overflow-x: auto; 22 | background-color: $sidebar-drive-bg; 23 | border: 1px solid $border-color; 24 | + .media-drive { 25 | border-top: 0; 26 | } 27 | > ul > li { 28 | padding-left: 25px; 29 | } 30 | } 31 | 32 | .media-drive-name { 33 | padding: 4px 10px; 34 | &::before { 35 | margin-right: 6px; 36 | font-family: FontAwesome; 37 | color: $sidebar-tree-icon-color; 38 | content: $sidebar-tree-folder-icon; 39 | } 40 | &:hover { 41 | cursor: pointer; 42 | } 43 | } 44 | 45 | .media-disk-name { 46 | padding: 4px 1px; 47 | font-size: .8em; 48 | color: #aaa; 49 | text-transform: uppercase; 50 | letter-spacing: 1px; 51 | &:empty { 52 | display: none; 53 | } 54 | } 55 | 56 | .media-tree-item { 57 | position: relative; 58 | display: block; 59 | &::before { 60 | position: absolute; 61 | top: ($sidebar-tree-line-height / 2); 62 | left: 15px; 63 | width: 10px; 64 | height: 1px; 65 | margin: auto; 66 | content: ""; 67 | background-color: $sidebar-tree-line-color; 68 | } 69 | &::after { 70 | position: absolute; 71 | top: 0; 72 | bottom: 0; 73 | left: 15px; 74 | width: 1px; 75 | height: 100%; 76 | content: ""; 77 | background-color: $sidebar-tree-line-color; 78 | } 79 | &:last-child { 80 | &::after { 81 | height: ($sidebar-tree-line-height / 2); 82 | } 83 | } 84 | li { 85 | padding-left: 25px; 86 | &::before, &::after { 87 | left: 13px; 88 | } 89 | } 90 | } 91 | 92 | .media-tree-item a { 93 | display: block; 94 | padding: 0 7px; 95 | line-height: $sidebar-tree-line-height; 96 | text-decoration: none; 97 | white-space: nowrap; 98 | cursor: pointer; 99 | } 100 | 101 | .media-tree-item.active > a { 102 | &:hover { 103 | text-decoration: none; 104 | background-color: $sidebar-tree-item-hover-bg; 105 | } 106 | } 107 | 108 | .media-tree-item .item-icon { 109 | display: inline-block; 110 | padding-right: 2px; 111 | font-size: 15px; 112 | line-height: normal; 113 | color: $sidebar-tree-icon-color; 114 | vertical-align: middle; 115 | } 116 | 117 | .media-tree-item.active > a .item-icon { 118 | color: $sidebar-active-icon-color; 119 | } 120 | 121 | .item-name { 122 | display: inline-block; 123 | overflow: hidden; 124 | font-size: .9em; 125 | text-overflow: ellipsis; 126 | white-space: nowrap; 127 | vertical-align: middle; 128 | } 129 | 130 | .media-tree-item.active > a .item-name { 131 | font-weight: bold; 132 | } 133 | -------------------------------------------------------------------------------- /server/thirdParty/css.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /server/thirdParty/pptx.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /server/thirdParty/pub.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /server/thirdParty/mp3.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /server/src/routes/apiRouter.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | 3 | const router = express.Router(); 4 | 5 | const multer = require('multer'); 6 | 7 | const fs = require('fs-extra'); 8 | 9 | const checkAuth = require('../middleware/check-auth'); 10 | 11 | const checkFileAccess = require('../middleware/checkFileAccess'); 12 | 13 | const ApiController = require('../controllers/apiController'); 14 | 15 | const storage = multer.diskStorage({ 16 | destination: (req, file, cb) => { 17 | let targetPath = 'uploads/'; 18 | 19 | if (req.params.path !== 'my-drive') { 20 | targetPath = Buffer.from(req.params.path, 'base64').toString('ascii'); 21 | 22 | if (fs.existsSync(targetPath) && fs.statSync(targetPath).isDirectory()) { 23 | cb(null, targetPath); 24 | } else { 25 | fs.ensureDir(targetPath) 26 | .then(() => { 27 | cb(null, targetPath); 28 | }) 29 | .catch((err) => { 30 | this.res.status(500).json({ 31 | error: err, 32 | targetPath, 33 | }); 34 | }); 35 | } 36 | } else { 37 | cb(null, targetPath); 38 | } 39 | }, 40 | 41 | filename: (req, file, cb) => { 42 | cb(null, file.originalname); 43 | }, 44 | }); 45 | 46 | const fileFilter = (req, file, cb) => { 47 | // reject a file 48 | // if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') { 49 | cb(null, true); 50 | // } else { 51 | // cb(null, false); 52 | // } 53 | }; 54 | 55 | const upload = multer({ 56 | storage, 57 | limits: { 58 | fileSize: 1024 * 1024 * 1024 * 1024 * 1024 * 1024, 59 | }, 60 | fileFilter, 61 | }); 62 | 63 | 64 | // Get fies 65 | router.get('/getFiles/:dir/:limit?/:type?/:cache?/:event?', checkAuth, ApiController.getFiles); 66 | 67 | // get thirdParty files 68 | router.get('/thirdParty/:path/t/:type', checkFileAccess, ApiController.thirdParty); 69 | 70 | // get images 71 | router.get('/images/:path/t/:type/d/:width/:height/m/:mime1/:mime2/:key', checkFileAccess, ApiController.serveImages); 72 | 73 | // get files 74 | router.get('/files/:path/t/:type/m/:mime1/:mime2/s/:size/:key', checkFileAccess, ApiController.serveFiles); 75 | 76 | // Download files 77 | router.get('/download/file/:path', checkFileAccess, ApiController.downloadFile); 78 | 79 | // Batch files 80 | router.post('/batch/:path', checkFileAccess, ApiController.zip_batch); 81 | 82 | // Upload files 83 | router.post('/upload/:path', checkAuth, upload.single('files'), ApiController.uploadFiles); 84 | 85 | // Delete File 86 | router.delete('/delete/:path', checkAuth, ApiController.deleteFiles); 87 | 88 | // Create Directory 89 | router.put('/createDirectory/:path', checkAuth, ApiController.createDirectory); 90 | 91 | // rename 92 | router.put('/rename/:path', checkAuth, ApiController.rename); 93 | 94 | // Recents 95 | router.post('/log', checkAuth, ApiController.log); 96 | 97 | // test 98 | router.get('/test', ApiController.test); 99 | 100 | module.exports = router; 101 | -------------------------------------------------------------------------------- /server/thirdParty/photoshop.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /server/thirdParty/pps.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /server/src/lib/download.js: -------------------------------------------------------------------------------- 1 | 2 | const path = require('path'); 3 | const url = require('url'); 4 | const http = require('http'); 5 | const fs = require('fs'); 6 | 7 | let write_file; 8 | // what global variable do we have? 9 | let complete = false; 10 | let content_length = 0; 11 | let downloaded_bytes = 0; 12 | 13 | // create the downloader 'class' 14 | class Downloader { 15 | constructor() { 16 | // we will need to be able to set the remote file to download 17 | this.set_remote_file = function (file) { 18 | remote_file = file; 19 | local_file = path.basename(remote_file); 20 | }; 21 | // we want to set the local file to write to 22 | this.set_local_file = function (file) { 23 | local_file = file; 24 | }; 25 | // run this fukker! 26 | this.run = function () { 27 | // start the download 28 | this.download(remote_file, local_file, 0); 29 | }; 30 | this.download = function (remote, local, num) { 31 | console.log(remote); 32 | if (num > 10) { 33 | console.log('Too many redirects'); 34 | } 35 | // remember who we are 36 | const self = this; 37 | // set some default values 38 | const redirect = false; 39 | let new_remote = null; 40 | const write_to_file = false; 41 | let write_file_ready = false; 42 | // parse the url of the remote file 43 | const u = url.parse(remote); 44 | // set the options for the 'get' from the remote file 45 | const opts = { 46 | host: u.hostname, 47 | port: u.port, 48 | path: u.pathname, 49 | }; 50 | // get the file 51 | var request = http.get(opts, (response) => { 52 | switch (response.statusCode) { 53 | case 200: 54 | // this is good 55 | // what is the content length? 56 | content_length = response.headers['content-length']; 57 | break; 58 | case 302: 59 | new_remote = response.headers.location; 60 | self.download(new_remote, local_file, num + 1); 61 | return; 62 | break; 63 | case 404: 64 | console.log('File Not Found'); 65 | default: 66 | // what the hell is default in this situation? 404? 67 | request.abort(); 68 | return; 69 | } 70 | response.on('data', (chunk) => { 71 | //are we supposed to be writing to file? 72 | if (!write_file_ready) { 73 | //set up the write file 74 | write_file = fs.createWriteStream(local_file); 75 | write_file_ready = true; 76 | } 77 | write_file.write(chunk); 78 | downloaded_bytes += chunk.length; 79 | percent = parseInt((downloaded_bytes / content_length) * 100); 80 | console.log(percent); 81 | }); 82 | response.on('end', () => { 83 | complete = true; 84 | write_file.end(); 85 | }); 86 | }); 87 | request.on('error', (e) => { 88 | console.log('Got error: ' + e.message); 89 | }); 90 | }; 91 | } 92 | } 93 | exports.Downloader = Downloader; 94 | -------------------------------------------------------------------------------- /server/thirdParty/rar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 10 | 26 | 28 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /server/thirdParty/docx.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /server/thirdParty/bmp.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | --------------------------------------------------------------------------------