namespace _zeitbild.api { /** * @todo zu plankton auslagern? */ type type_stuff = { version : (null | string); headers : Record; path_parameters : Record; query_parameters : Record; }; /** */ export async function session_from_stuff( stuff : {headers : Record;} ) : Promise<{key : string; value : lib_plankton.session.type_session}> { const key : string = (stuff.headers["X-Session-Key"] || stuff.headers["X-Session-Key".toLowerCase()]); const value : lib_plankton.session.type_session = await lib_plankton.session.get(key); return {"key": key, "value": value}; } /** */ export async function user_from_web_auth( stuff : {headers : Record;} ) : Promise< { id : _zeitbild.type_user_id; object : _zeitbild.type_user_object; } > { const authorization_string : string = ( stuff.headers["Authorization"] ?? stuff.headers["authorization"] ?? null ); if (authorization_string === null) { return Promise.reject(new Error("authorization header missing")); } else { const parts : Array = authorization_string.split(" "); const strategy : string = parts[0]; const data_raw : string = parts.slice(1).join(" "); switch (strategy) { default: { lib_plankton.log.notice( "zeitbild.user_from_web_auth.unhandled_strategy", { "strategy": strategy, } ); return Promise.reject(new Error("unhandled authorization strategy: " + strategy)); break; } case "Basic": { const data_raw_decoded : string = lib_plankton.base64.decode(data_raw); const parts_ : Array = data_raw_decoded.split(":"); const username : string = parts_[0]; const password_is : string = parts_.slice(1).join(":"); const {"value": user_id, "error": error} = await lib_plankton.call.try_catch_wrap_async<_zeitbild.type_user_id>( () => _zeitbild.service.user.identify(username) ); if ((error !== null) || (user_id === null)) { lib_plankton.log.notice( "zeitbild.user_from_web_auth.unknown_user", { "username": username, } ); return Promise.reject(); } else { const user_object : _zeitbild.type_user_object = await _zeitbild.service.user.get(user_id); if (user_object.dav_token !== null) { lib_plankton.log.notice( "zeitbild.user_from_web_auth.dav_token_unset", { "user_id": user_id, } ); return Promise.reject(new Error("DAV token unset")); } else { const password_shall : string = user_object.dav_token; if (! (password_is === password_shall)) { lib_plankton.log.notice( "zeitbild.user_from_web_auth.wrong_password", { "user_id": user_id, "password_is": password_is, } ); return Promise.reject(new Error("wrong password")); } else { return Promise.resolve({"id": user_id, "object": user_object}); } } } break; } } } } /** */ export const restriction_none : lib_plankton.rest_caldav.type_restriction = ( (stuff) => Promise.resolve(true) ); /** */ export const restriction_web_auth : lib_plankton.rest_caldav.type_restriction = ( stuff => ( user_from_web_auth(stuff) .then(() => Promise.resolve(true)) .catch(() => Promise.resolve(false)) ) ); /** */ export const restriction_logged_in : lib_plankton.rest_caldav.type_restriction = ( (stuff) => ( session_from_stuff(stuff) .then(() => Promise.resolve(true)) .catch(() => Promise.resolve(false)) ) ); /** */ export function register( rest_subject : lib_plankton.rest_caldav.type_rest, http_method : lib_plankton.caldav.enum_method, path : string, options : { active ?: ((version : (null | string)) => boolean); restriction ?: (null | lib_plankton.rest_caldav.type_restriction); execution ?: lib_plankton.rest_caldav.type_execution; title ?: (null | string); description ?: (null | string); query_parameters ?: ((version : (null | string)) => Array< { name : string; description : (null | string); required : boolean; } >); input_schema ?: ((version: (null | string)) => lib_plankton.rest_caldav.type_oas_schema); output_schema ?: ((version: (null | string)) => lib_plankton.rest_caldav.type_oas_schema); request_body_mimetype ?: ( (version : (null | string)) => string ); request_body_decode ?: ( (version : (null | string)) => (http_request_body : Buffer, http_request_header_content_type : (null | string)) => Promise ); response_body_mimetype ?: string; response_body_encode ?: ( (output : any) => Promise ); } = {} ) : void { options = Object.assign( { }, options ); lib_plankton.rest_caldav.register( rest_subject, http_method, (_zeitbild.conf.get().server.path_base + path), { "active": options.active, /** * @todo heed version */ "restriction": ( ((options.restriction === undefined) || (options.restriction === null)) ? undefined : (version) => (options.restriction as lib_plankton.rest_caldav.type_restriction) ), /** * @todo heed version */ "execution": ( ((options.execution === undefined) || (options.execution === null)) ? undefined : (version) => (options.execution as lib_plankton.rest_caldav.type_execution) ), /** * @todo heed version */ "title": ( ((options.title === undefined) || (options.title === null)) ? (version) => null : (version) => (options.title as string) ), /** * @todo heed version */ "description": ( ((options.description === undefined) || (options.description === null)) ? (version) => null : (version) => (options.description as string) ), "query_parameters": options.query_parameters, "input_schema": options.input_schema, "output_schema": options.output_schema, "request_body_mimetype": options.request_body_mimetype, "request_body_decode": options.request_body_decode, /** * @todo heed version */ "response_body_mimetype": ( ((options.response_body_mimetype === undefined) || (options.response_body_mimetype === null)) ? undefined : (version) => (options.response_body_mimetype as string) ), /** * @todo heed version */ "response_body_encode": ( ((options.response_body_encode === undefined) || (options.response_body_encode === null)) ? undefined : (version) => (options.response_body_encode as ((output : any) => Promise)) ), } ); } }