diff --git a/src/background.html b/src/background.html
index a9e418fd..d353afbb 100644
--- a/src/background.html
+++ b/src/background.html
@@ -5,7 +5,6 @@
-
diff --git a/src/background.js b/src/background.js
index c573fd68..04f720c4 100644
--- a/src/background.js
+++ b/src/background.js
@@ -4,6 +4,7 @@ import AppIdService from './services/appId.service';
import ConstantsService from './services/constants.service';
import CryptoService from './services/crypto.service';
import EnvironmentService from './services/environment.service';
+import FolderService from './services/folder.service';
import i18nService from './services/i18nService.js';
import LockService from './services/lockService.js';
import PasswordGenerationService from './services/passwordGeneration.service';
@@ -14,6 +15,8 @@ import UserService from './services/user.service';
import UtilsService from './services/utils.service';
// Model imports
+import { Folder } from './models/domain/folder';
+
import { AttachmentData } from './models/data/attachmentData';
import { CardData } from './models/data/cardData';
import { CipherData } from './models/data/cipherData';
diff --git a/src/models/domain/domain.ts b/src/models/domain/domain.ts
new file mode 100644
index 00000000..4c565967
--- /dev/null
+++ b/src/models/domain/domain.ts
@@ -0,0 +1,42 @@
+import { CipherString } from '../domain/cipherString';
+
+export default abstract class Domain {
+ protected buildDomainModel(model: any, obj: any, map: any, alreadyEncrypted: boolean, notEncList: any = []) {
+ for (var prop in map) {
+ if (map.hasOwnProperty(prop)) {
+ var objProp = obj[(map[prop] || prop)];
+ if (alreadyEncrypted === true || notEncList.indexOf(prop) > -1) {
+ model[prop] = objProp ? objProp : null;
+ } else {
+ model[prop] = objProp ? new CipherString(objProp) : null;
+ }
+ }
+ }
+ }
+
+ protected async decryptObj(model: any, self: any, map: any, orgId: string) {
+ var promises = [];
+ for (let prop in map) {
+ if (!map.hasOwnProperty(prop)) {
+ continue;
+ }
+
+ (function (theProp) {
+ let promise = Promise.resolve().then(function () {
+ var mapProp = map[theProp] || theProp;
+ if (self[mapProp]) {
+ return self[mapProp].decrypt(orgId);
+ }
+ return null;
+ }).then(function (val) {
+ model[theProp] = val;
+ return;
+ });
+ promises.push(promise);
+ })(prop);
+ }
+
+ await Promise.all(promises);
+ return model;
+ }
+}
\ No newline at end of file
diff --git a/src/models/domain/folder.ts b/src/models/domain/folder.ts
new file mode 100644
index 00000000..7c8ca2a2
--- /dev/null
+++ b/src/models/domain/folder.ts
@@ -0,0 +1,35 @@
+import { CipherString } from './cipherString';
+import { FolderData } from '../data/folderData'
+
+import Domain from './domain'
+
+class Folder extends Domain {
+ id: string;
+ name: CipherString;
+
+ constructor(obj?: FolderData, alreadyEncrypted: boolean = false) {
+ super();
+ if(obj == null) {
+ return;
+ }
+
+ this.buildDomainModel(this, obj, {
+ id: null,
+ name: null
+ }, alreadyEncrypted, ['id']);
+ }
+
+ async decrypt(): Promise {
+ var self = this;
+ var model = {
+ id: self.id
+ };
+
+ return await this.decryptObj(model, this, {
+ name: null
+ }, null);
+ }
+}
+
+export { Folder };
+(window as any).Folder = Folder;
diff --git a/src/popup/app/app.js b/src/popup/app/app.js
index 34c4c36e..a49b67c0 100644
--- a/src/popup/app/app.js
+++ b/src/popup/app/app.js
@@ -32,6 +32,8 @@ import ServicesModule from './services/services.module';
import LockModule from './lock/lock.module';
// Model imports
+import { Folder } from './models/domain/folder';
+
import { AttachmentData } from '../../models/data/attachmentData';
import { CardData } from '../../models/data/cardData';
import { CipherData } from '../../models/data/cipherData';
diff --git a/src/services/folder.service.ts b/src/services/folder.service.ts
new file mode 100644
index 00000000..7761a1b6
--- /dev/null
+++ b/src/services/folder.service.ts
@@ -0,0 +1,153 @@
+import { CipherString } from '../models/domain/cipherString';
+import { Folder } from '../models/domain/folder';
+import { FolderData } from '../models/data/folderData';
+import { FolderResponse } from '../models/response/folderResponse';
+import { FolderRequest } from '../models/request/folderRequest';
+
+import ApiService from './api.service';
+import ConstantsService from './constants.service';
+import CryptoService from './crypto.service';
+import UserService from './user.service';
+import UtilsService from './utils.service';
+
+const Keys = {
+ foldersPrefix: 'folders_'
+};
+
+export default class FolderService {
+ decryptedFolderCache: any[];
+
+ constructor(private cryptoService: CryptoService, private userService: UserService, private i18nService: any, private apiService: ApiService) {
+
+ }
+
+ clearCache(): void {
+ this.decryptedFolderCache = null;
+ }
+
+ async encrypt(model: any): Promise {
+ const folder = new Folder();
+ folder.name = await this.cryptoService.encrypt(model.name);
+ return folder;
+ }
+
+ async get(id:string): Promise {
+ const userId = await this.userService.getUserId();
+ const folders = await UtilsService.getObjFromStorage