1+ import { Inject , Injectable , OnModuleInit } from "@nestjs/common" ;
2+ import { Db , ObjectId } from "mongodb" ;
3+ import { v4 as uuidv4 } from "uuid" ;
4+ import { Collections } from "@src/modules/common/enum/database.collection.enum" ;
5+
6+ @Injectable ( )
7+ export class AuthToAuthProfilesMigration implements OnModuleInit {
8+ private hasRun = false ;
9+
10+ constructor ( @Inject ( "DATABASE_CONNECTION" ) private db : Db ) { }
11+
12+ async onModuleInit ( ) : Promise < void > {
13+ if ( this . hasRun ) return ;
14+
15+ try {
16+ console . log ( `\n\x1b[32m[Nest]\x1b[0m \x1b[32mRunning AuthToAuthProfilesMigration...` ) ;
17+
18+ const collection = this . db . collection ( Collections . COLLECTION ) ;
19+
20+ const documents = await collection
21+ . find ( {
22+ $or : [
23+ { auth : { $type : "object" } , "auth.0" : { $exists : false } } , // Valid auth object (not array)
24+ { auth : { $exists : false } } , // No auth field
25+ { auth : null } , // Null auth
26+ ] ,
27+ } )
28+ . toArray ( ) ;
29+
30+ if ( documents . length === 0 ) {
31+ console . log ( "No documents needing authProfiles migration." ) ;
32+ this . hasRun = true ;
33+ return ;
34+ }
35+
36+ const now = new Date ( ) ;
37+
38+ for ( const doc of documents ) {
39+ const authObject = doc . auth ;
40+
41+ // Case 1: auth is missing or invalid
42+ if ( ! authObject || typeof authObject !== "object" || Array . isArray ( authObject ) ) {
43+ const update : any = { } ;
44+
45+ if ( ! Array . isArray ( doc . authProfiles ) ) {
46+ update . $set = { authProfiles : [ ] } ;
47+
48+ await collection . updateOne (
49+ { _id : new ObjectId ( doc . _id ) } ,
50+ update
51+ ) ;
52+
53+ console . log ( `Set empty authProfiles for document: ${ doc . _id } ` ) ;
54+ } else {
55+ console . log ( `authProfiles already exists for document: ${ doc . _id } ` ) ;
56+ }
57+
58+ continue ;
59+ }
60+
61+ // Case 2: auth is a valid object, migrate to authProfiles
62+ let authType = "" ;
63+ const { bearerToken, basicAuth = { } , apiKey = { } } = authObject ;
64+
65+ const hasBearer = bearerToken && bearerToken . trim ( ) !== "" ;
66+ const hasBasic = basicAuth . username ?. trim ( ) || basicAuth . password ?. trim ( ) ;
67+ const hasApiKey = apiKey . authKey ?. trim ( ) || apiKey . authValue ?. trim ( ) ;
68+
69+ if ( hasBearer ) {
70+ authType = "Bearer Token" ;
71+ } else if ( hasBasic ) {
72+ authType = "Basic Auth" ;
73+ } else if ( hasApiKey ) {
74+ authType = "API Key" ;
75+ } else {
76+ console . warn ( `Skipping ${ doc . _id } : no valid auth data.` ) ;
77+ continue ;
78+ }
79+
80+ const newAuthProfile = {
81+ name : "New-Auth-Profile" ,
82+ description : "" ,
83+ authType,
84+ auth : {
85+ bearerToken : bearerToken || "" ,
86+ basicAuth : {
87+ username : basicAuth . username || "" ,
88+ password : basicAuth . password || "" ,
89+ } ,
90+ apiKey : {
91+ authKey : apiKey . authKey || "" ,
92+ authValue : apiKey . authValue || "" ,
93+ addTo : apiKey . addTo || "Header" ,
94+ } ,
95+ } ,
96+ defaultKey : false ,
97+ createdAt : now ,
98+ authId : uuidv4 ( ) ,
99+ } ;
100+
101+ const update : any = { } ;
102+
103+ if ( Array . isArray ( doc . authProfiles ) ) {
104+ update . $push = { authProfiles : newAuthProfile } ;
105+ } else {
106+ update . $set = { authProfiles : [ newAuthProfile ] } ;
107+ }
108+
109+ await collection . updateOne (
110+ { _id : new ObjectId ( doc . _id ) } ,
111+ update
112+ ) ;
113+
114+ console . log ( `Updated authProfiles for document: ${ doc . _id } ` ) ;
115+ }
116+
117+ console . log ( `Migration completed. Total processed: ${ documents . length } ` ) ;
118+ this . hasRun = true ;
119+ } catch ( error ) {
120+ console . error ( "Error during AuthToAuthProfilesMigration:" , error ) ;
121+ }
122+ }
123+ }
0 commit comments