diff --git a/.gitignore b/.gitignore
index 1382ce4ebe8f01ca33b80e917558220ace3cd5c5..3d5d1fd0b6ef80fe1a25c106e6af36d6695daed4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -235,3 +235,4 @@ modules.xml
 # End of https://www.toptal.com/developers/gitignore/api/webstorm+all,visualstudiocode,node,dotenv
 
 *.db
+/photos/*.jpg
\ No newline at end of file
diff --git a/photos/.gitkeep b/photos/.gitkeep
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index 71499cecfa4281fbe9e737b5d552eb06676a5daf..f1968e52fd77e5dfcd9d62eeb84733e8c85949e5 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -25,11 +25,9 @@ model Agent {
     entries Entry[]
 }
 
-// Types: 'picture', 'location', 'text'
 model Entry {
     id      String  @id @default(uuid())
 
-    type    String
     private Boolean
 
     content String?
diff --git a/src/app.module.ts b/src/app.module.ts
index 46d666f1f3cf41da70a154233dd4a44636ad83be..7e2ad6badd1d2912a720d821d063014e4d55490a 100644
--- a/src/app.module.ts
+++ b/src/app.module.ts
@@ -3,7 +3,9 @@ import { PrismaModule } from './prisma/prisma.module';
 import { TelegramModule } from './telegram/telegram.module';
 import { GraphQLModule } from '@nestjs/graphql';
 import { ResolverModule } from './resolvers/resolver.module';
-import { AuthGuard } from './auth/auth.guard';
+import { GraphQLAuthGuard } from './auth/graphql-auth.guard';
+import { ImageController } from './images.controller';
+import { WebAuthGuard } from './auth/web-auth.guard';
 
 @Module({
     imports: [
@@ -18,6 +20,7 @@ import { AuthGuard } from './auth/auth.guard';
             }),
         }),
     ],
-    providers: [AuthGuard],
+    providers: [GraphQLAuthGuard, WebAuthGuard],
+    controllers: [ImageController],
 })
 export class AppModule {}
diff --git a/src/auth/auth.guard.ts b/src/auth/graphql-auth.guard.ts
similarity index 93%
rename from src/auth/auth.guard.ts
rename to src/auth/graphql-auth.guard.ts
index b1e3bb5dfd095c95a369b0c800f7b7a710ee9fbd..ef72b1b9b1b74a28289437e635da5a446808bda3 100644
--- a/src/auth/auth.guard.ts
+++ b/src/auth/graphql-auth.guard.ts
@@ -5,7 +5,7 @@ import { Observable } from "rxjs";
 import { PrismaService } from "src/prisma/prisma.service";
 
 @Injectable()
-export class AuthGuard implements CanActivate {
+export class GraphQLAuthGuard implements CanActivate {
 
     constructor(private prismaService: PrismaService) {}
     
diff --git a/src/auth/web-auth.guard.ts b/src/auth/web-auth.guard.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9f63f6b0756ba391fead96b40e0abf6dcc7ac5cc
--- /dev/null
+++ b/src/auth/web-auth.guard.ts
@@ -0,0 +1,30 @@
+import { CanActivate, ExecutionContext, Injectable } from "@nestjs/common";
+import { Request } from "express";
+import { PrismaService } from "src/prisma/prisma.service";
+
+@Injectable()
+export class WebAuthGuard implements CanActivate {
+
+    constructor(private prismaService: PrismaService) {}
+    
+    async canActivate(context: ExecutionContext): Promise<boolean> {
+        const req: Request = context.switchToHttp().getRequest();
+
+        const token = req.headers.authorization;
+
+        if (!token)
+            return false;
+
+        const group = await this.prismaService.group.findFirst({
+            where: { code: token },
+        });
+
+        if (!group)
+            return false;
+
+        req.group = group;
+
+        return true;
+    }
+
+}
\ No newline at end of file
diff --git a/src/images.controller.ts b/src/images.controller.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1523c0f3e932934188ce62bbcabf3fb7bb3408b1
--- /dev/null
+++ b/src/images.controller.ts
@@ -0,0 +1,17 @@
+import { Controller, Get, Header, HttpCode, Param, Res, UseGuards } from '@nestjs/common';
+import { Response } from 'express';
+import { join } from 'path';
+import { WebAuthGuard } from './auth/web-auth.guard';
+
+@Controller('images')
+@UseGuards(WebAuthGuard)
+export class ImageController {
+
+    @Get(':id')
+    public image(
+      @Param('id') id: string,
+      @Res() res: Response,
+    ) {
+        res.sendFile(join(process.cwd(), 'photos', `${id}.jpg`));
+    }
+}
\ No newline at end of file
diff --git a/src/resolvers/agent.resolver.ts b/src/resolvers/agent.resolver.ts
index 3138bf72b79c3ecd89597538447cd5617bc6d284..dcbc342ebb74dd0aa8b296f66f9076db85e10c5b 100644
--- a/src/resolvers/agent.resolver.ts
+++ b/src/resolvers/agent.resolver.ts
@@ -3,17 +3,16 @@ import { Agent } from './models/agent.model';
 import { PrismaService } from '../prisma/prisma.service';
 import { GraphQLString } from 'graphql';
 import { NotFoundException, UseGuards } from '@nestjs/common';
-import { AuthGuard } from 'src/auth/auth.guard';
+import { GraphQLAuthGuard } from 'src/auth/graphql-auth.guard';
 import { Request } from 'express';
 
 @Resolver(() => Agent)
-@UseGuards(AuthGuard)
+@UseGuards(GraphQLAuthGuard)
 export class AgentResolver {
     constructor(private prismaService: PrismaService) {}
 
     @Query(() => [Agent])
     listAgents(@Context() { req }: { req: Request }) {
-        console.log(req.group)
         return this.prismaService.agent.findMany();
     }
 
@@ -31,7 +30,19 @@ export class AgentResolver {
     }
 
     @ResolveField('entries')
-    async entries(@Parent() entry: Agent) {
+    async entries(
+        @Parent() entry: Agent,
+        @Context() { req }: { req: Request },
+    ) {
+        const unlocks = await this.prismaService.group.findFirst({
+            where: { id: req.group.id },
+            select: {
+                unlocks: true,
+            },
+        })
+            .then(value => value.unlocks)
+            .then(unlocks => unlocks.map(value => value.id));
+
         const result = await this.prismaService.agent.findFirst({
             where: {
                 id: entry.id,
@@ -41,6 +52,22 @@ export class AgentResolver {
             },
         });
 
+        const entries = result.entries.map(entry => {
+            if (!entry.private || unlocks.includes(entry.id))
+                return {
+                    ...entry,
+                    locked: false,
+                };
+
+            return {
+                id: entry.id,
+                agentId: entry.agentId,
+                private: true,
+                createdAt: entry.createdAt,
+                locked: true,
+            };
+        });
 
+        return entries;
     }
 }
diff --git a/src/resolvers/entry.resolver.ts b/src/resolvers/entry.resolver.ts
index 70bc535a51d4ba1fd9630569a349d0d18886a5c3..d914f24e3efda57cfd76408012406024d2f7da85 100644
--- a/src/resolvers/entry.resolver.ts
+++ b/src/resolvers/entry.resolver.ts
@@ -4,10 +4,10 @@ import { PrismaService } from '../prisma/prisma.service';
 import { GraphQLString } from 'graphql';
 import { BadRequestException, NotFoundException, UseGuards } from '@nestjs/common';
 import { Request } from 'express';
-import { AuthGuard } from 'src/auth/auth.guard';
+import { GraphQLAuthGuard } from 'src/auth/graphql-auth.guard';
 
 @Resolver(() => Entry)
-@UseGuards(AuthGuard)
+@UseGuards(GraphQLAuthGuard)
 export class EntryResolver {
     constructor(private prismaService: PrismaService) {}
 
@@ -39,6 +39,17 @@ export class EntryResolver {
         if (req.group.tokens <= 0)
             throw new BadRequestException('No remaining tokens');
 
+        const count = await this.prismaService.group.count({
+            where: {
+                unlocks: {
+                    some: { id },
+                },
+            },
+        });
+
+        if (count > 0)
+            throw new BadRequestException("Already unlocked");
+
         await this.prismaService.group.update({
             where: { id: req.group.id },
             data: {
@@ -49,7 +60,10 @@ export class EntryResolver {
             },
         });
 
-        return unlock;
+        return {
+            ...unlock,
+            locked: false,
+        };
 
     }
 }
diff --git a/src/resolvers/group.resolver.ts b/src/resolvers/group.resolver.ts
index 781044bd0ac58da831cf399659238a52199c4fbc..92b360e3a8547ac69bdbe9e571969c6a809d83ad 100644
--- a/src/resolvers/group.resolver.ts
+++ b/src/resolvers/group.resolver.ts
@@ -12,11 +12,11 @@ import { PrismaService } from '../prisma/prisma.service';
 import { GraphQLString } from 'graphql';
 import seedWords from 'mnemonic-words';
 import { NotFoundException, UseGuards } from '@nestjs/common';
-import { AuthGuard } from 'src/auth/auth.guard';
+import { GraphQLAuthGuard } from 'src/auth/graphql-auth.guard';
 import { Request } from 'express';
 
 @Resolver(() => Group)
-@UseGuards(AuthGuard)
+@UseGuards(GraphQLAuthGuard)
 export class GroupResolver {
     constructor(private prismaService: PrismaService) {}
 
@@ -57,6 +57,9 @@ export class GroupResolver {
             select: { unlocks: true },
         });
 
-        return result.unlocks;
+        return result.unlocks.map(unlock => ({
+            ...unlock,
+            locked: false,
+        }));
     }
 }
diff --git a/src/resolvers/models/entry.model.ts b/src/resolvers/models/entry.model.ts
index 1be72c1dd50bbecfffce091d75e388f77ee1b60b..e907a6f93c5b207c4621ad8a281adc1e834cce56 100644
--- a/src/resolvers/models/entry.model.ts
+++ b/src/resolvers/models/entry.model.ts
@@ -12,13 +12,10 @@ export class Entry {
     @Field()
     locked: boolean;
 
-    @Field()
-    type: string;
-
     @Field({ nullable: true })
     content?: string;
     @Field({ nullable: true })
-    path?: string;
+    image?: string;
     @Field({ nullable: true })
     lat?: string;
     @Field({ nullable: true })
diff --git a/src/telegram/telegram.service.ts b/src/telegram/telegram.service.ts
index 16674c1d586823132f6075858fb1e83a197f30f0..93e59f098991081b4a4858a8103dda1d0b8d25ef 100644
--- a/src/telegram/telegram.service.ts
+++ b/src/telegram/telegram.service.ts
@@ -5,11 +5,14 @@ import { PrismaService } from '../prisma/prisma.service';
 import * as fs from 'fs';
 import * as path from 'path';
 import { v4 as uuid } from 'uuid';
+import { Entry } from '@prisma/client';
 
 @Injectable()
 export class TelegramService {
     private telegram: TelegramBot;
 
+    private messageCache = new Map<number, Partial<Entry>>();
+
     constructor(private prismaService: PrismaService) {
         this.telegram = new TelegramBot(process.env.BOT_TOKEN, {
             polling: true,
@@ -19,7 +22,11 @@ export class TelegramService {
         this.telegram.onText(/^\/unregister/, this.unregister.bind(this));
         this.telegram.onText(/^\/state/, this.state.bind(this));
         this.telegram.onText(/^\/start/, this.start.bind(this));
-        this.telegram.onText(/^\/commit (.+)/, this.commit.bind(this));
+
+        this.telegram.onText(/^\/private/, this.private.bind(this));
+        this.telegram.onText(/^\/public/, this.public.bind(this));
+        this.telegram.onText(/^\/clear/, this.clear.bind(this));
+
         this.telegram.on('message', this.supplyValue.bind(this));
     }
 
@@ -32,40 +39,55 @@ export class TelegramService {
         ).toString(36);
     }
 
-    async start(msg: Message, match: RegExpMatchArray) {
-        await this.telegram.sendMessage(
+    async private(msg: Message, match: RegExpMatchArray) {
+        this.commitMessage(msg.from.id, true, msg);
+    }
+
+    async public(msg: Message, match: RegExpMatchArray) {
+        this.commitMessage(msg.from.id, false, msg);
+    }
+
+
+    async clear(msg: Message, match: RegExpMatchArray) {
+        this.messageCache.delete(msg.from.id);
+
+        return void (await this.telegram.sendMessage(
             msg.chat.id,
-            `/register [Name]\n/state\n/unregister`,
-        );
+            'Message Queue cleared!',
+        ));
     }
 
-    async commit(msg: Message, match: RegExpMatchArray) {
-        if (!match[1])
+    async commitMessage(id: number, isPrivate: boolean, msg: Message) {
+        if (!(await this.isRegistered(msg.from.id)))
             return void (await this.telegram.sendMessage(
                 msg.chat.id,
-                'No message',
+                'Not registered!',
             ));
 
-        if (!(await this.isRegistered(msg.from.id)))
+        if (!this.messageCache.has(id))
             return void (await this.telegram.sendMessage(
                 msg.chat.id,
-                'Not registered',
+                'No queued Messages!',
             ));
 
-        const agent = await this.prismaService.agent.findFirst({
-            where: { uid: String(msg.from.id) },
-        });
+        const entry = this.messageCache.get(msg.from.id);
+
+        entry.private = isPrivate;
+
+        this.messageCache.delete(msg.from.id);
 
         await this.prismaService.entry.create({
-            data: {
-                agentId: agent.id,
-                content: match[1],
-                private: false,
-                type: 'text',
-            },
+            data: entry as any,
         });
 
-        await this.telegram.sendMessage(msg.chat.id, 'Commit accepted');
+        // TODO: Send a notification to subscriptions
+    }
+
+    async start(msg: Message, match: RegExpMatchArray) {
+        await this.telegram.sendMessage(
+            msg.chat.id,
+            `/register [Name]\n/state\n/unregister`,
+        );
     }
 
     async register(msg: Message, match: RegExpMatchArray) {
@@ -135,20 +157,45 @@ export class TelegramService {
             where: { uid: String(msg.from.id) },
         });
 
-        const entries = await this.prismaService.entry.count({
-            where: { agentId: agent.id },
+        const publicEntries = await this.prismaService.entry.count({
+            where: { agentId: agent.id, private: false },
         });
 
-        const unlockEntries = await this.prismaService.entry.count({
-            where: { agentId: agent.id },
+        const privateEntries = await this.prismaService.entry.count({
+            where: { agentId: agent.id, private: true },
         });
 
         await this.telegram.sendMessage(
             msg.chat.id,
-            `Id: ${agent.id}\nName: ${agent.name}\nCode: ${agent.slug}\nPublic Entries: ${entries}\nUnlockable Entries: ${unlockEntries}`,
+            `Id: ${agent.id}\nName: ${agent.name}\nCode: ${agent.slug}\nPublic Entries: ${publicEntries}\nPrivate Entries: ${privateEntries}`,
         );
     }
 
+    async receiveImage(msg: Message): Promise<Partial<Entry>> {
+        let file;
+        let size = -1;
+
+        for (const p of msg.photo) {
+            if (p.width > size) {
+                size = p.width;
+                file = p.file_id;
+            }
+        }
+
+        const id = uuid();
+
+        const dest = fs.createWriteStream(
+            path.join(process.cwd(), 'photos', `${id}.jpg`),
+        );
+        const pipe = this.telegram.getFileStream(file).pipe(dest);
+
+        await new Promise((resolve) => pipe.on('finish', resolve));
+
+        return {
+            image: `${id}.jpg`,
+        };
+    }
+
     async supplyValue(msg: Message, metadata: Metadata) {
         if (metadata.type === 'text' && msg.text.startsWith('/')) return;
 
@@ -158,73 +205,50 @@ export class TelegramService {
             where: { uid: String(msg.from.id) },
         });
 
-        if (metadata.type === 'photo') {
-            let file,
-                size = -1;
-            for (const p of msg.photo) {
-                if (p.width > size) {
-                    size = p.width;
-                    file = p.file_id;
-                }
-            }
-
-            const id = uuid();
+        let entry: Partial<Entry> = {};
+        if (this.messageCache.has(msg.from.id))
+            entry = this.messageCache.get(msg.from.id);
 
-            const dest = fs.createWriteStream(
-                path.join(process.cwd(), 'static', 'photos', `${id}.jpg`),
-            );
-            const pipe = this.telegram.getFileStream(file).pipe(dest);
+        entry.agentId = agent.id;
 
-            await new Promise((resolve) => pipe.on('finish', resolve));
+        if (metadata.type === 'photo') {
+            const imageEntry = await this.receiveImage(msg);
+            
+            if (entry.image)
+                await this.telegram.sendMessage(
+                    msg.chat.id,
+                    'Overwriting previous image',
+                );
 
-            await this.prismaService.entry.create({
-                data: {
-                    type: 'picture',
-                    agentId: agent.id,
-                    image: `${id}.jpg`,
-                    private: true,
-                },
-            });
+            entry.image = imageEntry.image;
 
-            return void (await this.telegram.sendMessage(
+            await this.telegram.sendMessage(
                 msg.chat.id,
-                `Accepted Photo`,
-            ));
+                'Queued Image',
+            );
         } else if (metadata.type === 'text') {
-            await this.prismaService.entry.create({
-                data: {
-                    type: 'text',
-                    agentId: agent.id,
-                    content: msg.text,
-                    private: true,
-                },
-            });
+            entry.content = msg.text;
 
-            return void (await this.telegram.sendMessage(
+            await this.telegram.sendMessage(
                 msg.chat.id,
-                'Accepted Text',
-            ));
+                'Queued Text',
+            );
         } else if (metadata.type === 'location') {
-            await this.prismaService.entry.create({
-                data: {
-                    agentId: agent.id,
-                    type: 'location',
-                    lat: msg.location.latitude.toString(),
-                    lon: msg.location.longitude.toString(),
-                    private: true,
-                },
-            });
+            entry.lat = msg.location.latitude.toString();
+            entry.lon = msg.location.longitude.toString();
 
-            return void (await this.telegram.sendMessage(
+            await this.telegram.sendMessage(
                 msg.chat.id,
-                'Accepted Location',
-            ));
+                'Queued Location',
+            );
         } else {
             return void (await this.telegram.sendMessage(
                 msg.chat.id,
                 'Unsupported DataType',
             ));
         }
+
+        this.messageCache.set(msg.from.id, entry);
     }
 
     private async isRegistered(uid: string | number): Promise<boolean> {