diff --git a/api/ENVIRONMENT.md b/api/ENVIRONMENT.md index 0f7a05e..ae23e1a 100644 --- a/api/ENVIRONMENT.md +++ b/api/ENVIRONMENT.md @@ -42,9 +42,6 @@ To emulate Azure Blob Storage locally. Azurite needs to be installed and running - `LOGIN_AUTHORIZED_DOMAINS`: Comma-separated list of additional email domains authorized to access the service via Google OAuth. -### Terms and Conditions - -- `CURRENT_TERMS_VERSION`: Version string for the current terms and conditions that users must accept. Example: `v1.0`, `v2.1`. Defaults to `v1.0` if not set. ### HTTPS - `HTTPS`: Set to 'true' to enable HTTPS for local deployment diff --git a/api/script/routes/authentication.ts b/api/script/routes/authentication.ts index 1c55da5..a99d471 100644 --- a/api/script/routes/authentication.ts +++ b/api/script/routes/authentication.ts @@ -75,8 +75,8 @@ export class Authentication { private isEmailDomainAuthorized(email: string): boolean { const authorizedDomains = process.env.LOGIN_AUTHORIZED_DOMAINS; - // Always include dream11.com as an allowed domain - let allowedDomains: string[] = ['dream11.com']; + // Initialize empty allowed domains array + let allowedDomains: string[] = []; if (authorizedDomains && authorizedDomains.trim() !== '') { // Parse comma-separated domains and normalize diff --git a/api/script/routes/management.ts b/api/script/routes/management.ts index 997213f..2b9e820 100644 --- a/api/script/routes/management.ts +++ b/api/script/routes/management.ts @@ -176,106 +176,7 @@ export function getManagementRouter(config: ManagementConfig): Router { .catch((error: error.CodePushError) => errorUtils.restErrorHandler(res, error, next)) }); - router.get("/account/ownerTermsStatus", (req: Request, res: Response, next: (err?: any) => void): any => { - const accountId: string = req.user.id; - const termsVersion = process.env.CURRENT_TERMS_VERSION || "v1.0"; - - // First check if user is an owner of at least one app - storage - .getAppOwnershipCount(accountId) - .then((ownershipCount: number) => { - if (ownershipCount === 0) { - // User is not an owner of any app - res.send({ - accountId: accountId, - isOwner: false, - ownerAppCount: 0, - termsAccepted: false, - termsVersion: null, - message: "Logged in account is not an owner of any app" - }); - return; - } - // User is an owner, now check terms acceptance - return storage.getTermsAcceptance(accountId) - .then((termsRecord: storageTypes.TermsAcceptance) => { - const isCurrentVersion = termsRecord.termsVersion === termsVersion; - res.send({ - accountId: accountId, - isOwner: true, - ownerAppCount: ownershipCount, - termsAccepted: true, - termsVersion: termsRecord.termsVersion, - acceptedTime: termsRecord.acceptedTime, - isCurrentVersion: isCurrentVersion, - currentRequiredVersion: termsVersion - }); - }) - .catch((termsError: storageTypes.StorageError) => { - if (termsError.code === storageTypes.ErrorCode.NotFound) { - // User is owner but hasn't accepted terms yet - res.send({ - accountId: accountId, - isOwner: true, - ownerAppCount: ownershipCount, - termsAccepted: false, - termsVersion: null, - acceptedTime: null, - isCurrentVersion: false, - currentRequiredVersion: termsVersion - }); - } else { - // Other error occurred - errorUtils.restErrorHandler(res, termsError, next); - } - }); - }) - .catch((error: storageTypes.StorageError) => { - errorUtils.restErrorHandler(res, error, next); - }); - }); - - router.post("/account/acceptTerms", (req: Request, res: Response, next: (err?: any) => void): any => { - const accountId: string = req.user.id; - const termsVersion = req.body.termsVersion; - console.log("termsVersion", termsVersion); - - // Validate required fields - if (!termsVersion || typeof termsVersion !== 'string') { - res.status(400).send({ error: "termsVersion is required and must be a string" }); - return; - } - - // Get user account to retrieve email - storage - .getAccount(accountId) - .then((account: storageTypes.Account) => { - const termsData: storageTypes.TermsAcceptance = { - accountId: accountId, - email: account.email, - termsVersion: termsVersion, - acceptedTime: new Date().getTime() - }; - - return storage.addOrUpdateTermsAcceptance(termsData); - }) - .then((savedTerms: storageTypes.TermsAcceptance) => { - res.status(201).send({ - message: "Terms acceptance recorded successfully", - termsAcceptance: { - id: savedTerms.id, - accountId: savedTerms.accountId, - email: savedTerms.email, - termsVersion: savedTerms.termsVersion, - acceptedTime: savedTerms.acceptedTime - } - }); - }) - .catch((error: storageTypes.StorageError) => { - errorUtils.restErrorHandler(res, error, next); - }); - }); router.patch("/accessKeys/:accessKeyName", (req: Request, res: Response, next: (err?: any) => void): any => { const accountId: string = req.user.id; diff --git a/api/script/storage/aws-storage.ts b/api/script/storage/aws-storage.ts index 34ce24b..657bb54 100644 --- a/api/script/storage/aws-storage.ts +++ b/api/script/storage/aws-storage.ts @@ -115,24 +115,6 @@ export function createCollaborators(sequelize: Sequelize) { }) } -//Create TermsAcceptance -export function createTermsAcceptance(sequelize: Sequelize) { - return sequelize.define("termsAcceptance", { - id: { type: DataTypes.STRING, allowNull: false, primaryKey: true }, - accountId: { - type: DataTypes.STRING, - allowNull: false, - unique: true, // Prevents duplicate entries per account - references: { - model: 'accounts', - key: 'id', - } - }, - email: { type: DataTypes.STRING, allowNull: false }, - termsVersion: { type: DataTypes.STRING, allowNull: false }, - acceptedTime: { type: DataTypes.BIGINT, allowNull: false }, // Epoch timestamp - }) -} //Create Deployment @@ -246,7 +228,6 @@ export function createModelss(sequelize: Sequelize) { const AppPointer = createAppPointer(sequelize); const Collaborator = createCollaborators(sequelize); const App = createApp(sequelize); - const TermsAcceptance = createTermsAcceptance(sequelize); // Define associations @@ -287,7 +268,6 @@ export function createModelss(sequelize: Sequelize) { AppPointer, Collaborator, App, - TermsAcceptance, }; } @@ -312,7 +292,6 @@ export const MODELS = { ACCOUNT : "account", APPPOINTER: "AppPointer", TENANT : "tenant", - TERMS_ACCEPTANCE : "termsAcceptance" } const DB_NAME = "codepushdb" @@ -523,66 +502,6 @@ export class S3Storage implements storage.Storage { .catch(S3Storage.storageErrorHandler); } - // Terms acceptance methods - public getTermsAcceptance(accountId: string): Promise { - return this.setupPromise - .then(() => { - return this.sequelize.models[MODELS.TERMS_ACCEPTANCE].findOne({ - where: { accountId: accountId } - }); - }) - .then((result: any) => { - if (!result) { - throw storage.storageError( - storage.ErrorCode.NotFound, - `Terms acceptance record not found for account ${accountId}` - ); - } - return { - id: result.id, - accountId: result.accountId, - email: result.email, - termsVersion: result.termsVersion, - acceptedTime: result.acceptedTime - }; - }) - .catch(S3Storage.storageErrorHandler); - } - - public addOrUpdateTermsAcceptance(termsAcceptance: storage.TermsAcceptance): Promise { - return this.setupPromise - .then(() => { - const termsData = { - id: termsAcceptance.id || security.generateSecureKey(termsAcceptance.accountId), - accountId: termsAcceptance.accountId, - email: termsAcceptance.email, - termsVersion: termsAcceptance.termsVersion, - acceptedTime: termsAcceptance.acceptedTime - // createdAt and updatedAt handled by Sequelize defaults - }; - - // Use upsert (INSERT ... ON DUPLICATE KEY UPDATE) - return this.sequelize.models[MODELS.TERMS_ACCEPTANCE].upsert(termsData, { - returning: true - }); - }) - .then(() => { - // After upsert, fetch the record to return it - return this.sequelize.models[MODELS.TERMS_ACCEPTANCE].findOne({ - where: { accountId: termsAcceptance.accountId } - }); - }) - .then((result: any) => { - return { - id: result.id, - accountId: result.accountId, - email: result.email, - termsVersion: result.termsVersion, - acceptedTime: result.acceptedTime - }; - }) - .catch(S3Storage.storageErrorHandler); - } public getAccountIdFromAccessKey(accessKey: string): Promise { diff --git a/api/script/storage/azure-storage.ts b/api/script/storage/azure-storage.ts index 7f5f878..25340b5 100644 --- a/api/script/storage/azure-storage.ts +++ b/api/script/storage/azure-storage.ts @@ -315,6 +315,7 @@ export class AzureStorage implements storage.Storage { }) .catch(AzureStorage.azureErrorHandler); } + // NOTE: This method is not implemented for azure storage public getAppOwnershipCount(accountId: string): Promise { return Promise.reject( @@ -325,25 +326,6 @@ export class AzureStorage implements storage.Storage { ); } - // NOTE: Terms acceptance methods - stubs for Azure (not implemented) - public getTermsAcceptance(accountId: string): Promise { - return Promise.reject( - storage.storageError( - storage.ErrorCode.Other, - "AzureStorage is not configured. Please use S3Storage or JsonStorage." - ) - ); - } - - public addOrUpdateTermsAcceptance(termsAcceptance: storage.TermsAcceptance): Promise { - return Promise.reject( - storage.storageError( - storage.ErrorCode.Other, - "AzureStorage is not configured. Please use S3Storage or JsonStorage." - ) - ); - } - public getAccountIdFromAccessKey(accessKey: string): Promise { const partitionKey: string = Keys.getShortcutAccessKeyPartitionKey(accessKey); const rowKey: string = ""; diff --git a/api/script/storage/json-storage.ts b/api/script/storage/json-storage.ts index 560cce0..0c8bc22 100644 --- a/api/script/storage/json-storage.ts +++ b/api/script/storage/json-storage.ts @@ -44,7 +44,6 @@ export class JsonStorage implements storage.Storage { public packages: { [id: string]: storage.Package } = {}; public blobs: { [id: string]: string } = {}; public accessKeys: { [id: string]: storage.AccessKey } = {}; - public termsAcceptance: { [accountId: string]: storage.TermsAcceptance } = {}; public accountToAppsMap: { [id: string]: string[] } = {}; public appToAccountMap: { [id: string]: string } = {}; @@ -242,39 +241,6 @@ export class JsonStorage implements storage.Storage { }); } - // Terms acceptance methods - public getTermsAcceptance(accountId: string): Promise { - const termsRecord = this.termsAcceptance[accountId]; - if (!termsRecord) { - return JsonStorage.getRejectedPromise(storage.ErrorCode.NotFound); - } - return Promise.resolve(clone(termsRecord)); - } - - public addOrUpdateTermsAcceptance(termsAcceptance: storage.TermsAcceptance): Promise { - const existingRecord = this.termsAcceptance[termsAcceptance.accountId]; - - if (existingRecord) { - // Update existing record - existingRecord.termsVersion = termsAcceptance.termsVersion; - existingRecord.acceptedTime = termsAcceptance.acceptedTime; - this.saveStateAsync(); - return Promise.resolve(clone(existingRecord)); - } else { - // Create new record - const newRecord: storage.TermsAcceptance = { - id: termsAcceptance.id || this.newId(), - accountId: termsAcceptance.accountId, - email: termsAcceptance.email, - termsVersion: termsAcceptance.termsVersion, - acceptedTime: termsAcceptance.acceptedTime - }; - - this.termsAcceptance[termsAcceptance.accountId] = newRecord; - this.saveStateAsync(); - return Promise.resolve(clone(newRecord)); - } - } public getAccountIdFromAccessKey(accessKey: string): Promise { if (!this.accessKeyNameToAccountIdMap[accessKey]) { diff --git a/api/script/storage/storage.ts b/api/script/storage/storage.ts index c7bb937..61fc87c 100644 --- a/api/script/storage/storage.ts +++ b/api/script/storage/storage.ts @@ -73,13 +73,6 @@ export interface Organization { role: string; } -export interface TermsAcceptance { - /*generated*/ id?: string; - accountId: string; - email: string; - termsVersion: string; - acceptedTime: number; // Epoch timestamp -} export interface Deployment { /*generated*/ createdTime?: number; @@ -161,9 +154,6 @@ export interface Storage { updateAccount(email: string, updates: Account): Promise; getAppOwnershipCount(accountId: string): Promise; - // Terms acceptance methods - getTermsAcceptance(accountId: string): Promise; - addOrUpdateTermsAcceptance(termsAcceptance: TermsAcceptance): Promise; getTenants(accountId: string): Promise; removeTenant(accountId: string, tenantId: string): Promise;