PBKDF2 is not a method of encryption, it's a method of hashing - e.g., it's one-way.

Depending on what you're looking to accomplish (e.g., validating users against some external system), delegated authentication (https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls...) with a ZAUTHETNICATE routine (see https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls...) might help.

@Craig.Regester I'd be really interested to see what you're doing with the server hooks. (Maybe @Raj Singh would be interested too?) It sounds like you're rolling your own; what are you integrating with? Git, Perforce, SVN, etc.?

A few tidbits that may or may not be relevant for your use cases:

%Studio.Extension.Base:UserAction (see https://docs.intersystems.com/irislatest/csp/documatic/%25CSP.Documatic....) with Action=3 will also launch an external browser given a full URL provided in Target (not necessarily CSP, but could be). This isn't truly a "modal" window but would give you a little bit more control perhaps.

For the sake of VSCode specifically there's a different API (not really documented) for closing a page opened with Action = 2 - specifically, sending a message to the parent frame (a VSCode web view) with data {"result":"done"}. This looks something like (in %CSP.Page:OnPage):

    If (%request.Get("EndTemplate") = 1) {
        If (%request.UserAgent [ " Code/") {
            // For VSCode only:
            Set %response.ContentType="text/html",%response.CharSet="UTF-8"
            Write "<html>",!
            Write "<script type=""text/javascript"">",!
            &js<if (window.parent) {
                window.parent.postMessage({"result":"done"},'*')
            }>
            Write "</script>",!
            Write "</html>",!
        } Else {
            Set %response.ContentType="text/xml",%response.CharSet="UTF-8"
            Set delim = ##class(%CSP.StudioTemplateError).#DELIM
            Write "<?xml version=""1.0""?>",!
            Write "<template><![CDATA[BODY",delim
            Write delim,"]]]]><![CDATA[></template>",!
        }
        Quit $$$OK
    }

@Evgeny Shvarov, the power of generators and projections is more in the creation of frameworks/tools that speed up building solutions. This includes many parts of IRIS itself, but moves into the user space for larger/more complicated applications (e.g., what we've done with AppS.REST both for REST-enabling older ObjectScript-based applications and for quickly building out new applications using IRIS and modern web technologies).

@Evgeny Shvarov anything with CodeMode=objectgenerator, typical uses of projections, anything that works with %Dictionary.(.*Definition|Compiled.*), anything that works directly with %Library.Routine / %Library.RoutineMgr... there are examples all over the place, including throughout both of my Open Exchange projects.

https://openexchange.intersystems.com/package/Test-Coverage-Tool
https://openexchange.intersystems.com/package/apps-rest

These don't go to the level of dynamically modifying/instrumenting code, but another of my projects (a mock framework for ObjectScript, still internal to InterSystems) does.

The right way to describe a list of a particular type of object is:

ClassMethod myMethod() As %ListOfObjects(ELEMENTTYPE="MyPackage.MyClass")

This is most relevant from the perspective of XML projections - e.g., web services. You can also define a subclass of %ListOfObjects with the ELEMENTTYPE parameter overridden for reuse. See https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GX...

One note - many use cases that call for a composite primary key in a typical boring database would be good use cases for a parent-child relationship in IRIS. This provides nicer features from an object/SQL perspective (e.g., using arrow syntax / implicit joins instead of explicit joins on the composite key fields). See: https://docs.intersystems.com/irisforhealthlatest/csp/docbook/Doc.View.c...

@Yuri Marx there's actually a separate "API Security Top 10" which is particularly relevant for REST APIs and modern web applications: https://owasp.org/www-project-api-security/

API4, API9, and API10 are all good IAM use cases; for the others, I'd recommend looking at https://github.com/intersystems/apps-rest for a security-first generic REST API implementation.

I'd expect that to work provided the id (not name) of the combobox/dataCombo is 'MyCombo'. e.g., this works fine:

Class DC.Demo.FindElement Extends %ZEN.Component.page
{

XData Contents [ XMLNamespace = "http://www.intersystems.com/zen" ]
{
<page xmlns="http://www.intersystems.com/zen">
<form>
<tabGroup showTabBar="true">
<tab caption="Tab One">
<combobox id="MyCombo" editable="true" />
</tab>
<tab caption="Tab Two">
</tab>
</tabGroup>
</form>
<button onclick="zenPage.alertComboValue()" />
</page>
}

ClientMethod alertComboValue() [ Language = javascript ]
{
    alert(zen('MyCombo').findElement('input').value);
}

}

This is a little messy and I'm going to report part of the answer as a bug internally. But regardless, here's one way to make it work - in short, have all of the things that could be listed as a recipient extend a common parent class, and in that class override %JSONNew to detect which type it is.

Class DC.Demo.Container Extends (%RegisteredObject, %JSON.Adaptor)
{
Property recipient As DC.Demo.Recipient;
ClassMethod Demo()
{
    for json = {"recipient":{"dob":"2021-06-10"}}, {"recipient":{"reference":"foo"}} {
        set inst = ..%New()
        do inst.%JSONImport(json)
        write !,json.%ToJSON(),!,$classname(inst.recipient),!
    }
}
}

Class DC.Demo.Recipient Extends (%RegisteredObject, %JSON.Adaptor)
{
/// Get an instance of an JSON enabled class.<br><br>
/// 
/// You may override this method to do custom processing (such as initializing
/// the object instance) before returning an instance of this class.
/// However, this method should not be called directly from user code.<br>
/// Arguments:<br>
///     dynamicObject is the dynamic object with thee values to be assigned to the new object.<br>
///     containerOref is the containing object instance when called from JSONImport.
ClassMethod %JSONNew(dynamicObject As %DynamicObject, containerOref As %RegisteredObject = "") As %RegisteredObject
{
    // This is weird: shouldn't need to reference .recipient here
    if dynamicObject.recipient.%IsDefined("dob") {
        quit ##class(DC.Demo.Patient).%New()
    } elseif dynamicObject.recipient.%IsDefined("reference") {
        quit ##class(DC.Demo.Reference).%New()
    } else {
        quit ..%New()
    }
}
}

Class DC.Demo.Reference Extends DC.Demo.Recipient
{
Property reference As %String;
}

Class DC.Demo.Patient Extends DC.Demo.Recipient
{
Property dob As %Date;
}

Output is:

 d ##class(DC.Demo.Container).Demo()
{"recipient":{"dob":"2021-06-10"}}
DC.Demo.Patient
{"recipient":{"reference":"foo"}}
DC.Demo.Reference

Only problem is, %JSONNew (as advertised in class reference documentation) should get the %DynamicObject representing the object itself, not the parent %DynamicObject. This would only really work if each type is used in exactly one context like this, which seems unlikely.

First off, it's generally best to avoid xecute. ;)

In the first case, routine is private (it isn't visible in the xecute stack frame). In the second, it's public, so it is visible there.

You could get the best of both worlds with:

ClassMethod Run()
{
   set routine="variable"
   set call="(routine) write routine,!"
   xecute (call, routine)
   quit
}

For more info see https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY...