diff --git a/assets/common.js/main.js b/assets/common.js/main.js
index dd5c0896..e1c805b6 100644
--- a/assets/common.js/main.js
+++ b/assets/common.js/main.js
@@ -1,6 +1,7 @@
 #include array.js
 #include csrf.js
 #include html.js
+#include meta.js
 #include uniqstr.js
 #include xhr.js
 
diff --git a/assets/common.js/meta.js b/assets/common.js/meta.js
new file mode 100644
index 00000000..60fc34e8
--- /dev/null
+++ b/assets/common.js/meta.js
@@ -0,0 +1,36 @@
+#include html.js
+
+const $meta = (() => {
+    return {
+        get(name, prefixed=true) {
+            if(!name) return;
+            if(prefixed) name = `msz-${name}`;
+
+            const elem = $query(`meta[name="${name}"]`);
+            if(elem instanceof HTMLMetaElement && typeof elem.content === 'string')
+                return elem.content;
+
+            return null;
+        },
+        set(name, value, prefixed=true) {
+            if(!name) return;
+            if(prefixed) name = `msz-${name}`;
+
+            let elem = $query(`meta[name="${name}"]`);
+            if(elem instanceof HTMLMetaElement) {
+                if(typeof value === 'string')
+                    elem.content = value;
+                else
+                    elem.remove();
+            } else {
+                if(typeof value !== 'string')
+                    return;
+
+                elem = document.createElement('meta');
+                elem.name = name;
+                elem.content = value;
+                document.head.appendChild(elem);
+            }
+        },
+    };
+})();
diff --git a/assets/misuzu.js/ext/eeprom.js b/assets/misuzu.js/ext/eeprom.js
index b9527d0b..f3556c34 100644
--- a/assets/misuzu.js/ext/eeprom.js
+++ b/assets/misuzu.js/ext/eeprom.js
@@ -1,8 +1,6 @@
-const MszEEPROM = function(appId, endPoint) {
+const MszEEPROM = function(appId) {
     if(typeof appId !== 'string')
         throw 'appId must be a string';
-    if(typeof endPoint !== 'string')
-        throw 'endPoint must be a string';
 
     return {
         create: fileInput => {
@@ -42,7 +40,7 @@ const MszEEPROM = function(appId, endPoint) {
                         formData.append('src', appId);
                         formData.append('file', fileInput);
 
-                        const { status, body } = await $xhr.post(`${endPoint}/uploads`, {
+                        const { status, body } = await $xhr.post('/uploads', {
                             type: 'json',
                             authed: true,
                             upload: reportProgress,
diff --git a/assets/misuzu.js/forum/editor.jsx b/assets/misuzu.js/forum/editor.jsx
index 53ebde0d..ab441c3e 100644
--- a/assets/misuzu.js/forum/editor.jsx
+++ b/assets/misuzu.js/forum/editor.jsx
@@ -19,142 +19,144 @@ const MszForumEditor = function(form) {
     let lastPostText = '';
     let lastPostParser;
 
-    const eepromClient = new MszEEPROM(peepApp, peepPath);
-    const eepromHistory = <div class="eeprom-widget-history-items"/>;
+    const storagePool = $meta.get('forum-storage-pool');
+    if(storagePool) {
+        const eepromClient = new MszEEPROM(storagePool);
+        const eepromHistory = <div class="eeprom-widget-history-items"/>;
+        const eepromHandleFileUpload = async file => {
+            const uploadElemNameValue = <div class="eeprom-widget-file-name-value" title={file.name}>{file.name}</div>;
+            const uploadElemName = <a class="eeprom-widget-file-name" target="_blank">{uploadElemNameValue}</a>;
+            const uploadElemProgressText = <div class="eeprom-widget-file-progress">Please wait...</div>;
+            const uploadElemProgressBarValue = <div class="eeprom-widget-file-bar-fill" style={{ width: '0%' }}/>;
+            const uploadElem = <div class="eeprom-widget-file">
+                <div class="eeprom-widget-file-info">
+                    {uploadElemName}
+                    {uploadElemProgressText}
+                </div>
+                <div class="eeprom-widget-file-bar">
+                    {uploadElemProgressBarValue}
+                </div>
+            </div>;
 
-    const eepromHandleFileUpload = async file => {
-        const uploadElemNameValue = <div class="eeprom-widget-file-name-value" title={file.name}>{file.name}</div>;
-        const uploadElemName = <a class="eeprom-widget-file-name" target="_blank">{uploadElemNameValue}</a>;
-        const uploadElemProgressText = <div class="eeprom-widget-file-progress">Please wait...</div>;
-        const uploadElemProgressBarValue = <div class="eeprom-widget-file-bar-fill" style={{ width: '0%' }}/>;
-        const uploadElem = <div class="eeprom-widget-file">
-            <div class="eeprom-widget-file-info">
-                {uploadElemName}
-                {uploadElemProgressText}
+            eepromHistory.insertAdjacentElement('afterbegin', uploadElem);
+
+            const explodeUploadElem = () => { uploadElem.remove(); };
+            const uploadTask = eepromClient.create(file);
+
+            uploadTask.onProgress(prog => {
+                uploadElemProgressBarValue.style.width = `${Math.ceil(prog.progress * 100)}%`;
+                uploadElemProgressText.textContent = `${prog.progress.toLocaleString(undefined, { style: 'percent' })} (${prog.total - prog.loaded} bytes remaining)`;
+            });
+
+            try {
+                const fileInfo = await uploadTask.start();
+
+                uploadElem.classList.add('eeprom-widget-file-done');
+                uploadElemName.href = fileInfo.url;
+                uploadElemProgressText.textContent = '';
+
+                const insertTheLinkIntoTheBoxEx2 = () => {
+                    let insertText = location.protocol + fileInfo.url;
+
+                    if(parserElem.value == 'bb') { // bbcode
+                        if(fileInfo.isImage())
+                            insertText = `[img]${fileInfo.url}[/img]`;
+                        else if(fileInfo.isAudio())
+                            insertText = `[audio]${fileInfo.url}[/audio]`;
+                        else if(fileInfo.isVideo())
+                            insertText = `[video]${fileInfo.url}[/video]`;
+                    } else if(parserElem.value == 'md') { // markdown
+                        if(fileInfo.isMedia())
+                            insertText = `![](${fileInfo.url})`;
+                    }
+
+                    $insertTags(textElem, insertText, '');
+                    textElem.value = textElem.value.trim();
+                };
+
+                uploadElemProgressText.appendChild(<a href="javascript:void(0)" onclick={() => insertTheLinkIntoTheBoxEx2()}>Insert</a>);
+                uploadElemProgressText.appendChild($text(' '));
+                uploadElemProgressText.appendChild(<a href="javascript:void(0)" onclick={() => {
+                    eepromClient.delete(fileInfo)
+                        .then(() => explodeUploadElem())
+                        .catch(ex => {
+                            console.error(ex);
+                            MszShowMessageBox(ex, 'Upload Error');
+                        });
+                }}>Delete</a>);
+
+                insertTheLinkIntoTheBoxEx2();
+            } catch(ex) {
+                let errorText = 'Upload aborted.';
+
+                if(!ex.aborted) {
+                    console.error(ex);
+                    errorText = ex.toString();
+                }
+
+                uploadElem.classList.add('eeprom-widget-file-fail');
+                uploadElemProgressText.textContent = errorText;
+                await MszShowMessageBox(errorText, 'Upload Error');
+            }
+        };
+
+        const eepromFormInput = <input type="file" multiple={true} class="eeprom-widget-form-input"
+            onchange={() => {
+                const files = eepromFormInput.files;
+                for(const file of files)
+                    eepromHandleFileUpload(file);
+                eepromFormInput.value = '';
+            }}/>;
+
+        const eepromForm = <label class="eeprom-widget-form">
+            {eepromFormInput}
+            <div class="eeprom-widget-form-text">
+                Select Files...
             </div>
-            <div class="eeprom-widget-file-bar">
-                {uploadElemProgressBarValue}
+        </label>;
+
+        const eepromWidget = <div class="eeprom-widget">
+            {eepromForm}
+            <div class="eeprom-widget-history">
+                {eepromHistory}
             </div>
         </div>;
 
-        eepromHistory.insertAdjacentElement('afterbegin', uploadElem);
+        form.appendChild(eepromWidget);
 
-        const explodeUploadElem = () => { uploadElem.remove(); };
-        const uploadTask = eepromClient.create(file);
+        textElem.addEventListener('paste', ev => {
+            if(ev.clipboardData && ev.clipboardData.files.length > 0) {
+                ev.preventDefault();
 
-        uploadTask.onProgress(prog => {
-            uploadElemProgressBarValue.style.width = `${Math.ceil(prog.progress * 100)}%`;
-            uploadElemProgressText.textContent = `${prog.progress.toLocaleString(undefined, { style: 'percent' })} (${prog.total - prog.loaded} bytes remaining)`;
+                const files = ev.clipboardData.files;
+                for(const file of files)
+                    eepromHandleFileUpload(file);
+            }
         });
 
-        try {
-            const fileInfo = await uploadTask.start();
-
-            uploadElem.classList.add('eeprom-widget-file-done');
-            uploadElemName.href = fileInfo.url;
-            uploadElemProgressText.textContent = '';
-
-            const insertTheLinkIntoTheBoxEx2 = () => {
-                let insertText = location.protocol + fileInfo.url;
-
-                if(parserElem.value == 'bb') { // bbcode
-                    if(fileInfo.isImage())
-                        insertText = `[img]${fileInfo.url}[/img]`;
-                    else if(fileInfo.isAudio())
-                        insertText = `[audio]${fileInfo.url}[/audio]`;
-                    else if(fileInfo.isVideo())
-                        insertText = `[video]${fileInfo.url}[/video]`;
-                } else if(parserElem.value == 'md') { // markdown
-                    if(fileInfo.isMedia())
-                        insertText = `![](${fileInfo.url})`;
-                }
-
-                $insertTags(textElem, insertText, '');
-                textElem.value = textElem.value.trim();
-            };
-
-            uploadElemProgressText.appendChild(<a href="javascript:void(0)" onclick={() => insertTheLinkIntoTheBoxEx2()}>Insert</a>);
-            uploadElemProgressText.appendChild($text(' '));
-            uploadElemProgressText.appendChild(<a href="javascript:void(0)" onclick={() => {
-                eepromClient.delete(fileInfo)
-                    .then(() => explodeUploadElem())
-                    .catch(ex => {
-                        console.error(ex);
-                        MszShowMessageBox(ex, 'Upload Error');
-                    });
-            }}>Delete</a>);
-
-            insertTheLinkIntoTheBoxEx2();
-        } catch(ex) {
-            let errorText = 'Upload aborted.';
-
-            if(!ex.aborted) {
-                console.error(ex);
-                errorText = ex.toString();
-            }
-
-            uploadElem.classList.add('eeprom-widget-file-fail');
-            uploadElemProgressText.textContent = errorText;
-            await MszShowMessageBox(errorText, 'Upload Error');
-        }
-    };
-
-    const eepromFormInput = <input type="file" multiple={true} class="eeprom-widget-form-input"
-        onchange={() => {
-            const files = eepromFormInput.files;
-            for(const file of files)
-                eepromHandleFileUpload(file);
-            eepromFormInput.value = '';
-        }}/>;
-
-    const eepromForm = <label class="eeprom-widget-form">
-        {eepromFormInput}
-        <div class="eeprom-widget-form-text">
-            Select Files...
-        </div>
-    </label>;
-
-    const eepromWidget = <div class="eeprom-widget">
-        {eepromForm}
-        <div class="eeprom-widget-history">
-            {eepromHistory}
-        </div>
-    </div>;
-
-    form.appendChild(eepromWidget);
-
-    textElem.addEventListener('paste', ev => {
-        if(ev.clipboardData && ev.clipboardData.files.length > 0) {
+        document.body.addEventListener('dragenter', ev => {
             ev.preventDefault();
+            ev.stopPropagation();
+        });
+        document.body.addEventListener('dragover', ev => {
+            ev.preventDefault();
+            ev.stopPropagation();
+        });
+        document.body.addEventListener('dragleave', ev => {
+            ev.preventDefault();
+            ev.stopPropagation();
+        });
+        document.body.addEventListener('drop', ev => {
+            ev.preventDefault();
+            ev.stopPropagation();
 
-            const files = ev.clipboardData.files;
-            for(const file of files)
-                eepromHandleFileUpload(file);
-        }
-    });
-
-    document.body.addEventListener('dragenter', ev => {
-        ev.preventDefault();
-        ev.stopPropagation();
-    });
-    document.body.addEventListener('dragover', ev => {
-        ev.preventDefault();
-        ev.stopPropagation();
-    });
-    document.body.addEventListener('dragleave', ev => {
-        ev.preventDefault();
-        ev.stopPropagation();
-    });
-    document.body.addEventListener('drop', ev => {
-        ev.preventDefault();
-        ev.stopPropagation();
-
-        if(ev.dataTransfer && ev.dataTransfer.files.length > 0) {
-            const files = ev.dataTransfer.files;
-            for(const file of files)
-                eepromHandleFileUpload(file);
-        }
-    });
+            if(ev.dataTransfer && ev.dataTransfer.files.length > 0) {
+                const files = ev.dataTransfer.files;
+                for(const file of files)
+                    eepromHandleFileUpload(file);
+            }
+        });
+    }
 
     // hack: don't prompt user when hitting submit, really need to make this not stupid.
     buttonsElem.firstChild.addEventListener('click', () => MszForumEditorAllowClose = true);
diff --git a/assets/misuzu.js/messages/reply.jsx b/assets/misuzu.js/messages/reply.jsx
index 05559b88..8295b129 100644
--- a/assets/misuzu.js/messages/reply.jsx
+++ b/assets/misuzu.js/messages/reply.jsx
@@ -65,73 +65,76 @@ const MszMessagesReply = function(element) {
 
     // this implementation is godawful but it'll do for now lol
     // need to make it easier to share the forum's implementation
-    const eepromClient = new MszEEPROM(peepApp, peepPath);
-    const eepromHandleFileUpload = async file => {
-        const uploadTask = eepromClient.create(file);
+    const storagePool = $meta.get('messages-storage-pool');
+    if(storagePool) {
+        const eepromClient = new MszEEPROM(storagePool);
+        const eepromHandleFileUpload = async file => {
+            const uploadTask = eepromClient.create(file);
 
-        try {
-            const fileInfo = await uploadTask.start();
-            const parserMode = parseInt(parserSelect.value);
-            let insertText = location.protocol + fileInfo.url;
+            try {
+                const fileInfo = await uploadTask.start();
+                const parserMode = parseInt(parserSelect.value);
+                let insertText = location.protocol + fileInfo.url;
 
-            if(parserMode == 1) { // bbcode
-                if(fileInfo.isImage())
-                    insertText = `[img]${fileInfo.url}[/img]`;
-                else if(fileInfo.isAudio())
-                    insertText = `[audio]${fileInfo.url}[/audio]`;
-                else if(fileInfo.isVideo())
-                    insertText = `[video]${fileInfo.url}[/video]`;
-            } else if(parserMode == 2) { // markdown
-                if(fileInfo.isMedia())
-                    insertText = `![](${fileInfo.url})`;
+                if(parserMode == 1) { // bbcode
+                    if(fileInfo.isImage())
+                        insertText = `[img]${fileInfo.url}[/img]`;
+                    else if(fileInfo.isAudio())
+                        insertText = `[audio]${fileInfo.url}[/audio]`;
+                    else if(fileInfo.isVideo())
+                        insertText = `[video]${fileInfo.url}[/video]`;
+                } else if(parserMode == 2) { // markdown
+                    if(fileInfo.isMedia())
+                        insertText = `![](${fileInfo.url})`;
+                }
+
+                $insertTags(bodyElem, insertText, '');
+                bodyElem.value = bodyElem.value.trim();
+            } catch(ex) {
+                let errorText = 'Upload aborted.';
+
+                if(!ex.aborted) {
+                    console.error(ex);
+                    errorText = ex.toString();
+                }
+
+                await MszShowMessageBox(errorText, 'Upload Error');
             }
+        };
 
-            $insertTags(bodyElem, insertText, '');
-            bodyElem.value = bodyElem.value.trim();
-        } catch(ex) {
-            let errorText = 'Upload aborted.';
+        bodyElem.addEventListener('paste', ev => {
+            if(ev.clipboardData && ev.clipboardData.files.length > 0) {
+                ev.preventDefault();
 
-            if(!ex.aborted) {
-                console.error(ex);
-                errorText = ex.toString();
+                const files = ev.clipboardData.files;
+                for(const file of files)
+                    eepromHandleFileUpload(file);
             }
+        });
 
-            await MszShowMessageBox(errorText, 'Upload Error');
-        }
-    };
-
-    bodyElem.addEventListener('paste', ev => {
-        if(ev.clipboardData && ev.clipboardData.files.length > 0) {
+        document.body.addEventListener('dragenter', ev => {
             ev.preventDefault();
+            ev.stopPropagation();
+        });
+        document.body.addEventListener('dragover', ev => {
+            ev.preventDefault();
+            ev.stopPropagation();
+        });
+        document.body.addEventListener('dragleave', ev => {
+            ev.preventDefault();
+            ev.stopPropagation();
+        });
+        document.body.addEventListener('drop', ev => {
+            ev.preventDefault();
+            ev.stopPropagation();
 
-            const files = ev.clipboardData.files;
-            for(const file of files)
-                eepromHandleFileUpload(file);
-        }
-    });
-
-    document.body.addEventListener('dragenter', ev => {
-        ev.preventDefault();
-        ev.stopPropagation();
-    });
-    document.body.addEventListener('dragover', ev => {
-        ev.preventDefault();
-        ev.stopPropagation();
-    });
-    document.body.addEventListener('dragleave', ev => {
-        ev.preventDefault();
-        ev.stopPropagation();
-    });
-    document.body.addEventListener('drop', ev => {
-        ev.preventDefault();
-        ev.stopPropagation();
-
-        if(ev.dataTransfer && ev.dataTransfer.files.length > 0) {
-            const files = ev.dataTransfer.files;
-            for(const file of files)
-                eepromHandleFileUpload(file);
-        }
-    });
+            if(ev.dataTransfer && ev.dataTransfer.files.length > 0) {
+                const files = ev.dataTransfer.files;
+                for(const file of files)
+                    eepromHandleFileUpload(file);
+            }
+        });
+    }
 
     return {
         get element() { return element; },
diff --git a/docs/source.md b/docs/source.md
index 953f690c..cdf85cda 100644
--- a/docs/source.md
+++ b/docs/source.md
@@ -8,7 +8,6 @@ Below are a number of links to source code repositories related to Flashii.net a
   - [Futami](https://patchii.net/flashii/futami): Common data shared between the chat clients.
   - [Mami](https://patchii.net/flashii/mami): Web client for chat.
   - [Ami](https://patchii.net/flashii/ami): Web client for chat for older browsers.
-  - [EEPROM](https://patchii.net/flashii/eeprom): Service for file uploading.
   - [Uiharu](https://patchii.net/flashii/uiharu): Service for looking up URL metadata.
   - [Seria](https://patchii.net/flashii/seria): Software used by the downloads tracker.
   - [Mince](https://patchii.net/flashii/mince): Source code for the Minecraft servers subwebsite.
diff --git a/src/Forum/ForumContext.php b/src/Forum/ForumContext.php
index 3b90ba87..3d6539ab 100644
--- a/src/Forum/ForumContext.php
+++ b/src/Forum/ForumContext.php
@@ -2,6 +2,7 @@
 namespace Misuzu\Forum;
 
 use stdClass;
+use Index\Config\Config;
 use Index\Db\DbConnection;
 use Misuzu\Parsers\TextFormat;
 use Misuzu\Users\UserInfo;
@@ -22,7 +23,14 @@ class ForumContext {
     /** @var array<string, ForumSignatureInfo> */
     private array $cachedSignatures = [];
 
-    public function __construct(DbConnection $dbConn) {
+    public string $storagePoolName {
+        get => $this->config->getString('storage_pool');
+    }
+
+    public function __construct(
+        DbConnection $dbConn,
+        public private(set) Config $config,
+    ) {
         $this->categories = new ForumCategoriesData($dbConn);
         $this->topics = new ForumTopicsData($dbConn);
         $this->topicRedirects = new ForumTopicRedirectsData($dbConn);
diff --git a/src/Messages/MessagesContext.php b/src/Messages/MessagesContext.php
index 57fafa66..87f10174 100644
--- a/src/Messages/MessagesContext.php
+++ b/src/Messages/MessagesContext.php
@@ -1,12 +1,20 @@
 <?php
 namespace Misuzu\Messages;
 
+use Index\Config\Config;
 use Index\Db\DbConnection;
 
 class MessagesContext {
     public private(set) MessagesData $database;
 
-    public function __construct(DbConnection $dbConn) {
+    public string $storagePoolName {
+        get => $this->config->getString('storage_pool');
+    }
+
+    public function __construct(
+        DbConnection $dbConn,
+        public private(set) Config $config,
+    ) {
         $this->database = new MessagesData($dbConn);
     }
 }
diff --git a/src/MisuzuContext.php b/src/MisuzuContext.php
index 4a9307c2..36b40a8c 100644
--- a/src/MisuzuContext.php
+++ b/src/MisuzuContext.php
@@ -94,8 +94,14 @@ class MisuzuContext {
             config: $this->config->scopeTo('auth'),
         ));
         $this->deps->register($this->commentsCtx = $this->deps->constructLazy(Comments\CommentsContext::class));
-        $this->deps->register($this->forumCtx = $this->deps->constructLazy(Forum\ForumContext::class));
-        $this->deps->register($this->messagesCtx = $this->deps->constructLazy(Messages\MessagesContext::class));
+        $this->deps->register($this->forumCtx = $this->deps->constructLazy(
+            Forum\ForumContext::class,
+            config: $this->config->scopeTo('forum'),
+        ));
+        $this->deps->register($this->messagesCtx = $this->deps->constructLazy(
+            Messages\MessagesContext::class,
+            config: $this->config->scopeTo('messages'),
+        ));
         $this->deps->register($this->oauth2Ctx = $this->deps->constructLazy(
             OAuth2\OAuth2Context::class,
             config: $this->config->scopeTo('oauth2'),
@@ -153,17 +159,17 @@ class MisuzuContext {
     }
 
     public function startTemplating(bool $cache = true): void {
-        $globals = $this->config->getValues([
-            ['eeprom.path:s', '', 'eeprom_path'],
-            ['eeprom.app:s', '', 'eeprom_app'],
-            ['eeprom.appmsgs:s', '', 'eeprom_app_messages'],
-        ]);
-
         $isDebug = Misuzu::debug();
-        $globals['site_info'] = $this->siteInfo;
-        $globals['auth_info'] = $this->authInfo;
-        $globals['active_ban_info'] = $this->usersCtx->tryGetActiveBan($this->authInfo->userInfo);
-        $globals['display_timings_info'] = $isDebug || $this->authInfo->getPerms('global')->check(Perm::G_TIMINGS_VIEW);
+        $globals = [
+            'site_info' => $this->siteInfo,
+            'auth_info' => $this->authInfo,
+            'active_ban_info' => $this->usersCtx->tryGetActiveBan($this->authInfo->userInfo),
+            'display_timings_info' => $isDebug || $this->authInfo->getPerms('global')->check(Perm::G_TIMINGS_VIEW),
+            'meta' => [
+                'forum-storage-pool' => $this->forumCtx->storagePoolName,
+                'messages-storage-pool' => $this->messagesCtx->storagePoolName,
+            ],
+        ];
 
         $this->templating = new TplEnvironment(
             Misuzu::PATH_TEMPLATES,
diff --git a/src/Storage/Files/FilesContext.php b/src/Storage/Files/FilesContext.php
index d01efcc8..efe6c23f 100644
--- a/src/Storage/Files/FilesContext.php
+++ b/src/Storage/Files/FilesContext.php
@@ -146,7 +146,7 @@ class FilesContext {
             throw new InvalidArgumentException('$format is not a supported format');
 
         $type = 'application/octet-stream';
-        $path = tempnam(sys_get_temp_dir(), 'eeprom-thumbnail-');
+        $path = tempnam(sys_get_temp_dir(), 'msz-thumbnail-');
         $imagick = new Imagick;
         try {
             $this->readIntoImagick($imagick, $original);
@@ -174,7 +174,7 @@ class FilesContext {
         if(!is_file($sourcePath))
             throw new RuntimeException('local data for provided $original does not exist');
 
-        $targetPath = tempnam(sys_get_temp_dir(), sprintf('eeprom-crop-%d-', $dimensions));
+        $targetPath = tempnam(sys_get_temp_dir(), sprintf('msz-crop-%d-', $dimensions));
         $imagick = new Imagick;
         try {
             if($original->isImage)
diff --git a/src/Storage/Pools/PoolInfoGetField.php b/src/Storage/Pools/PoolInfoGetField.php
index c448ad22..fb07b6de 100644
--- a/src/Storage/Pools/PoolInfoGetField.php
+++ b/src/Storage/Pools/PoolInfoGetField.php
@@ -5,4 +5,5 @@ enum PoolInfoGetField {
     case Id;
     case Name;
     case UploadId;
+    case IdOrName;
 }
diff --git a/src/Storage/Pools/PoolsData.php b/src/Storage/Pools/PoolsData.php
index cf172bd3..76603169 100644
--- a/src/Storage/Pools/PoolsData.php
+++ b/src/Storage/Pools/PoolsData.php
@@ -49,6 +49,7 @@ class PoolsData {
         $field = match($field) {
             PoolInfoGetField::Id => 'pool_id = ?',
             PoolInfoGetField::Name => 'pool_name = ?',
+            PoolInfoGetField::IdOrName => sprintf('pool_%s = ?', ctype_digit($value) ? 'id' : 'name'),
             PoolInfoGetField::UploadId => 'pool_id = (SELECT pool_id FROM msz_storage_uploads WHERE upload_id = ?)',
         };
 
diff --git a/src/Storage/Tasks/TasksContext.php b/src/Storage/Tasks/TasksContext.php
index 61679830..130d3c6f 100644
--- a/src/Storage/Tasks/TasksContext.php
+++ b/src/Storage/Tasks/TasksContext.php
@@ -29,6 +29,6 @@ class TasksContext {
         if($taskInfo instanceof TaskInfo)
             $taskInfo = $taskInfo->id;
 
-        return implode(DIRECTORY_SEPARATOR, [sys_get_temp_dir(), sprintf('eeprom-upload-%s', $taskInfo)]);
+        return implode(DIRECTORY_SEPARATOR, [sys_get_temp_dir(), sprintf('msz-upload-%s', $taskInfo)]);
     }
 }
diff --git a/src/Storage/Uploads/UploadsLegacyRoutes.php b/src/Storage/Uploads/UploadsLegacyRoutes.php
index d719a9e3..62ddf963 100644
--- a/src/Storage/Uploads/UploadsLegacyRoutes.php
+++ b/src/Storage/Uploads/UploadsLegacyRoutes.php
@@ -14,7 +14,7 @@ use Index\Urls\{UrlFormat,UrlSource,UrlSourceCommon};
 use Misuzu\Perm;
 use Misuzu\Auth\AuthInfo;
 use Misuzu\Storage\Denylist\{DenylistContext,DenylistReason};
-use Misuzu\Storage\Pools\PoolsContext;
+use Misuzu\Storage\Pools\{PoolsContext,PoolInfoGetField};
 use Misuzu\Storage\Pools\Rules\{ConstrainSizeRule,EnsureVariantRule,EnsureVariantRuleThumb};
 use Misuzu\Storage\Files\{FilesContext,FileImportMode,FileInfoGetFileField};
 use Misuzu\Users\UsersContext;
@@ -180,7 +180,10 @@ class UploadsLegacyRoutes implements RouteHandler, UrlSource {
         }
 
         try {
-            $poolInfo = $this->poolsCtx->pools->getPool((string)$content->getFilteredParam('src', FILTER_VALIDATE_INT));
+            $poolInfo = $this->poolsCtx->pools->getPool(
+                (string)$content->getParam('src'),
+                PoolInfoGetField::IdOrName,
+            );
             if($poolInfo->protected) {
                 $response->statusCode = 404;
                 return [
@@ -227,7 +230,7 @@ class UploadsLegacyRoutes implements RouteHandler, UrlSource {
             ];
         }
 
-        $tmpFile = tempnam(sys_get_temp_dir(), 'eeprom-upload-');
+        $tmpFile = tempnam(sys_get_temp_dir(), 'msz-upload-');
         $file->moveTo($tmpFile);
         $hash = hash_file('sha256', $tmpFile, true);
 
diff --git a/templates/forum/posting.twig b/templates/forum/posting.twig
index 0b09491d..14f9ed8e 100644
--- a/templates/forum/posting.twig
+++ b/templates/forum/posting.twig
@@ -109,10 +109,4 @@
             </div>
         </div>
     </form>
-
-    {% if globals.eeprom_path is not empty and globals.eeprom_app is not empty %}
-        <script>
-            const peepPath = '{{ globals.eeprom_path }}', peepApp = '{{ globals.eeprom_app }}';
-        </script>
-    {% endif %}
 {% endblock %}
diff --git a/templates/master.twig b/templates/master.twig
index 97d022f2..d3d4778f 100644
--- a/templates/master.twig
+++ b/templates/master.twig
@@ -5,6 +5,9 @@
     <link href="/vendor/fontawesome/css/all.min.css" rel="stylesheet">
     <link href="{{ asset('common.css') }}" rel="stylesheet">
     <link href="{{ asset('misuzu.css') }}" rel="stylesheet">
+    {% for name, value in globals.meta %}
+        {% if value is not empty %}<meta name="msz-{{ name }}" content="{{ value }}">{% endif %}
+    {% endfor %}
     {% if main_css_vars is defined and main_css_vars is iterable and main_css_vars is not empty %}
         <style>
             :root {
diff --git a/templates/messages/master.twig b/templates/messages/master.twig
index 8d431ee4..fd9c24a6 100644
--- a/templates/messages/master.twig
+++ b/templates/messages/master.twig
@@ -3,10 +3,4 @@
 {% block content %}
     {% block messages_content %}
     {% endblock %}
-
-    {% if globals.eeprom_path is not empty and globals.eeprom_app_messages is not empty %}
-        <script>
-            const peepPath = '{{ globals.eeprom_path }}', peepApp = '{{ globals.eeprom_app_messages }}';
-        </script>
-    {% endif %}
 {% endblock %}