2018-09-01 13:58:06 -04:00
import { Parse } from 'parse/node' ;
2016-02-25 20:01:52 -08:00
import * as triggers from '../triggers' ;
2021-10-09 14:04:12 +11:00
import Deprecator from '../Deprecator/Deprecator' ;
2023-01-06 23:39:02 +11:00
import { addRateLimit } from '../middlewares' ;
2020-12-31 03:23:44 +11:00
const Config = require ( '../Config' ) ;
2016-02-05 14:38:09 -05:00
2019-04-23 16:24:20 +01:00
function isParseObjectConstructor ( object ) {
2020-10-25 15:06:58 -05:00
return typeof object === 'function' && Object . prototype . hasOwnProperty . call ( object , 'className' ) ;
2019-04-23 16:24:20 +01:00
}
2021-03-02 10:52:21 +11:00
function validateValidator ( validator ) {
if ( ! validator || typeof validator === 'function' ) {
return ;
}
const fieldOptions = {
type : [ 'Any' ] ,
constant : [ Boolean ] ,
default : [ 'Any' ] ,
options : [ Array , 'function' , 'Any' ] ,
required : [ Boolean ] ,
error : [ String ] ,
} ;
const allowedKeys = {
requireUser : [ Boolean ] ,
requireAnyUserRoles : [ Array , 'function' ] ,
requireAllUserRoles : [ Array , 'function' ] ,
requireMaster : [ Boolean ] ,
validateMasterKey : [ Boolean ] ,
skipWithMasterKey : [ Boolean ] ,
requireUserKeys : [ Array , Object ] ,
fields : [ Array , Object ] ,
2023-01-06 23:39:02 +11:00
rateLimit : [ Object ] ,
2021-03-02 10:52:21 +11:00
} ;
const getType = fn => {
if ( Array . isArray ( fn ) ) {
return 'array' ;
}
if ( fn === 'Any' || fn === 'function' ) {
return fn ;
}
const type = typeof fn ;
if ( typeof fn === 'function' ) {
const match = fn && fn . toString ( ) . match ( /^\s*function (\w+)/ ) ;
return ( match ? match [ 1 ] : 'function' ) . toLowerCase ( ) ;
}
return type ;
} ;
const checkKey = ( key , data , validatorParam ) => {
const parameter = data [ key ] ;
if ( ! parameter ) {
throw ` ${ key } is not a supported parameter for Cloud Function validations. ` ;
}
const types = parameter . map ( type => getType ( type ) ) ;
const type = getType ( validatorParam ) ;
if ( ! types . includes ( type ) && ! types . includes ( 'Any' ) ) {
throw ` Invalid type for Cloud Function validation key ${ key } . Expected ${ types . join (
'|'
) } , actual $ { type } ` ;
}
} ;
for ( const key in validator ) {
checkKey ( key , allowedKeys , validator [ key ] ) ;
if ( key === 'fields' || key === 'requireUserKeys' ) {
const values = validator [ key ] ;
if ( Array . isArray ( values ) ) {
continue ;
}
for ( const value in values ) {
const data = values [ value ] ;
for ( const subKey in data ) {
checkKey ( subKey , fieldOptions , data [ subKey ] ) ;
}
}
}
}
}
2023-01-06 23:39:02 +11:00
const getRoute = parseClass => {
const route =
{
_User : 'users' ,
_Session : 'sessions' ,
'@File' : 'files' ,
} [ parseClass ] || 'classes' ;
if ( parseClass === '@File' ) {
2023-05-23 00:39:32 +10:00
return ` / ${ route } /:id?(.*) ` ;
2023-01-06 23:39:02 +11:00
}
2023-05-23 00:39:32 +10:00
return ` / ${ route } / ${ parseClass } /:id?(.*) ` ;
2023-01-06 23:39:02 +11:00
} ;
2018-08-09 16:20:13 -04:00
/ * * @ n a m e s p a c e
* @ name Parse
* @ description The Parse SDK .
* see [ api docs ] ( https : //docs.parseplatform.org/js/api) and [guide](https://docs.parseplatform.org/js/guide)
* /
/ * * @ n a m e s p a c e
* @ name Parse . Cloud
* @ memberof Parse
* @ description The Parse Cloud Code SDK .
* /
2016-02-05 14:38:09 -05:00
var ParseCloud = { } ;
2018-08-09 16:20:13 -04:00
/ * *
* Defines a Cloud Function .
*
* * * Available in Cloud Code only . * *
2020-10-26 04:36:54 +11:00
*
* ` ` `
* Parse . Cloud . define ( 'functionName' , ( request ) => {
* // code here
* } , ( request ) => {
* // validation code here
* } ) ;
*
* Parse . Cloud . define ( 'functionName' , ( request ) => {
* // code here
* } , { ... validationObject } ) ;
* ` ` `
*
2018-08-09 16:20:13 -04:00
* @ static
* @ memberof Parse . Cloud
* @ param { String } name The name of the Cloud Function
* @ param { Function } data The Cloud Function to register . This function can be an async function and should take one parameter a { @ link Parse . Cloud . FunctionRequest } .
2020-10-26 04:36:54 +11:00
* @ param { ( Object | Function ) } validator An optional function to help validating cloud code . This function can be an async function and should take one parameter a { @ link Parse . Cloud . FunctionRequest } , or a { @ link Parse . Cloud . ValidatorObject } .
2018-08-09 16:20:13 -04:00
* /
2020-07-13 13:06:52 -05:00
ParseCloud . define = function ( functionName , handler , validationHandler ) {
2021-03-02 10:52:21 +11:00
validateValidator ( validationHandler ) ;
2020-10-25 15:06:58 -05:00
triggers . addFunction ( functionName , handler , validationHandler , Parse . applicationId ) ;
2023-01-06 23:39:02 +11:00
if ( validationHandler && validationHandler . rateLimit ) {
addRateLimit (
{ requestPath : ` /functions/ ${ functionName } ` , ... validationHandler . rateLimit } ,
2023-03-11 09:54:05 +11:00
Parse . applicationId ,
true
2023-01-06 23:39:02 +11:00
) ;
}
2016-02-05 14:38:09 -05:00
} ;
2018-08-09 16:20:13 -04:00
/ * *
* Defines a Background Job .
*
* * * Available in Cloud Code only . * *
*
* @ method job
* @ name Parse . Cloud . job
* @ param { String } name The name of the Background Job
* @ param { Function } func The Background Job to register . This function can be async should take a single parameters a { @ link Parse . Cloud . JobRequest }
*
* /
2020-07-13 13:06:52 -05:00
ParseCloud . job = function ( functionName , handler ) {
2016-08-30 07:19:21 -04:00
triggers . addJob ( functionName , handler , Parse . applicationId ) ;
} ;
2018-08-09 16:20:13 -04:00
/ * *
*
* Registers a before save function .
*
* * * Available in Cloud Code only . * *
*
2022-05-30 04:48:55 +10:00
* If you want to use beforeSave for a predefined class in the Parse JavaScript SDK ( e . g . { @ link Parse . User } or { @ link Parse . File } ) , you should pass the class itself and not the String for arg1 .
2018-08-09 16:20:13 -04:00
*
* ` ` `
* Parse . Cloud . beforeSave ( 'MyCustomClass' , ( request ) => {
* // code here
2020-10-26 04:36:54 +11:00
* } , ( request ) => {
* // validation code here
* } ) ;
2018-08-09 16:20:13 -04:00
*
* Parse . Cloud . beforeSave ( Parse . User , ( request ) => {
* // code here
2020-10-26 04:36:54 +11:00
* } , { ... validationObject } )
2018-08-09 16:20:13 -04:00
* ` ` `
*
* @ method beforeSave
* @ name Parse . Cloud . beforeSave
* @ param { ( String | Parse . Object ) } arg1 The Parse . Object subclass to register the after save function for . This can instead be a String that is the className of the subclass .
* @ param { Function } func The function to run before a save . This function can be async and should take one parameter a { @ link Parse . Cloud . TriggerRequest } ;
2020-10-26 04:36:54 +11:00
* @ param { ( Object | Function ) } validator An optional function to help validating cloud code . This function can be an async function and should take one parameter a { @ link Parse . Cloud . TriggerRequest } , or a { @ link Parse . Cloud . ValidatorObject } .
2018-08-09 16:20:13 -04:00
* /
2020-10-26 04:36:54 +11:00
ParseCloud . beforeSave = function ( parseClass , handler , validationHandler ) {
2021-10-09 02:24:33 +11:00
const className = triggers . getClassName ( parseClass ) ;
2021-03-02 10:52:21 +11:00
validateValidator ( validationHandler ) ;
2018-09-01 13:58:06 -04:00
triggers . addTrigger (
triggers . Types . beforeSave ,
className ,
handler ,
2020-10-26 04:36:54 +11:00
Parse . applicationId ,
validationHandler
2018-09-01 13:58:06 -04:00
) ;
2023-01-06 23:39:02 +11:00
if ( validationHandler && validationHandler . rateLimit ) {
addRateLimit (
{
requestPath : getRoute ( className ) ,
requestMethods : [ 'POST' , 'PUT' ] ,
... validationHandler . rateLimit ,
} ,
2023-03-11 09:54:05 +11:00
Parse . applicationId ,
true
2023-01-06 23:39:02 +11:00
) ;
}
2016-02-05 14:38:09 -05:00
} ;
2018-08-09 16:20:13 -04:00
/ * *
* Registers a before delete function .
*
* * * Available in Cloud Code only . * *
*
2022-05-30 04:48:55 +10:00
* If you want to use beforeDelete for a predefined class in the Parse JavaScript SDK ( e . g . { @ link Parse . User } or { @ link Parse . File } ) , you should pass the class itself and not the String for arg1 .
2018-08-09 16:20:13 -04:00
* ` ` `
* Parse . Cloud . beforeDelete ( 'MyCustomClass' , ( request ) => {
* // code here
2020-10-26 04:36:54 +11:00
* } , ( request ) => {
* // validation code here
* } ) ;
2018-08-09 16:20:13 -04:00
*
* Parse . Cloud . beforeDelete ( Parse . User , ( request ) => {
* // code here
2020-10-26 04:36:54 +11:00
* } , { ... validationObject } )
2018-08-09 16:20:13 -04:00
* ` ` `
*
* @ method beforeDelete
* @ name Parse . Cloud . beforeDelete
* @ param { ( String | Parse . Object ) } arg1 The Parse . Object subclass to register the before delete function for . This can instead be a String that is the className of the subclass .
* @ param { Function } func The function to run before a delete . This function can be async and should take one parameter , a { @ link Parse . Cloud . TriggerRequest } .
2020-10-26 04:36:54 +11:00
* @ param { ( Object | Function ) } validator An optional function to help validating cloud code . This function can be an async function and should take one parameter a { @ link Parse . Cloud . TriggerRequest } , or a { @ link Parse . Cloud . ValidatorObject } .
2018-08-09 16:20:13 -04:00
* /
2020-10-26 04:36:54 +11:00
ParseCloud . beforeDelete = function ( parseClass , handler , validationHandler ) {
2021-10-09 02:24:33 +11:00
const className = triggers . getClassName ( parseClass ) ;
2021-03-02 10:52:21 +11:00
validateValidator ( validationHandler ) ;
2018-09-01 13:58:06 -04:00
triggers . addTrigger (
triggers . Types . beforeDelete ,
className ,
handler ,
2020-10-26 04:36:54 +11:00
Parse . applicationId ,
validationHandler
2018-09-01 13:58:06 -04:00
) ;
2023-01-06 23:39:02 +11:00
if ( validationHandler && validationHandler . rateLimit ) {
addRateLimit (
{
requestPath : getRoute ( className ) ,
requestMethods : 'DELETE' ,
... validationHandler . rateLimit ,
} ,
2023-03-11 09:54:05 +11:00
Parse . applicationId ,
true
2023-01-06 23:39:02 +11:00
) ;
}
2016-02-05 14:38:09 -05:00
} ;
2019-04-23 16:24:20 +01:00
/ * *
*
* Registers the before login function .
*
* * * Available in Cloud Code only . * *
*
* This function provides further control
* in validating a login attempt . Specifically ,
* it is triggered after a user enters
* correct credentials ( or other valid authData ) ,
* but prior to a session being generated .
*
* ` ` `
* Parse . Cloud . beforeLogin ( ( request ) => {
* // code here
* } )
*
* ` ` `
*
* @ method beforeLogin
* @ name Parse . Cloud . beforeLogin
* @ param { Function } func The function to run before a login . This function can be async and should take one parameter a { @ link Parse . Cloud . TriggerRequest } ;
* /
2023-01-06 23:39:02 +11:00
ParseCloud . beforeLogin = function ( handler , validationHandler ) {
2019-04-23 16:24:20 +01:00
let className = '_User' ;
if ( typeof handler === 'string' || isParseObjectConstructor ( handler ) ) {
// validation will occur downstream, this is to maintain internal
// code consistency with the other hook types.
2021-10-09 02:24:33 +11:00
className = triggers . getClassName ( handler ) ;
2019-04-23 16:24:20 +01:00
handler = arguments [ 1 ] ;
2023-01-06 23:39:02 +11:00
validationHandler = arguments . length >= 2 ? arguments [ 2 ] : null ;
2019-04-23 16:24:20 +01:00
}
2020-10-25 15:06:58 -05:00
triggers . addTrigger ( triggers . Types . beforeLogin , className , handler , Parse . applicationId ) ;
2023-01-06 23:39:02 +11:00
if ( validationHandler && validationHandler . rateLimit ) {
addRateLimit (
{ requestPath : ` /login ` , requestMethods : 'POST' , ... validationHandler . rateLimit } ,
2023-03-11 09:54:05 +11:00
Parse . applicationId ,
true
2023-01-06 23:39:02 +11:00
) ;
}
2019-04-23 16:24:20 +01:00
} ;
2020-02-11 17:38:14 -06:00
/ * *
*
* Registers the after login function .
*
* * * Available in Cloud Code only . * *
*
* This function is triggered after a user logs in successfully ,
* and after a _Session object has been created .
*
* ` ` `
* Parse . Cloud . afterLogin ( ( request ) => {
* // code here
2020-10-26 04:36:54 +11:00
* } ) ;
2020-02-11 17:38:14 -06:00
* ` ` `
*
* @ method afterLogin
* @ name Parse . Cloud . afterLogin
* @ param { Function } func The function to run after a login . This function can be async and should take one parameter a { @ link Parse . Cloud . TriggerRequest } ;
* /
2020-07-13 13:06:52 -05:00
ParseCloud . afterLogin = function ( handler ) {
2020-02-11 17:38:14 -06:00
let className = '_User' ;
if ( typeof handler === 'string' || isParseObjectConstructor ( handler ) ) {
// validation will occur downstream, this is to maintain internal
// code consistency with the other hook types.
2021-10-09 02:24:33 +11:00
className = triggers . getClassName ( handler ) ;
2020-02-11 17:38:14 -06:00
handler = arguments [ 1 ] ;
}
2020-10-25 15:06:58 -05:00
triggers . addTrigger ( triggers . Types . afterLogin , className , handler , Parse . applicationId ) ;
2020-02-11 17:38:14 -06:00
} ;
2019-11-16 04:52:57 +01:00
/ * *
*
* Registers the after logout function .
*
* * * Available in Cloud Code only . * *
*
* This function is triggered after a user logs out .
*
* ` ` `
* Parse . Cloud . afterLogout ( ( request ) => {
* // code here
2020-10-26 04:36:54 +11:00
* } ) ;
2019-11-16 04:52:57 +01:00
* ` ` `
*
* @ method afterLogout
* @ name Parse . Cloud . afterLogout
* @ param { Function } func The function to run after a logout . This function can be async and should take one parameter a { @ link Parse . Cloud . TriggerRequest } ;
* /
2020-07-13 13:06:52 -05:00
ParseCloud . afterLogout = function ( handler ) {
2019-11-16 04:52:57 +01:00
let className = '_Session' ;
if ( typeof handler === 'string' || isParseObjectConstructor ( handler ) ) {
// validation will occur downstream, this is to maintain internal
// code consistency with the other hook types.
2021-10-09 02:24:33 +11:00
className = triggers . getClassName ( handler ) ;
2019-11-16 04:52:57 +01:00
handler = arguments [ 1 ] ;
}
2020-10-25 15:06:58 -05:00
triggers . addTrigger ( triggers . Types . afterLogout , className , handler , Parse . applicationId ) ;
2019-11-16 04:52:57 +01:00
} ;
2018-08-09 16:20:13 -04:00
/ * *
* Registers an after save function .
*
* * * Available in Cloud Code only . * *
*
2022-05-30 04:48:55 +10:00
* If you want to use afterSave for a predefined class in the Parse JavaScript SDK ( e . g . { @ link Parse . User } or { @ link Parse . File } ) , you should pass the class itself and not the String for arg1 .
2018-08-09 16:20:13 -04:00
*
* ` ` `
* Parse . Cloud . afterSave ( 'MyCustomClass' , async function ( request ) {
* // code here
2020-10-26 04:36:54 +11:00
* } , ( request ) => {
* // validation code here
* } ) ;
2018-08-09 16:20:13 -04:00
*
* Parse . Cloud . afterSave ( Parse . User , async function ( request ) {
* // code here
2020-10-26 04:36:54 +11:00
* } , { ... validationObject } ) ;
2018-08-09 16:20:13 -04:00
* ` ` `
*
* @ method afterSave
* @ name Parse . Cloud . afterSave
* @ param { ( String | Parse . Object ) } arg1 The Parse . Object subclass to register the after save function for . This can instead be a String that is the className of the subclass .
* @ param { Function } func The function to run after a save . This function can be an async function and should take just one parameter , { @ link Parse . Cloud . TriggerRequest } .
2020-10-26 04:36:54 +11:00
* @ param { ( Object | Function ) } validator An optional function to help validating cloud code . This function can be an async function and should take one parameter a { @ link Parse . Cloud . TriggerRequest } , or a { @ link Parse . Cloud . ValidatorObject } .
2018-08-09 16:20:13 -04:00
* /
2020-10-26 04:36:54 +11:00
ParseCloud . afterSave = function ( parseClass , handler , validationHandler ) {
2021-10-09 02:24:33 +11:00
const className = triggers . getClassName ( parseClass ) ;
2021-03-02 10:52:21 +11:00
validateValidator ( validationHandler ) ;
2018-09-01 13:58:06 -04:00
triggers . addTrigger (
triggers . Types . afterSave ,
className ,
handler ,
2020-10-26 04:36:54 +11:00
Parse . applicationId ,
validationHandler
2018-09-01 13:58:06 -04:00
) ;
2016-02-05 14:38:09 -05:00
} ;
2018-08-09 16:20:13 -04:00
/ * *
* Registers an after delete function .
*
* * * Available in Cloud Code only . * *
*
2022-05-30 04:48:55 +10:00
* If you want to use afterDelete for a predefined class in the Parse JavaScript SDK ( e . g . { @ link Parse . User } or { @ link Parse . File } ) , you should pass the class itself and not the String for arg1 .
2018-08-09 16:20:13 -04:00
* ` ` `
* Parse . Cloud . afterDelete ( 'MyCustomClass' , async ( request ) => {
* // code here
2020-10-26 04:36:54 +11:00
* } , ( request ) => {
* // validation code here
* } ) ;
2018-08-09 16:20:13 -04:00
*
* Parse . Cloud . afterDelete ( Parse . User , async ( request ) => {
* // code here
2020-10-26 04:36:54 +11:00
* } , { ... validationObject } ) ;
2018-08-09 16:20:13 -04:00
* ` ` `
*
* @ method afterDelete
* @ name Parse . Cloud . afterDelete
* @ param { ( String | Parse . Object ) } arg1 The Parse . Object subclass to register the after delete function for . This can instead be a String that is the className of the subclass .
* @ param { Function } func The function to run after a delete . This function can be async and should take just one parameter , { @ link Parse . Cloud . TriggerRequest } .
2020-10-26 04:36:54 +11:00
* @ param { ( Object | Function ) } validator An optional function to help validating cloud code . This function can be an async function and should take one parameter a { @ link Parse . Cloud . TriggerRequest } , or a { @ link Parse . Cloud . ValidatorObject } .
2018-08-09 16:20:13 -04:00
* /
2020-10-26 04:36:54 +11:00
ParseCloud . afterDelete = function ( parseClass , handler , validationHandler ) {
2021-10-09 02:24:33 +11:00
const className = triggers . getClassName ( parseClass ) ;
2021-03-02 10:52:21 +11:00
validateValidator ( validationHandler ) ;
2018-09-01 13:58:06 -04:00
triggers . addTrigger (
triggers . Types . afterDelete ,
className ,
handler ,
2020-10-26 04:36:54 +11:00
Parse . applicationId ,
validationHandler
2018-09-01 13:58:06 -04:00
) ;
2016-02-05 14:38:09 -05:00
} ;
2016-05-19 13:38:16 -07:00
2018-08-09 16:20:13 -04:00
/ * *
* Registers a before find function .
*
* * * Available in Cloud Code only . * *
*
2022-05-30 04:48:55 +10:00
* If you want to use beforeFind for a predefined class in the Parse JavaScript SDK ( e . g . { @ link Parse . User } or { @ link Parse . File } ) , you should pass the class itself and not the String for arg1 .
2018-08-09 16:20:13 -04:00
* ` ` `
* Parse . Cloud . beforeFind ( 'MyCustomClass' , async ( request ) => {
* // code here
2020-10-26 04:36:54 +11:00
* } , ( request ) => {
* // validation code here
* } ) ;
2018-08-09 16:20:13 -04:00
*
* Parse . Cloud . beforeFind ( Parse . User , async ( request ) => {
* // code here
2020-10-26 04:36:54 +11:00
* } , { ... validationObject } ) ;
2018-08-09 16:20:13 -04:00
* ` ` `
*
* @ method beforeFind
* @ name Parse . Cloud . beforeFind
* @ param { ( String | Parse . Object ) } arg1 The Parse . Object subclass to register the before find function for . This can instead be a String that is the className of the subclass .
* @ param { Function } func The function to run before a find . This function can be async and should take just one parameter , { @ link Parse . Cloud . BeforeFindRequest } .
2020-10-26 04:36:54 +11:00
* @ param { ( Object | Function ) } validator An optional function to help validating cloud code . This function can be an async function and should take one parameter a { @ link Parse . Cloud . BeforeFindRequest } , or a { @ link Parse . Cloud . ValidatorObject } .
2018-08-09 16:20:13 -04:00
* /
2020-10-26 04:36:54 +11:00
ParseCloud . beforeFind = function ( parseClass , handler , validationHandler ) {
2021-10-09 02:24:33 +11:00
const className = triggers . getClassName ( parseClass ) ;
2021-03-02 10:52:21 +11:00
validateValidator ( validationHandler ) ;
2018-09-01 13:58:06 -04:00
triggers . addTrigger (
triggers . Types . beforeFind ,
className ,
handler ,
2020-10-26 04:36:54 +11:00
Parse . applicationId ,
validationHandler
2018-09-01 13:58:06 -04:00
) ;
2023-01-06 23:39:02 +11:00
if ( validationHandler && validationHandler . rateLimit ) {
addRateLimit (
{
requestPath : getRoute ( className ) ,
requestMethods : 'GET' ,
... validationHandler . rateLimit ,
} ,
2023-03-11 09:54:05 +11:00
Parse . applicationId ,
true
2023-01-06 23:39:02 +11:00
) ;
}
2016-09-17 16:52:35 -04:00
} ;
2018-08-09 16:20:13 -04:00
/ * *
* Registers an after find function .
*
* * * Available in Cloud Code only . * *
*
2022-05-30 04:48:55 +10:00
* If you want to use afterFind for a predefined class in the Parse JavaScript SDK ( e . g . { @ link Parse . User } or { @ link Parse . File } ) , you should pass the class itself and not the String for arg1 .
2018-08-09 16:20:13 -04:00
* ` ` `
* Parse . Cloud . afterFind ( 'MyCustomClass' , async ( request ) => {
* // code here
2020-10-26 04:36:54 +11:00
* } , ( request ) => {
* // validation code here
* } ) ;
2018-08-09 16:20:13 -04:00
*
* Parse . Cloud . afterFind ( Parse . User , async ( request ) => {
* // code here
2020-10-26 04:36:54 +11:00
* } , { ... validationObject } ) ;
2018-08-09 16:20:13 -04:00
* ` ` `
*
* @ method afterFind
* @ name Parse . Cloud . afterFind
* @ param { ( String | Parse . Object ) } arg1 The Parse . Object subclass to register the after find function for . This can instead be a String that is the className of the subclass .
* @ param { Function } func The function to run before a find . This function can be async and should take just one parameter , { @ link Parse . Cloud . AfterFindRequest } .
2020-10-26 04:36:54 +11:00
* @ param { ( Object | Function ) } validator An optional function to help validating cloud code . This function can be an async function and should take one parameter a { @ link Parse . Cloud . AfterFindRequest } , or a { @ link Parse . Cloud . ValidatorObject } .
2018-08-09 16:20:13 -04:00
* /
2020-10-26 04:36:54 +11:00
ParseCloud . afterFind = function ( parseClass , handler , validationHandler ) {
2021-10-09 02:24:33 +11:00
const className = triggers . getClassName ( parseClass ) ;
2021-03-02 10:52:21 +11:00
validateValidator ( validationHandler ) ;
2018-09-01 13:58:06 -04:00
triggers . addTrigger (
triggers . Types . afterFind ,
className ,
handler ,
2020-10-26 04:36:54 +11:00
Parse . applicationId ,
validationHandler
2018-09-01 13:58:06 -04:00
) ;
2016-11-12 09:35:34 -08:00
} ;
2020-04-02 17:00:15 -04:00
/ * *
* Registers a before save file function .
*
* * * Available in Cloud Code only . * *
*
* ` ` `
* Parse . Cloud . beforeSaveFile ( async ( request ) => {
* // code here
2020-10-26 04:36:54 +11:00
* } , ( request ) => {
* // validation code here
* } ) ;
*
* Parse . Cloud . beforeSaveFile ( async ( request ) => {
* // code here
* } , { ... validationObject } ) ;
2020-04-02 17:00:15 -04:00
* ` ` `
*
* @ method beforeSaveFile
2022-05-30 04:48:55 +10:00
* @ deprecated
2020-04-02 17:00:15 -04:00
* @ name Parse . Cloud . beforeSaveFile
* @ param { Function } func The function to run before saving a file . This function can be async and should take just one parameter , { @ link Parse . Cloud . FileTriggerRequest } .
2020-10-26 04:36:54 +11:00
* @ param { ( Object | Function ) } validator An optional function to help validating cloud code . This function can be an async function and should take one parameter a { @ link Parse . Cloud . FileTriggerRequest } , or a { @ link Parse . Cloud . ValidatorObject } .
2020-04-02 17:00:15 -04:00
* /
2020-10-26 04:36:54 +11:00
ParseCloud . beforeSaveFile = function ( handler , validationHandler ) {
2022-05-30 04:48:55 +10:00
Deprecator . logRuntimeDeprecation ( {
usage : 'Parse.Cloud.beforeSaveFile' ,
solution : 'Use Parse.Cloud.beforeSave(Parse.File, (request) => {})' ,
} ) ;
ParseCloud . beforeSave ( Parse . File , handler , validationHandler ) ;
2020-04-02 17:00:15 -04:00
} ;
/ * *
* Registers an after save file function .
*
* * * Available in Cloud Code only . * *
*
* ` ` `
* Parse . Cloud . afterSaveFile ( async ( request ) => {
* // code here
2020-10-26 04:36:54 +11:00
* } , ( request ) => {
* // validation code here
* } ) ;
*
* Parse . Cloud . afterSaveFile ( async ( request ) => {
* // code here
* } , { ... validationObject } ) ;
2020-04-02 17:00:15 -04:00
* ` ` `
*
* @ method afterSaveFile
2022-05-30 04:48:55 +10:00
* @ deprecated
2020-04-02 17:00:15 -04:00
* @ name Parse . Cloud . afterSaveFile
* @ param { Function } func The function to run after saving a file . This function can be async and should take just one parameter , { @ link Parse . Cloud . FileTriggerRequest } .
2020-10-26 04:36:54 +11:00
* @ param { ( Object | Function ) } validator An optional function to help validating cloud code . This function can be an async function and should take one parameter a { @ link Parse . Cloud . FileTriggerRequest } , or a { @ link Parse . Cloud . ValidatorObject } .
2020-04-02 17:00:15 -04:00
* /
2020-10-26 04:36:54 +11:00
ParseCloud . afterSaveFile = function ( handler , validationHandler ) {
2022-05-30 04:48:55 +10:00
Deprecator . logRuntimeDeprecation ( {
usage : 'Parse.Cloud.afterSaveFile' ,
solution : 'Use Parse.Cloud.afterSave(Parse.File, (request) => {})' ,
} ) ;
ParseCloud . afterSave ( Parse . File , handler , validationHandler ) ;
2020-04-02 17:00:15 -04:00
} ;
/ * *
* Registers a before delete file function .
*
* * * Available in Cloud Code only . * *
*
* ` ` `
* Parse . Cloud . beforeDeleteFile ( async ( request ) => {
* // code here
2020-10-26 04:36:54 +11:00
* } , ( request ) => {
* // validation code here
* } ) ;
*
* Parse . Cloud . beforeDeleteFile ( async ( request ) => {
* // code here
* } , { ... validationObject } ) ;
2020-04-02 17:00:15 -04:00
* ` ` `
*
* @ method beforeDeleteFile
2022-05-30 04:48:55 +10:00
* @ deprecated
2020-04-02 17:00:15 -04:00
* @ name Parse . Cloud . beforeDeleteFile
* @ param { Function } func The function to run before deleting a file . This function can be async and should take just one parameter , { @ link Parse . Cloud . FileTriggerRequest } .
2020-10-26 04:36:54 +11:00
* @ param { ( Object | Function ) } validator An optional function to help validating cloud code . This function can be an async function and should take one parameter a { @ link Parse . Cloud . FileTriggerRequest } , or a { @ link Parse . Cloud . ValidatorObject } .
2020-04-02 17:00:15 -04:00
* /
2020-10-26 04:36:54 +11:00
ParseCloud . beforeDeleteFile = function ( handler , validationHandler ) {
2022-05-30 04:48:55 +10:00
Deprecator . logRuntimeDeprecation ( {
usage : 'Parse.Cloud.beforeDeleteFile' ,
solution : 'Use Parse.Cloud.beforeDelete(Parse.File, (request) => {})' ,
} ) ;
ParseCloud . beforeDelete ( Parse . File , handler , validationHandler ) ;
2020-04-02 17:00:15 -04:00
} ;
/ * *
* Registers an after delete file function .
*
* * * Available in Cloud Code only . * *
*
* ` ` `
* Parse . Cloud . afterDeleteFile ( async ( request ) => {
* // code here
2020-10-26 04:36:54 +11:00
* } , ( request ) => {
* // validation code here
* } ) ;
*
* Parse . Cloud . afterDeleteFile ( async ( request ) => {
* // code here
* } , { ... validationObject } ) ;
2020-04-02 17:00:15 -04:00
* ` ` `
*
* @ method afterDeleteFile
2022-05-30 04:48:55 +10:00
* @ deprecated
2020-04-02 17:00:15 -04:00
* @ name Parse . Cloud . afterDeleteFile
* @ param { Function } func The function to after before deleting a file . This function can be async and should take just one parameter , { @ link Parse . Cloud . FileTriggerRequest } .
2020-10-26 04:36:54 +11:00
* @ param { ( Object | Function ) } validator An optional function to help validating cloud code . This function can be an async function and should take one parameter a { @ link Parse . Cloud . FileTriggerRequest } , or a { @ link Parse . Cloud . ValidatorObject } .
2020-04-02 17:00:15 -04:00
* /
2020-10-26 04:36:54 +11:00
ParseCloud . afterDeleteFile = function ( handler , validationHandler ) {
2022-05-30 04:48:55 +10:00
Deprecator . logRuntimeDeprecation ( {
usage : 'Parse.Cloud.afterDeleteFile' ,
solution : 'Use Parse.Cloud.afterDelete(Parse.File, (request) => {})' ,
} ) ;
ParseCloud . afterDelete ( Parse . File , handler , validationHandler ) ;
2020-04-02 17:00:15 -04:00
} ;
2020-07-17 11:36:38 +10:00
/ * *
* Registers a before live query server connect function .
*
* * * Available in Cloud Code only . * *
*
* ` ` `
* Parse . Cloud . beforeConnect ( async ( request ) => {
* // code here
2020-10-26 04:36:54 +11:00
* } , ( request ) => {
* // validation code here
* } ) ;
*
* Parse . Cloud . beforeConnect ( async ( request ) => {
* // code here
* } , { ... validationObject } ) ;
2020-07-17 11:36:38 +10:00
* ` ` `
*
* @ method beforeConnect
* @ name Parse . Cloud . beforeConnect
* @ param { Function } func The function to before connection is made . This function can be async and should take just one parameter , { @ link Parse . Cloud . ConnectTriggerRequest } .
2020-10-26 04:36:54 +11:00
* @ param { ( Object | Function ) } validator An optional function to help validating cloud code . This function can be an async function and should take one parameter a { @ link Parse . Cloud . ConnectTriggerRequest } , or a { @ link Parse . Cloud . ValidatorObject } .
2020-07-17 11:36:38 +10:00
* /
2020-10-26 04:36:54 +11:00
ParseCloud . beforeConnect = function ( handler , validationHandler ) {
2021-03-02 10:52:21 +11:00
validateValidator ( validationHandler ) ;
2020-07-17 11:36:38 +10:00
triggers . addConnectTrigger (
triggers . Types . beforeConnect ,
handler ,
2020-10-26 04:36:54 +11:00
Parse . applicationId ,
validationHandler
2020-07-17 11:36:38 +10:00
) ;
} ;
2020-12-31 03:23:44 +11:00
/ * *
* Sends an email through the Parse Server mail adapter .
*
* * * Available in Cloud Code only . * *
* * * Requires a mail adapter to be configured for Parse Server . * *
*
* ` ` `
* Parse . Cloud . sendEmail ( {
* from : 'Example <test@example.com>' ,
* to : 'contact@example.com' ,
* subject : 'Test email' ,
* text : 'This email is a test.'
* } ) ;
* ` ` `
*
* @ method sendEmail
* @ name Parse . Cloud . sendEmail
* @ param { Object } data The object of the mail data to send .
* /
ParseCloud . sendEmail = function ( data ) {
const config = Config . get ( Parse . applicationId ) ;
const emailAdapter = config . userController . adapter ;
if ( ! emailAdapter ) {
config . loggerController . error (
'Failed to send email because no mail adapter is configured for Parse Server.'
) ;
return ;
}
return emailAdapter . sendMail ( data ) ;
} ;
2020-07-17 11:36:38 +10:00
/ * *
* Registers a before live query subscription function .
*
* * * Available in Cloud Code only . * *
*
2022-05-30 04:48:55 +10:00
* If you want to use beforeSubscribe for a predefined class in the Parse JavaScript SDK ( e . g . { @ link Parse . User } or { @ link Parse . File } ) , you should pass the class itself and not the String for arg1 .
2020-07-17 11:36:38 +10:00
* ` ` `
* Parse . Cloud . beforeSubscribe ( 'MyCustomClass' , ( request ) => {
* // code here
2020-10-26 04:36:54 +11:00
* } , ( request ) => {
* // validation code here
* } ) ;
2020-07-17 11:36:38 +10:00
*
* Parse . Cloud . beforeSubscribe ( Parse . User , ( request ) => {
* // code here
2020-10-26 04:36:54 +11:00
* } , { ... validationObject } ) ;
2020-07-17 11:36:38 +10:00
* ` ` `
*
* @ method beforeSubscribe
* @ name Parse . Cloud . beforeSubscribe
* @ param { ( String | Parse . Object ) } arg1 The Parse . Object subclass to register the before subscription function for . This can instead be a String that is the className of the subclass .
* @ param { Function } func The function to run before a subscription . This function can be async and should take one parameter , a { @ link Parse . Cloud . TriggerRequest } .
2020-10-26 04:36:54 +11:00
* @ param { ( Object | Function ) } validator An optional function to help validating cloud code . This function can be an async function and should take one parameter a { @ link Parse . Cloud . TriggerRequest } , or a { @ link Parse . Cloud . ValidatorObject } .
2020-07-17 11:36:38 +10:00
* /
2020-10-26 04:36:54 +11:00
ParseCloud . beforeSubscribe = function ( parseClass , handler , validationHandler ) {
2021-03-02 10:52:21 +11:00
validateValidator ( validationHandler ) ;
2021-10-09 02:24:33 +11:00
const className = triggers . getClassName ( parseClass ) ;
2020-07-17 11:36:38 +10:00
triggers . addTrigger (
triggers . Types . beforeSubscribe ,
className ,
handler ,
2020-10-26 04:36:54 +11:00
Parse . applicationId ,
validationHandler
2020-07-17 11:36:38 +10:00
) ;
} ;
2020-07-13 13:06:52 -05:00
ParseCloud . onLiveQueryEvent = function ( handler ) {
2017-09-15 17:20:51 -04:00
triggers . addLiveQueryEventHandler ( handler , Parse . applicationId ) ;
} ;
2020-10-20 02:38:55 +11:00
/ * *
* Registers an after live query server event function .
*
* * * Available in Cloud Code only . * *
*
* ` ` `
* Parse . Cloud . afterLiveQueryEvent ( 'MyCustomClass' , ( request ) => {
* // code here
2020-10-26 04:36:54 +11:00
* } , ( request ) => {
* // validation code here
* } ) ;
*
* Parse . Cloud . afterLiveQueryEvent ( 'MyCustomClass' , ( request ) => {
* // code here
* } , { ... validationObject } ) ;
2020-10-20 02:38:55 +11:00
* ` ` `
*
* @ method afterLiveQueryEvent
* @ name Parse . Cloud . afterLiveQueryEvent
* @ param { ( String | Parse . Object ) } arg1 The Parse . Object subclass to register the after live query event function for . This can instead be a String that is the className of the subclass .
* @ param { Function } func The function to run after a live query event . This function can be async and should take one parameter , a { @ link Parse . Cloud . LiveQueryEventTrigger } .
2020-10-26 04:36:54 +11:00
* @ param { ( Object | Function ) } validator An optional function to help validating cloud code . This function can be an async function and should take one parameter a { @ link Parse . Cloud . LiveQueryEventTrigger } , or a { @ link Parse . Cloud . ValidatorObject } .
2020-10-20 02:38:55 +11:00
* /
2020-10-25 15:06:58 -05:00
ParseCloud . afterLiveQueryEvent = function ( parseClass , handler , validationHandler ) {
2021-10-09 02:24:33 +11:00
const className = triggers . getClassName ( parseClass ) ;
2021-03-02 10:52:21 +11:00
validateValidator ( validationHandler ) ;
2020-10-20 02:38:55 +11:00
triggers . addTrigger (
triggers . Types . afterEvent ,
className ,
handler ,
2020-10-26 04:36:54 +11:00
Parse . applicationId ,
validationHandler
2020-10-20 02:38:55 +11:00
) ;
} ;
2016-05-19 13:38:16 -07:00
ParseCloud . _removeAllHooks = ( ) => {
triggers . _unregisterAll ( ) ;
2023-03-11 09:54:05 +11:00
const config = Config . get ( Parse . applicationId ) ;
config ? . unregisterRateLimiters ( ) ;
2018-09-01 13:58:06 -04:00
} ;
2016-05-19 13:38:16 -07:00
2016-12-07 18:35:22 -05:00
ParseCloud . useMasterKey = ( ) => {
// eslint-disable-next-line
2018-09-01 13:58:06 -04:00
console . warn (
'Parse.Cloud.useMasterKey is deprecated (and has no effect anymore) on parse-server, please refer to the cloud code migration notes: http://docs.parseplatform.org/parse-server/guide/#master-key-must-be-passed-explicitly'
) ;
} ;
2016-12-07 18:35:22 -05:00
2016-02-05 14:38:09 -05:00
module . exports = ParseCloud ;
2018-08-09 16:20:13 -04:00
/ * *
2018-08-10 15:51:31 -04:00
* @ interface Parse . Cloud . TriggerRequest
2018-08-09 16:20:13 -04:00
* @ property { String } installationId If set , the installationId triggering the request .
* @ property { Boolean } master If true , means the master key was used .
2022-11-11 03:35:39 +11:00
* @ property { Boolean } isChallenge If true , means the current request is originally triggered by an auth challenge .
2018-08-09 16:20:13 -04:00
* @ property { Parse . User } user If set , the user that made the request .
* @ property { Parse . Object } object The object triggering the hook .
2023-01-05 14:26:54 +01:00
* @ property { String } ip The IP address of the client making the request . To ensure retrieving the correct IP address , set the Parse Server option ` trustProxy: true ` if Parse Server runs behind a proxy server , for example behind a load balancer .
2018-08-09 16:20:13 -04:00
* @ property { Object } headers The original HTTP headers for the request .
* @ property { String } triggerName The name of the trigger ( ` beforeSave ` , ` afterSave ` , ... )
* @ property { Object } log The current logger inside Parse Server .
* @ property { Parse . Object } original If set , the object , as currently stored .
* /
2020-04-02 17:00:15 -04:00
/ * *
* @ interface Parse . Cloud . FileTriggerRequest
* @ property { String } installationId If set , the installationId triggering the request .
* @ property { Boolean } master If true , means the master key was used .
* @ property { Parse . User } user If set , the user that made the request .
* @ property { Parse . File } file The file that triggered the hook .
* @ property { Integer } fileSize The size of the file in bytes .
* @ property { Integer } contentLength The value from Content - Length header
* @ property { String } ip The IP address of the client making the request .
* @ property { Object } headers The original HTTP headers for the request .
* @ property { String } triggerName The name of the trigger ( ` beforeSaveFile ` , ` afterSaveFile ` )
* @ property { Object } log The current logger inside Parse Server .
* /
2020-07-17 11:36:38 +10:00
/ * *
* @ interface Parse . Cloud . ConnectTriggerRequest
* @ property { String } installationId If set , the installationId triggering the request .
* @ property { Boolean } useMasterKey If true , means the master key was used .
* @ property { Parse . User } user If set , the user that made the request .
* @ property { Integer } clients The number of clients connected .
* @ property { Integer } subscriptions The number of subscriptions connected .
* @ property { String } sessionToken If set , the session of the user that made the request .
* /
2020-10-20 02:38:55 +11:00
/ * *
* @ interface Parse . Cloud . LiveQueryEventTrigger
* @ property { String } installationId If set , the installationId triggering the request .
* @ property { Boolean } useMasterKey If true , means the master key was used .
* @ property { Parse . User } user If set , the user that made the request .
* @ property { String } sessionToken If set , the session of the user that made the request .
* @ property { String } event The live query event that triggered the request .
* @ property { Parse . Object } object The object triggering the hook .
* @ property { Parse . Object } original If set , the object , as currently stored .
* @ property { Integer } clients The number of clients connected .
* @ property { Integer } subscriptions The number of subscriptions connected .
2020-10-22 08:50:21 +11:00
* @ property { Boolean } sendEvent If the LiveQuery event should be sent to the client . Set to false to prevent LiveQuery from pushing to the client .
2020-10-20 02:38:55 +11:00
* /
2018-08-09 16:20:13 -04:00
/ * *
2018-08-10 15:51:31 -04:00
* @ interface Parse . Cloud . BeforeFindRequest
2018-08-09 16:20:13 -04:00
* @ property { String } installationId If set , the installationId triggering the request .
* @ property { Boolean } master If true , means the master key was used .
* @ property { Parse . User } user If set , the user that made the request .
* @ property { Parse . Query } query The query triggering the hook .
* @ property { String } ip The IP address of the client making the request .
* @ property { Object } headers The original HTTP headers for the request .
* @ property { String } triggerName The name of the trigger ( ` beforeSave ` , ` afterSave ` , ... )
* @ property { Object } log The current logger inside Parse Server .
* @ property { Boolean } isGet wether the query a ` get ` or a ` find `
* /
/ * *
2018-08-10 15:51:31 -04:00
* @ interface Parse . Cloud . AfterFindRequest
2018-08-09 16:20:13 -04:00
* @ property { String } installationId If set , the installationId triggering the request .
* @ property { Boolean } master If true , means the master key was used .
* @ property { Parse . User } user If set , the user that made the request .
* @ property { Parse . Query } query The query triggering the hook .
* @ property { Array < Parse . Object > } results The results the query yielded .
* @ property { String } ip The IP address of the client making the request .
* @ property { Object } headers The original HTTP headers for the request .
* @ property { String } triggerName The name of the trigger ( ` beforeSave ` , ` afterSave ` , ... )
* @ property { Object } log The current logger inside Parse Server .
* /
/ * *
2018-08-10 15:51:31 -04:00
* @ interface Parse . Cloud . FunctionRequest
2018-08-09 16:20:13 -04:00
* @ property { String } installationId If set , the installationId triggering the request .
* @ property { Boolean } master If true , means the master key was used .
* @ property { Parse . User } user If set , the user that made the request .
* @ property { Object } params The params passed to the cloud function .
* /
/ * *
2018-08-10 15:51:31 -04:00
* @ interface Parse . Cloud . JobRequest
2018-08-09 16:20:13 -04:00
* @ property { Object } params The params passed to the background job .
* @ property { function } message If message is called with a string argument , will update the current message to be stored in the job status .
* /
2020-10-26 04:36:54 +11:00
/ * *
* @ interface Parse . Cloud . ValidatorObject
* @ property { Boolean } requireUser whether the cloud trigger requires a user .
* @ property { Boolean } requireMaster whether the cloud trigger requires a master key .
* @ property { Boolean } validateMasterKey whether the validator should run if masterKey is provided . Defaults to false .
2020-10-27 06:49:30 +11:00
* @ property { Boolean } skipWithMasterKey whether the cloud code function should be ignored using a masterKey .
2020-10-26 04:36:54 +11:00
*
* @ property { Array < String > | Object } requireUserKeys If set , keys required on request . user to make the request .
* @ property { String } requireUserKeys . field If requireUserKeys is an object , name of field to validate on request user
* @ property { Array | function | Any } requireUserKeys . field . options array of options that the field can be , function to validate field , or single value . Throw an error if value is invalid .
* @ property { String } requireUserKeys . field . error custom error message if field is invalid .
*
2021-02-13 09:01:38 +11:00
* @ property { Array < String > | function } requireAnyUserRoles If set , request . user has to be part of at least one roles name to make the request . If set to a function , function must return role names .
* @ property { Array < String > | function } requireAllUserRoles If set , request . user has to be part all roles name to make the request . If set to a function , function must return role names .
*
2020-10-26 04:36:54 +11:00
* @ property { Object | Array < String > } fields if an array of strings , validator will look for keys in request . params , and throw if not provided . If Object , fields to validate . If the trigger is a cloud function , ` request.params ` will be validated , otherwise ` request.object ` .
* @ property { String } fields . field name of field to validate .
* @ property { String } fields . field . type expected type of data for field .
* @ property { Boolean } fields . field . constant whether the field can be modified on the object .
* @ property { Any } fields . field . default default value if field is ` null ` , or initial value ` constant ` is ` true ` .
* @ property { Array | function | Any } fields . field . options array of options that the field can be , function to validate field , or single value . Throw an error if value is invalid .
* @ property { String } fields . field . error custom error message if field is invalid .
* /