@@ -50,7 +50,7 @@ async function readPuterFile(actor, filePath) {
5050 stream . on ( "data" , ( data ) => {
5151 chunks . push ( data )
5252 bytes += data . byteLength
53- if ( bytes > 10 ** 7 ) {
53+ if ( bytes > 10 ** 7 ) {
5454 const err = Error ( "Worker source code must not exceed 10MB" ) ;
5555 stream . emit ( "error" , err ) ;
5656 throw err ;
@@ -82,100 +82,102 @@ const PREAMBLE_LENGTH = preamble.split("\n").length - 1
8282class WorkerService extends BaseService {
8383 _init ( ) {
8484 setCloudflareKeys ( this . config ) ;
85-
85+
8686 // Services used
8787 const svc_event = this . services . get ( 'event' ) ;
8888 const svc_su = this . services . get ( "su" ) ;
8989 const es_subdomain = this . services . get ( 'es:subdomain' ) ;
9090 const svc_auth = this . services . get ( "auth" ) ;
9191 const svc_notification = this . services . get ( 'notification' ) ;
92-
92+
9393 svc_event . on ( 'fs.written.file' , async ( _key , data , meta ) => {
9494 // Code should only run on the same server as the write
9595 if ( meta . from_outside ) return ;
9696
9797 // Check if the file that was written correlates to a worker
98- const result = await svc_su . sudo ( async ( ) => {
98+ const results = await svc_su . sudo ( async ( ) => {
9999 return await es_subdomain . select ( { predicate : new Eq ( { key : "root_dir" , value : data . node } ) } ) ;
100100 } ) ;
101- if ( ! result || result . length === 0 )
101+ if ( ! results || results . length === 0 )
102102 return ;
103103
104- // Person who just wrote file (not necessarily file owner)
105- const actor = Context . get ( "actor" ) ;
106-
107- // Worker data
108- const fileData = ( await readPuterFile ( Context . get ( "actor" ) , data . node . path ) ) . toString ( ) ;
109- const workerName = ( await result [ 0 ] . get ( "subdomain" ) ) . split ( "." ) . pop ( ) ;
110-
111- // Get appropriate deploy time auth token to give to the worker
112- let authToken ;
113- const appOwner = await result [ 0 ] . get ( "app_owner" ) ;
114- if ( appOwner ) { // If the deployer is an app...
115- const appID = await appOwner . get ( "uid" ) ;
116- authToken = await svc_su . sudo ( await data . node . get ( "owner" ) , async ( ) => {
117- return await svc_auth . get_user_app_token ( appID ) ;
118- } )
119- } else { // If the deployer is not attached to any application
120- authToken = ( await svc_auth . create_session_token ( ( await data . node . get ( "owner" ) ) . type . user ) ) . token
121- }
122-
123-
124- // svc_notification.notify(
125- // UsernameNotifSelector(actor.type.user.username),
126- // {
127- // source: 'worker',
128- // title: `Deploying CF worker ${workerName}`,
129- // template: 'user-requesting-share',
130- // fields: {
131- // username: actor.type.user.username,
132- // },
133- // }
134- // );
135- try {
136- // Create the worker
137- const cfData = await createWorker ( ( await data . node . get ( "owner" ) ) . type . user , authToken , workerName , preamble + fileData , PREAMBLE_LENGTH ) ;
138-
139- // Send user the appropriate notification
140- if ( cfData . success ) {
141- // svc_notification.notify(
142- // UsernameNotifSelector(actor.type.user.username),
143- // {
144- // source: 'worker',
145- // title: `Succesfully deployed ${cfData.url}`,
146- // template: 'user-requesting-share',
147- // fields: {
148- // username: actor.type.user.username,
149- // },
150- // }
151- // );
152- } else {
104+ for ( const result of results ) {
105+ // Person who just wrote file (not necessarily file owner)
106+ const actor = Context . get ( "actor" ) ;
107+
108+ // Worker data
109+ const fileData = ( await readPuterFile ( Context . get ( "actor" ) , data . node . path ) ) . toString ( ) ;
110+ const workerName = ( await result . get ( "subdomain" ) ) . split ( "." ) . pop ( ) ;
111+
112+ // Get appropriate deploy time auth token to give to the worker
113+ let authToken ;
114+ const appOwner = await result . get ( "app_owner" ) ;
115+ if ( appOwner ) { // If the deployer is an app...
116+ const appID = await appOwner . get ( "uid" ) ;
117+ authToken = await svc_su . sudo ( await data . node . get ( "owner" ) , async ( ) => {
118+ return await svc_auth . get_user_app_token ( appID ) ;
119+ } )
120+ } else { // If the deployer is not attached to any application
121+ authToken = ( await svc_auth . create_session_token ( ( await data . node . get ( "owner" ) ) . type . user ) ) . token
122+ }
123+
124+
125+ // svc_notification.notify(
126+ // UsernameNotifSelector(actor.type.user.username),
127+ // {
128+ // source: 'worker',
129+ // title: `Deploying CF worker ${workerName}`,
130+ // template: 'user-requesting-share',
131+ // fields: {
132+ // username: actor.type.user.username,
133+ // },
134+ // }
135+ // );
136+ try {
137+ // Create the worker
138+ const cfData = await createWorker ( ( await data . node . get ( "owner" ) ) . type . user , authToken , workerName , preamble + fileData , PREAMBLE_LENGTH ) ;
139+
140+ // Send user the appropriate notification
141+ if ( cfData . success ) {
142+ // svc_notification.notify(
143+ // UsernameNotifSelector(actor.type.user.username),
144+ // {
145+ // source: 'worker',
146+ // title: `Succesfully deployed ${cfData.url}`,
147+ // template: 'user-requesting-share',
148+ // fields: {
149+ // username: actor.type.user.username,
150+ // },
151+ // }
152+ // );
153+ } else {
154+ svc_notification . notify (
155+ UsernameNotifSelector ( actor . type . user . username ) ,
156+ {
157+ source : 'worker' ,
158+ title : `Failed to deploy ${ workerName } ! ${ cfData . errors } ` ,
159+ template : 'user-requesting-share' ,
160+ fields : {
161+ username : actor . type . user . username ,
162+ } ,
163+ }
164+ ) ;
165+ }
166+
167+
168+ } catch ( e ) {
153169 svc_notification . notify (
154170 UsernameNotifSelector ( actor . type . user . username ) ,
155171 {
156172 source : 'worker' ,
157- title : `Failed to deploy ${ workerName } ! ${ cfData . errors } ` ,
173+ title : `Failed to deploy ${ workerName } !!\n ${ e } ` ,
158174 template : 'user-requesting-share' ,
159175 fields : {
160176 username : actor . type . user . username ,
161177 } ,
162178 }
163179 ) ;
164180 }
165-
166-
167- } catch ( e ) {
168- svc_notification . notify (
169- UsernameNotifSelector ( actor . type . user . username ) ,
170- {
171- source : 'worker' ,
172- title : `Failed to deploy ${ workerName } !!\n ${ e } ` ,
173- template : 'user-requesting-share' ,
174- fields : {
175- username : actor . type . user . username ,
176- } ,
177- }
178- ) ;
179181 }
180182 } ) ;
181183 }
@@ -189,7 +191,14 @@ class WorkerService extends BaseService {
189191 async create ( { filePath, workerName, authorization } ) {
190192 try {
191193 workerName = workerName . toLocaleLowerCase ( ) ; // just incase
192- if ( ! ( / ^ [ a - z A - Z 0 - 9 _ - ] + $ / . test ( workerName ) ) ) return ;
194+
195+ if ( this . global_config . reserved_words . includes ( workerName ) ) {
196+ return APIError . create ( 'subdomain_reserved' , null , {
197+ subdomain : workerName ,
198+ } ) ;
199+ }
200+
201+ if ( ! ( / ^ [ a - z A - Z 0 - 9 _ - ] + $ / . test ( workerName ) ) ) return ;
193202
194203 filePath = await ( await ( new FSNodeParam ( 'path' ) ) . consolidate ( {
195204 req : { user : Context . get ( "actor" ) . type . user } ,
@@ -206,11 +215,11 @@ class WorkerService extends BaseService {
206215 } ) ;
207216 await es_subdomain . upsert ( entity ) ;
208217 } ) ;
209-
218+
210219 const fileData = ( await readPuterFile ( actor , filePath ) ) . toString ( ) ;
211220 const cfData = await createWorker ( userData , authorization , calculateWorkerNameNew ( userData . uuid , workerName ) , preamble + fileData , PREAMBLE_LENGTH ) ;
212221
213-
222+
214223 return cfData ;
215224 } catch ( e ) {
216225 if ( e instanceof APIError )
0 commit comments