53 lines
2.0 KiB
Python
53 lines
2.0 KiB
Python
from datetime import datetime
|
|
import enum
|
|
|
|
from sqlalchemy.dialects.mysql import INTEGER
|
|
|
|
from app import db
|
|
|
|
|
|
class ItemType(str, enum.Enum):
|
|
PASSWORD = 'password'
|
|
NOTE = 'note'
|
|
ADDRESS = 'address'
|
|
CARD = 'card'
|
|
BANK = 'bank'
|
|
SSN = 'ssn'
|
|
PASSKEY = 'passkey'
|
|
|
|
|
|
class VaultItem(db.Model):
|
|
__tablename__ = 'vault_items'
|
|
|
|
id = db.Column(INTEGER(unsigned=True), autoincrement=True, primary_key=True)
|
|
user_id = db.Column(INTEGER(unsigned=True), db.ForeignKey('users.id', ondelete='CASCADE'), nullable=False)
|
|
folder_id = db.Column(INTEGER(unsigned=True), db.ForeignKey('folders.id', ondelete='SET NULL'), nullable=True)
|
|
item_type = db.Column(db.String(20), nullable=False, default=ItemType.PASSWORD.value)
|
|
# name is stored in plaintext for display in the vault list.
|
|
# All other sensitive fields (username, password, URL, notes, etc.)
|
|
# are inside enc_data and are encrypted client-side with AES-256-GCM.
|
|
name = db.Column(db.String(255), nullable=False)
|
|
enc_data = db.Column(db.Text, nullable=False) # base64-encoded AES-256-GCM ciphertext
|
|
iv = db.Column(db.String(64), nullable=False) # base64-encoded 12-byte GCM nonce
|
|
created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
|
|
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
|
|
|
|
def to_dict(self):
|
|
# item_type is stored as a plain string; handle both str and enum safely
|
|
item_type = self.item_type
|
|
if isinstance(item_type, ItemType):
|
|
item_type = item_type.value
|
|
return {
|
|
'id': self.id,
|
|
'item_type': item_type,
|
|
'name': self.name,
|
|
'folder_id': self.folder_id,
|
|
'enc_data': self.enc_data,
|
|
'iv': self.iv,
|
|
'created_at': self.created_at.isoformat() if self.created_at else None,
|
|
'updated_at': self.updated_at.isoformat() if self.updated_at else None,
|
|
}
|
|
|
|
def __repr__(self):
|
|
return f'<VaultItem {self.name}>'
|