[{"data":1,"prerenderedAt":1609},["ShallowReactive",2],{"navigation":3,"\u002Fdocs\u002Fcore-concepts\u002Fguards":176,"\u002Fdocs\u002Fcore-concepts\u002Fguards-surround":1604},[4,21,86,158],{"title":5,"path":6,"stem":7,"children":8,"status":11,"icon":20},"Getting Started","\u002Fdocs\u002Fgetting-started","1.docs\u002F1.getting-started\u002F1.index",[9,12,16],{"title":10,"path":6,"stem":7,"status":11},"Introduction",null,{"title":13,"path":14,"stem":15,"status":11},"Installation","\u002Fdocs\u002Fgetting-started\u002Finstallation","1.docs\u002F1.getting-started\u002F2.installation",{"title":17,"path":18,"stem":19,"status":11},"Quick Start","\u002Fdocs\u002Fgetting-started\u002Fquick-start","1.docs\u002F1.getting-started\u002F3.quick-start",false,{"title":22,"path":23,"stem":24,"children":25,"status":11,"icon":20},"Core Concepts","\u002Fdocs\u002Fcore-concepts","1.docs\u002F2.core-concepts\u002F1.index",[26,28,32,36,46,50,54,58,62,66,70,74,78,82],{"title":27,"path":23,"stem":24,"status":11},"Overview",{"title":29,"path":30,"stem":31,"status":11},"Response","\u002Fdocs\u002Fcore-concepts\u002Fresponse","1.docs\u002F2.core-concepts\u002F10.response",{"title":33,"path":34,"stem":35,"status":11},"Testing","\u002Fdocs\u002Fcore-concepts\u002Ftesting","1.docs\u002F2.core-concepts\u002F12.testing",{"title":37,"path":38,"stem":39,"children":40,"status":11,"icon":20,"defaultOpen":20},"Decorators","\u002Fdocs\u002Fcore-concepts\u002Fdecorators","1.docs\u002F2.core-concepts\u002F13.decorators\u002F1.index",[41,42],{"title":27,"path":38,"stem":39,"status":11},{"title":43,"path":44,"stem":45,"status":11},"Custom","\u002Fdocs\u002Fcore-concepts\u002Fdecorators\u002Fcustom","1.docs\u002F2.core-concepts\u002F13.decorators\u002F2.custom",{"title":47,"path":48,"stem":49,"status":11},"Discovery Service","\u002Fdocs\u002Fcore-concepts\u002Fdiscovery","1.docs\u002F2.core-concepts\u002F14.discovery",{"title":51,"path":52,"stem":53,"status":11},"Application Lifecycle","\u002Fdocs\u002Fcore-concepts\u002Fapp-lifecycle","1.docs\u002F2.core-concepts\u002F15.app-lifecycle",{"title":55,"path":56,"stem":57,"status":11},"Controllers","\u002Fdocs\u002Fcore-concepts\u002Fcontrollers","1.docs\u002F2.core-concepts\u002F2.controllers",{"title":59,"path":60,"stem":61,"status":11},"Routing","\u002Fdocs\u002Fcore-concepts\u002Frouting","1.docs\u002F2.core-concepts\u002F3.routing",{"title":63,"path":64,"stem":65,"status":11},"Providers","\u002Fdocs\u002Fcore-concepts\u002Fproviders","1.docs\u002F2.core-concepts\u002F4.providers",{"title":67,"path":68,"stem":69,"status":11},"Modules","\u002Fdocs\u002Fcore-concepts\u002Fmodules","1.docs\u002F2.core-concepts\u002F5.modules",{"title":71,"path":72,"stem":73,"status":11},"Configuration","\u002Fdocs\u002Fcore-concepts\u002Fconfiguration","1.docs\u002F2.core-concepts\u002F6.configuration",{"title":75,"path":76,"stem":77,"status":11},"Middleware","\u002Fdocs\u002Fcore-concepts\u002Fmiddleware","1.docs\u002F2.core-concepts\u002F7.middleware",{"title":79,"path":80,"stem":81,"status":11},"Guards","\u002Fdocs\u002Fcore-concepts\u002Fguards","1.docs\u002F2.core-concepts\u002F8.guards",{"title":83,"path":84,"stem":85,"status":11},"Exceptions","\u002Fdocs\u002Fcore-concepts\u002Fexceptions","1.docs\u002F2.core-concepts\u002F9.exceptions",{"title":87,"path":88,"stem":89,"children":90,"status":11,"icon":20},"Packages","\u002Fdocs\u002Fpackages","1.docs\u002F3.packages\u002F1.index",[91,92,97,108,112,130,134,138,142,146,150,154],{"title":27,"path":88,"stem":89,"status":11},{"title":93,"path":94,"stem":95,"status":96},"CLI","\u002Fdocs\u002Fpackages\u002Fcli","1.docs\u002F3.packages\u002F10.cli","experimental",{"title":98,"path":99,"stem":100,"children":101,"status":11,"icon":20,"defaultOpen":20},"Events","\u002Fdocs\u002Fpackages\u002Fmessaging","1.docs\u002F3.packages\u002F11.messaging\u002F1.index",[102,104],{"title":27,"path":99,"stem":100,"status":103},"beta",{"title":105,"path":106,"stem":107,"status":96},"Redis","\u002Fdocs\u002Fpackages\u002Fmessaging\u002Fredis","1.docs\u002F3.packages\u002F11.messaging\u002F2.redis",{"title":109,"path":110,"stem":111,"status":103},"Serve Static","\u002Fdocs\u002Fpackages\u002Fserve-static","1.docs\u002F3.packages\u002F12.serve-static",{"title":113,"path":114,"stem":115,"children":116,"status":11,"icon":20,"defaultOpen":20},"Auth","\u002Fdocs\u002Fpackages\u002Fauth","1.docs\u002F3.packages\u002F2.auth\u002F1.index",[117,118,122,126],{"title":27,"path":114,"stem":115,"status":103},{"title":119,"path":120,"stem":121,"status":103},"JWT Provider","\u002Fdocs\u002Fpackages\u002Fauth\u002Fjwt","1.docs\u002F3.packages\u002F2.auth\u002F2.jwt",{"title":123,"path":124,"stem":125,"status":103},"Local Provider","\u002Fdocs\u002Fpackages\u002Fauth\u002Flocal","1.docs\u002F3.packages\u002F2.auth\u002F3.local",{"title":127,"path":128,"stem":129,"status":96},"OAuth2 Provider","\u002Fdocs\u002Fpackages\u002Fauth\u002Foauth2","1.docs\u002F3.packages\u002F2.auth\u002F4.oauth2",{"title":131,"path":132,"stem":133,"status":103},"JWT","\u002Fdocs\u002Fpackages\u002Fjwt","1.docs\u002F3.packages\u002F3.jwt",{"title":135,"path":136,"stem":137,"status":103},"Drizzle","\u002Fdocs\u002Fpackages\u002Fdrizzle","1.docs\u002F3.packages\u002F4.drizzle",{"title":139,"path":140,"stem":141,"status":103},"Papr","\u002Fdocs\u002Fpackages\u002Fpapr","1.docs\u002F3.packages\u002F5.papr",{"title":143,"path":144,"stem":145,"status":103},"Mongoose","\u002Fdocs\u002Fpackages\u002Fmongoose","1.docs\u002F3.packages\u002F6.mongoose",{"title":147,"path":148,"stem":149,"status":103},"Swagger","\u002Fdocs\u002Fpackages\u002Fswagger","1.docs\u002F3.packages\u002F7.swagger",{"title":151,"path":152,"stem":153,"status":103},"Node Server","\u002Fdocs\u002Fpackages\u002Fnode-server","1.docs\u002F3.packages\u002F8.node-server",{"title":155,"path":156,"stem":157,"status":103},"uWS Server","\u002Fdocs\u002Fpackages\u002Fuws-server","1.docs\u002F3.packages\u002F9.uws-server",{"title":159,"path":160,"stem":161,"children":162,"status":11,"icon":20},"Roadmap","\u002Fdocs\u002Froadmap","1.docs\u002F4.roadmap\u002F1.index",[163,164,168,172],{"title":27,"path":160,"stem":161,"status":11},{"title":165,"path":166,"stem":167,"status":11},"Short term (0-3 months)","\u002Fdocs\u002Froadmap\u002Fshort-term","1.docs\u002F4.roadmap\u002F2.short-term",{"title":169,"path":170,"stem":171,"status":11},"Mid term (3-9 months)","\u002Fdocs\u002Froadmap\u002Fmid-term","1.docs\u002F4.roadmap\u002F3.mid-term",{"title":173,"path":174,"stem":175,"status":11},"Long term (9-12+ months)","\u002Fdocs\u002Froadmap\u002Flong-term","1.docs\u002F4.roadmap\u002F4.long-term",{"id":177,"title":79,"body":178,"description":1599,"extension":1600,"meta":1601,"navigation":254,"path":80,"seo":1602,"status":11,"stem":81,"__hash__":1603},"docs\u002F1.docs\u002F2.core-concepts\u002F8.guards.md",{"type":179,"value":180,"toc":1587},"minimark",[181,185,190,198,386,413,417,422,553,557,648,652,697,701,704,971,975,978,1088,1091,1164,1175,1179,1186,1351,1372,1557,1571,1575,1583],[182,183,184],"p",{},"Guards determine whether a request should be handled by the route handler. They are the recommended way to implement authentication and authorization in MiiaJS.",[186,187,189],"h2",{"id":188},"canactivate-interface","CanActivate interface",[182,191,192,193,197],{},"A guard is a class that implements the ",[194,195,196],"code",{},"CanActivate"," interface:",[199,200,205],"pre",{"className":201,"code":202,"language":203,"meta":204,"style":204},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import type { CanActivate, RequestContext } from '@miiajs\u002Fcore'\n\nclass AuthGuard implements CanActivate {\n  canActivate(ctx: RequestContext): boolean | Promise\u003Cboolean> {\n    const token = ctx.req.headers.get('authorization')\n    return !!token\n  }\n}\n","typescript","",[194,206,207,249,256,275,317,362,374,380],{"__ignoreMap":204},[208,209,212,216,219,223,227,230,233,236,239,242,246],"span",{"class":210,"line":211},"line",1,[208,213,215],{"class":214},"s7zQu","import",[208,217,218],{"class":214}," type",[208,220,222],{"class":221},"sMK4o"," {",[208,224,226],{"class":225},"sTEyZ"," CanActivate",[208,228,229],{"class":221},",",[208,231,232],{"class":225}," RequestContext",[208,234,235],{"class":221}," }",[208,237,238],{"class":214}," from",[208,240,241],{"class":221}," '",[208,243,245],{"class":244},"sfazB","@miiajs\u002Fcore",[208,247,248],{"class":221},"'\n",[208,250,252],{"class":210,"line":251},2,[208,253,255],{"emptyLinePlaceholder":254},true,"\n",[208,257,259,263,267,270,272],{"class":210,"line":258},3,[208,260,262],{"class":261},"spNyl","class",[208,264,266],{"class":265},"sBMFI"," AuthGuard",[208,268,269],{"class":261}," implements",[208,271,226],{"class":265},[208,273,274],{"class":221}," {\n",[208,276,278,282,285,289,292,294,297,300,303,306,309,312,315],{"class":210,"line":277},4,[208,279,281],{"class":280},"swJcz","  canActivate",[208,283,284],{"class":221},"(",[208,286,288],{"class":287},"sHdIc","ctx",[208,290,291],{"class":221},":",[208,293,232],{"class":265},[208,295,296],{"class":221},"):",[208,298,299],{"class":265}," boolean",[208,301,302],{"class":221}," |",[208,304,305],{"class":265}," Promise",[208,307,308],{"class":221},"\u003C",[208,310,311],{"class":265},"boolean",[208,313,314],{"class":221},">",[208,316,274],{"class":221},[208,318,320,323,326,329,332,335,338,340,343,345,349,351,354,357,359],{"class":210,"line":319},5,[208,321,322],{"class":261},"    const",[208,324,325],{"class":225}," token",[208,327,328],{"class":221}," =",[208,330,331],{"class":225}," ctx",[208,333,334],{"class":221},".",[208,336,337],{"class":225},"req",[208,339,334],{"class":221},[208,341,342],{"class":225},"headers",[208,344,334],{"class":221},[208,346,348],{"class":347},"s2Zo4","get",[208,350,284],{"class":280},[208,352,353],{"class":221},"'",[208,355,356],{"class":244},"authorization",[208,358,353],{"class":221},[208,360,361],{"class":280},")\n",[208,363,365,368,371],{"class":210,"line":364},6,[208,366,367],{"class":214},"    return",[208,369,370],{"class":221}," !!",[208,372,373],{"class":225},"token\n",[208,375,377],{"class":210,"line":376},7,[208,378,379],{"class":221},"  }\n",[208,381,383],{"class":210,"line":382},8,[208,384,385],{"class":221},"}\n",[387,388,389,397,406],"ul",{},[390,391,392,393,396],"li",{},"Return ",[194,394,395],{},"true"," to allow the request",[390,398,392,399,402,403],{},[194,400,401],{},"false"," to reject with ",[194,404,405],{},"403 Forbidden",[390,407,408,409,412],{},"Throw an ",[194,410,411],{},"HttpException"," for a custom error response",[186,414,416],{"id":415},"applying-guards","Applying guards",[418,419,421],"h3",{"id":420},"per-route","Per route",[199,423,425],{"className":201,"code":424,"language":203,"meta":204,"style":204},"import { UseGuard } from '@miiajs\u002Fcore'\n\n@Controller('\u002Fitems')\nclass ItemController {\n  @Delete('\u002F:id')\n  @UseGuard(AuthGuard)\n  remove(ctx: RequestContext) {\n    return { deleted: true }\n  }\n}\n",[194,426,427,446,450,469,478,497,507,525,543,548],{"__ignoreMap":204},[208,428,429,431,433,436,438,440,442,444],{"class":210,"line":211},[208,430,215],{"class":214},[208,432,222],{"class":221},[208,434,435],{"class":225}," UseGuard",[208,437,235],{"class":221},[208,439,238],{"class":214},[208,441,241],{"class":221},[208,443,245],{"class":244},[208,445,248],{"class":221},[208,447,448],{"class":210,"line":251},[208,449,255],{"emptyLinePlaceholder":254},[208,451,452,455,458,460,462,465,467],{"class":210,"line":258},[208,453,454],{"class":221},"@",[208,456,457],{"class":347},"Controller",[208,459,284],{"class":225},[208,461,353],{"class":221},[208,463,464],{"class":244},"\u002Fitems",[208,466,353],{"class":221},[208,468,361],{"class":225},[208,470,471,473,476],{"class":210,"line":277},[208,472,262],{"class":261},[208,474,475],{"class":265}," ItemController",[208,477,274],{"class":221},[208,479,480,483,486,488,490,493,495],{"class":210,"line":319},[208,481,482],{"class":221},"  @",[208,484,485],{"class":347},"Delete",[208,487,284],{"class":225},[208,489,353],{"class":221},[208,491,492],{"class":244},"\u002F:id",[208,494,353],{"class":221},[208,496,361],{"class":225},[208,498,499,501,504],{"class":210,"line":364},[208,500,482],{"class":221},[208,502,503],{"class":347},"UseGuard",[208,505,506],{"class":225},"(AuthGuard)\n",[208,508,509,512,514,516,518,520,523],{"class":210,"line":376},[208,510,511],{"class":280},"  remove",[208,513,284],{"class":221},[208,515,288],{"class":287},[208,517,291],{"class":221},[208,519,232],{"class":265},[208,521,522],{"class":221},")",[208,524,274],{"class":221},[208,526,527,529,531,534,536,540],{"class":210,"line":382},[208,528,367],{"class":214},[208,530,222],{"class":221},[208,532,533],{"class":280}," deleted",[208,535,291],{"class":221},[208,537,539],{"class":538},"sfNiH"," true",[208,541,542],{"class":221}," }\n",[208,544,546],{"class":210,"line":545},9,[208,547,379],{"class":221},[208,549,551],{"class":210,"line":550},10,[208,552,385],{"class":221},[418,554,556],{"id":555},"per-controller","Per controller",[199,558,560],{"className":201,"code":559,"language":203,"meta":204,"style":204},"@Controller('\u002Fadmin')\n@UseGuard(AuthGuard)\nclass AdminController {\n  @Get('\u002Fdashboard')\n  dashboard() {\n    return { stats: {} }\n  }\n}\n",[194,561,562,579,587,596,614,624,640,644],{"__ignoreMap":204},[208,563,564,566,568,570,572,575,577],{"class":210,"line":211},[208,565,454],{"class":221},[208,567,457],{"class":347},[208,569,284],{"class":225},[208,571,353],{"class":221},[208,573,574],{"class":244},"\u002Fadmin",[208,576,353],{"class":221},[208,578,361],{"class":225},[208,580,581,583,585],{"class":210,"line":251},[208,582,454],{"class":221},[208,584,503],{"class":347},[208,586,506],{"class":225},[208,588,589,591,594],{"class":210,"line":258},[208,590,262],{"class":261},[208,592,593],{"class":265}," AdminController",[208,595,274],{"class":221},[208,597,598,600,603,605,607,610,612],{"class":210,"line":277},[208,599,482],{"class":221},[208,601,602],{"class":347},"Get",[208,604,284],{"class":225},[208,606,353],{"class":221},[208,608,609],{"class":244},"\u002Fdashboard",[208,611,353],{"class":221},[208,613,361],{"class":225},[208,615,616,619,622],{"class":210,"line":319},[208,617,618],{"class":280},"  dashboard",[208,620,621],{"class":221},"()",[208,623,274],{"class":221},[208,625,626,628,630,633,635,638],{"class":210,"line":364},[208,627,367],{"class":214},[208,629,222],{"class":221},[208,631,632],{"class":280}," stats",[208,634,291],{"class":221},[208,636,637],{"class":221}," {}",[208,639,542],{"class":221},[208,641,642],{"class":210,"line":376},[208,643,379],{"class":221},[208,645,646],{"class":210,"line":382},[208,647,385],{"class":221},[418,649,651],{"id":650},"global","Global",[199,653,655],{"className":201,"code":654,"language":203,"meta":204,"style":204},"const app = new Miia()\n  .useGuard(AuthGuard)\n  .register(AppModule)\n",[194,656,657,677,687],{"__ignoreMap":204},[208,658,659,662,665,668,671,674],{"class":210,"line":211},[208,660,661],{"class":261},"const",[208,663,664],{"class":225}," app ",[208,666,667],{"class":221},"=",[208,669,670],{"class":221}," new",[208,672,673],{"class":347}," Miia",[208,675,676],{"class":225},"()\n",[208,678,679,682,685],{"class":210,"line":251},[208,680,681],{"class":221},"  .",[208,683,684],{"class":347},"useGuard",[208,686,506],{"class":225},[208,688,689,691,694],{"class":210,"line":258},[208,690,681],{"class":221},[208,692,693],{"class":347},"register",[208,695,696],{"class":225},"(AppModule)\n",[186,698,700],{"id":699},"guards-with-di","Guards with DI",[182,702,703],{},"Guards can use dependency injection:",[199,705,707],{"className":201,"code":706,"language":203,"meta":204,"style":204},"@Injectable()\nclass AuthGuard implements CanActivate {\n  private tokenService = inject(TokenService)\n\n  async canActivate(ctx: RequestContext): Promise\u003Cboolean> {\n    const header = ctx.req.headers.get('authorization')\n    if (!header?.startsWith('Bearer ')) {\n      throw new UnauthorizedException()\n    }\n\n    const user = await this.tokenService.verify(header.slice(7))\n    if (!user) throw new UnauthorizedException()\n\n    ctx.user = user\n    return true\n  }\n}\n",[194,708,709,718,730,746,750,778,811,846,858,863,867,909,933,938,953,961,966],{"__ignoreMap":204},[208,710,711,713,716],{"class":210,"line":211},[208,712,454],{"class":221},[208,714,715],{"class":347},"Injectable",[208,717,676],{"class":225},[208,719,720,722,724,726,728],{"class":210,"line":251},[208,721,262],{"class":261},[208,723,266],{"class":265},[208,725,269],{"class":261},[208,727,226],{"class":265},[208,729,274],{"class":221},[208,731,732,735,738,740,743],{"class":210,"line":258},[208,733,734],{"class":261},"  private",[208,736,737],{"class":280}," tokenService",[208,739,328],{"class":221},[208,741,742],{"class":280}," inject",[208,744,745],{"class":225},"(TokenService)\n",[208,747,748],{"class":210,"line":277},[208,749,255],{"emptyLinePlaceholder":254},[208,751,752,755,758,760,762,764,766,768,770,772,774,776],{"class":210,"line":319},[208,753,754],{"class":261},"  async",[208,756,757],{"class":280}," canActivate",[208,759,284],{"class":221},[208,761,288],{"class":287},[208,763,291],{"class":221},[208,765,232],{"class":265},[208,767,296],{"class":221},[208,769,305],{"class":265},[208,771,308],{"class":221},[208,773,311],{"class":265},[208,775,314],{"class":221},[208,777,274],{"class":221},[208,779,780,782,785,787,789,791,793,795,797,799,801,803,805,807,809],{"class":210,"line":364},[208,781,322],{"class":261},[208,783,784],{"class":225}," header",[208,786,328],{"class":221},[208,788,331],{"class":225},[208,790,334],{"class":221},[208,792,337],{"class":225},[208,794,334],{"class":221},[208,796,342],{"class":225},[208,798,334],{"class":221},[208,800,348],{"class":347},[208,802,284],{"class":280},[208,804,353],{"class":221},[208,806,356],{"class":244},[208,808,353],{"class":221},[208,810,361],{"class":280},[208,812,813,816,819,822,825,828,831,833,835,838,840,843],{"class":210,"line":376},[208,814,815],{"class":214},"    if",[208,817,818],{"class":280}," (",[208,820,821],{"class":221},"!",[208,823,824],{"class":225},"header",[208,826,827],{"class":221},"?.",[208,829,830],{"class":347},"startsWith",[208,832,284],{"class":280},[208,834,353],{"class":221},[208,836,837],{"class":244},"Bearer ",[208,839,353],{"class":221},[208,841,842],{"class":280},")) ",[208,844,845],{"class":221},"{\n",[208,847,848,851,853,856],{"class":210,"line":382},[208,849,850],{"class":214},"      throw",[208,852,670],{"class":221},[208,854,855],{"class":347}," UnauthorizedException",[208,857,676],{"class":280},[208,859,860],{"class":210,"line":545},[208,861,862],{"class":221},"    }\n",[208,864,865],{"class":210,"line":550},[208,866,255],{"emptyLinePlaceholder":254},[208,868,870,872,875,877,880,883,886,888,891,893,895,897,900,902,906],{"class":210,"line":869},11,[208,871,322],{"class":261},[208,873,874],{"class":225}," user",[208,876,328],{"class":221},[208,878,879],{"class":214}," await",[208,881,882],{"class":221}," this.",[208,884,885],{"class":225},"tokenService",[208,887,334],{"class":221},[208,889,890],{"class":347},"verify",[208,892,284],{"class":280},[208,894,824],{"class":225},[208,896,334],{"class":221},[208,898,899],{"class":347},"slice",[208,901,284],{"class":280},[208,903,905],{"class":904},"sbssI","7",[208,907,908],{"class":280},"))\n",[208,910,912,914,916,918,921,924,927,929,931],{"class":210,"line":911},12,[208,913,815],{"class":214},[208,915,818],{"class":280},[208,917,821],{"class":221},[208,919,920],{"class":225},"user",[208,922,923],{"class":280},") ",[208,925,926],{"class":214},"throw",[208,928,670],{"class":221},[208,930,855],{"class":347},[208,932,676],{"class":280},[208,934,936],{"class":210,"line":935},13,[208,937,255],{"emptyLinePlaceholder":254},[208,939,941,944,946,948,950],{"class":210,"line":940},14,[208,942,943],{"class":225},"    ctx",[208,945,334],{"class":221},[208,947,920],{"class":225},[208,949,328],{"class":221},[208,951,952],{"class":225}," user\n",[208,954,956,958],{"class":210,"line":955},15,[208,957,367],{"class":214},[208,959,960],{"class":538}," true\n",[208,962,964],{"class":210,"line":963},16,[208,965,379],{"class":221},[208,967,969],{"class":210,"line":968},17,[208,970,385],{"class":221},[186,972,974],{"id":973},"parameterized-guards","Parameterized guards",[182,976,977],{},"Create guard factories for reusable logic:",[199,979,981],{"className":201,"code":980,"language":203,"meta":204,"style":204},"function Roles(...roles: string[]) {\n  class RolesGuard implements CanActivate {\n    canActivate(ctx: RequestContext) {\n      return roles.includes(ctx.user?.role)\n    }\n  }\n  return RolesGuard\n}\n",[194,982,983,1009,1023,1040,1068,1072,1076,1084],{"__ignoreMap":204},[208,984,985,988,991,994,997,999,1002,1005,1007],{"class":210,"line":211},[208,986,987],{"class":261},"function",[208,989,990],{"class":347}," Roles",[208,992,993],{"class":221},"(...",[208,995,996],{"class":287},"roles",[208,998,291],{"class":221},[208,1000,1001],{"class":265}," string",[208,1003,1004],{"class":225},"[]",[208,1006,522],{"class":221},[208,1008,274],{"class":221},[208,1010,1011,1014,1017,1019,1021],{"class":210,"line":251},[208,1012,1013],{"class":261},"  class",[208,1015,1016],{"class":265}," RolesGuard",[208,1018,269],{"class":261},[208,1020,226],{"class":265},[208,1022,274],{"class":221},[208,1024,1025,1028,1030,1032,1034,1036,1038],{"class":210,"line":258},[208,1026,1027],{"class":280},"    canActivate",[208,1029,284],{"class":221},[208,1031,288],{"class":287},[208,1033,291],{"class":221},[208,1035,232],{"class":265},[208,1037,522],{"class":221},[208,1039,274],{"class":221},[208,1041,1042,1045,1048,1050,1053,1055,1057,1059,1061,1063,1066],{"class":210,"line":277},[208,1043,1044],{"class":214},"      return",[208,1046,1047],{"class":225}," roles",[208,1049,334],{"class":221},[208,1051,1052],{"class":347},"includes",[208,1054,284],{"class":280},[208,1056,288],{"class":225},[208,1058,334],{"class":221},[208,1060,920],{"class":225},[208,1062,827],{"class":221},[208,1064,1065],{"class":225},"role",[208,1067,361],{"class":280},[208,1069,1070],{"class":210,"line":319},[208,1071,862],{"class":221},[208,1073,1074],{"class":210,"line":364},[208,1075,379],{"class":221},[208,1077,1078,1081],{"class":210,"line":376},[208,1079,1080],{"class":214},"  return",[208,1082,1083],{"class":225}," RolesGuard\n",[208,1085,1086],{"class":210,"line":382},[208,1087,385],{"class":221},[182,1089,1090],{},"Combine multiple guards:",[199,1092,1094],{"className":201,"code":1093,"language":203,"meta":204,"style":204},"@Delete('\u002F:id')\n@UseGuard(AuthGuard, Roles('admin'))\nremove(ctx: RequestContext) {\n  return { deleted: true }\n}\n",[194,1095,1096,1112,1136,1146,1160],{"__ignoreMap":204},[208,1097,1098,1100,1102,1104,1106,1108,1110],{"class":210,"line":211},[208,1099,454],{"class":221},[208,1101,485],{"class":347},[208,1103,284],{"class":225},[208,1105,353],{"class":221},[208,1107,492],{"class":244},[208,1109,353],{"class":221},[208,1111,361],{"class":225},[208,1113,1114,1116,1118,1121,1123,1125,1127,1129,1132,1134],{"class":210,"line":251},[208,1115,454],{"class":221},[208,1117,503],{"class":347},[208,1119,1120],{"class":225},"(AuthGuard",[208,1122,229],{"class":221},[208,1124,990],{"class":347},[208,1126,284],{"class":225},[208,1128,353],{"class":221},[208,1130,1131],{"class":244},"admin",[208,1133,353],{"class":221},[208,1135,908],{"class":225},[208,1137,1138,1141,1144],{"class":210,"line":258},[208,1139,1140],{"class":347},"remove",[208,1142,1143],{"class":225},"(ctx: RequestContext) ",[208,1145,845],{"class":221},[208,1147,1148,1150,1152,1154,1156,1158],{"class":210,"line":277},[208,1149,1080],{"class":214},[208,1151,222],{"class":221},[208,1153,533],{"class":280},[208,1155,291],{"class":221},[208,1157,539],{"class":538},[208,1159,542],{"class":221},[208,1161,1162],{"class":210,"line":319},[208,1163,385],{"class":221},[182,1165,1166,1167,1170,1171,1174],{},"Guards execute in order. If ",[194,1168,1169],{},"AuthGuard"," fails, ",[194,1172,1173],{},"Roles"," is never called.",[186,1176,1178],{"id":1177},"skipping-guards","Skipping guards",[182,1180,1181,1182,1185],{},"Use ",[194,1183,1184],{},"@SkipGuard()"," to exclude specific guards at compile time. The guard middleware is not added to the route pipeline at all - zero runtime overhead:",[199,1187,1189],{"className":201,"code":1188,"language":203,"meta":204,"style":204},"import { SkipGuard } from '@miiajs\u002Fcore'\n\n@Controller('\u002Fposts')\n@UseGuard(AuthGuard())\nclass PostController {\n  @Get('\u002F')\n  @SkipGuard(AuthGuard)  \u002F\u002F AuthGuard is not applied to this route\n  list() { return [] }\n\n  @Get('\u002F:id')            \u002F\u002F AuthGuard applies normally\n  findOne(ctx: RequestContext) { ... }\n}\n",[194,1190,1191,1210,1214,1231,1244,1253,1270,1284,1301,1305,1325,1347],{"__ignoreMap":204},[208,1192,1193,1195,1197,1200,1202,1204,1206,1208],{"class":210,"line":211},[208,1194,215],{"class":214},[208,1196,222],{"class":221},[208,1198,1199],{"class":225}," SkipGuard",[208,1201,235],{"class":221},[208,1203,238],{"class":214},[208,1205,241],{"class":221},[208,1207,245],{"class":244},[208,1209,248],{"class":221},[208,1211,1212],{"class":210,"line":251},[208,1213,255],{"emptyLinePlaceholder":254},[208,1215,1216,1218,1220,1222,1224,1227,1229],{"class":210,"line":258},[208,1217,454],{"class":221},[208,1219,457],{"class":347},[208,1221,284],{"class":225},[208,1223,353],{"class":221},[208,1225,1226],{"class":244},"\u002Fposts",[208,1228,353],{"class":221},[208,1230,361],{"class":225},[208,1232,1233,1235,1237,1239,1241],{"class":210,"line":277},[208,1234,454],{"class":221},[208,1236,503],{"class":347},[208,1238,284],{"class":225},[208,1240,1169],{"class":347},[208,1242,1243],{"class":225},"())\n",[208,1245,1246,1248,1251],{"class":210,"line":319},[208,1247,262],{"class":261},[208,1249,1250],{"class":265}," PostController",[208,1252,274],{"class":221},[208,1254,1255,1257,1259,1261,1263,1266,1268],{"class":210,"line":364},[208,1256,482],{"class":221},[208,1258,602],{"class":347},[208,1260,284],{"class":225},[208,1262,353],{"class":221},[208,1264,1265],{"class":244},"\u002F",[208,1267,353],{"class":221},[208,1269,361],{"class":225},[208,1271,1272,1274,1277,1280],{"class":210,"line":376},[208,1273,482],{"class":221},[208,1275,1276],{"class":347},"SkipGuard",[208,1278,1279],{"class":225},"(AuthGuard)  ",[208,1281,1283],{"class":1282},"sHwdD","\u002F\u002F AuthGuard is not applied to this route\n",[208,1285,1286,1289,1291,1293,1296,1299],{"class":210,"line":382},[208,1287,1288],{"class":280},"  list",[208,1290,621],{"class":221},[208,1292,222],{"class":221},[208,1294,1295],{"class":214}," return",[208,1297,1298],{"class":280}," [] ",[208,1300,385],{"class":221},[208,1302,1303],{"class":210,"line":545},[208,1304,255],{"emptyLinePlaceholder":254},[208,1306,1307,1309,1311,1313,1315,1317,1319,1322],{"class":210,"line":550},[208,1308,482],{"class":221},[208,1310,602],{"class":347},[208,1312,284],{"class":225},[208,1314,353],{"class":221},[208,1316,492],{"class":244},[208,1318,353],{"class":221},[208,1320,1321],{"class":225},")            ",[208,1323,1324],{"class":1282},"\u002F\u002F AuthGuard applies normally\n",[208,1326,1327,1330,1332,1334,1336,1338,1340,1342,1345],{"class":210,"line":869},[208,1328,1329],{"class":280},"  findOne",[208,1331,284],{"class":221},[208,1333,288],{"class":287},[208,1335,291],{"class":221},[208,1337,232],{"class":265},[208,1339,522],{"class":221},[208,1341,222],{"class":221},[208,1343,1344],{"class":221}," ...",[208,1346,542],{"class":221},[208,1348,1349],{"class":210,"line":911},[208,1350,385],{"class":221},[182,1352,1353,1356,1357,1360,1361,1368,1369,334],{},[194,1354,1355],{},"@SkipGuard"," works with direct guard classes, factory guards (like ",[194,1358,1359],{},"AuthGuard()","), ",[1362,1363,1364,1365],"strong",{},"and global guards registered via ",[194,1366,1367],{},"app.useGuard()",". Multiple guards can be skipped: ",[194,1370,1371],{},"@SkipGuard(GuardA, GuardB)",[199,1373,1375],{"className":201,"code":1374,"language":203,"meta":204,"style":204},"@Injectable()\nclass GlobalAuth implements CanActivate {\n  canActivate(_ctx: RequestContext) { return false }\n}\n\nconst app = new Miia().useGuard(GlobalAuth).register(AppModule)\n\n@Controller('\u002Fwebhooks')\nclass WebhookController {\n  @Post('\u002Fstripe')\n  @SkipGuard(GlobalAuth) \u002F\u002F bypass the app-level guard for this endpoint\n  stripe(ctx: RequestContext) {\n    return { received: true }\n  }\n}\n",[194,1376,1377,1385,1398,1422,1426,1430,1457,1461,1478,1487,1505,1517,1534,1549,1553],{"__ignoreMap":204},[208,1378,1379,1381,1383],{"class":210,"line":211},[208,1380,454],{"class":221},[208,1382,715],{"class":347},[208,1384,676],{"class":225},[208,1386,1387,1389,1392,1394,1396],{"class":210,"line":251},[208,1388,262],{"class":261},[208,1390,1391],{"class":265}," GlobalAuth",[208,1393,269],{"class":261},[208,1395,226],{"class":265},[208,1397,274],{"class":221},[208,1399,1400,1402,1404,1407,1409,1411,1413,1415,1417,1420],{"class":210,"line":258},[208,1401,281],{"class":280},[208,1403,284],{"class":221},[208,1405,1406],{"class":287},"_ctx",[208,1408,291],{"class":221},[208,1410,232],{"class":265},[208,1412,522],{"class":221},[208,1414,222],{"class":221},[208,1416,1295],{"class":214},[208,1418,1419],{"class":538}," false",[208,1421,542],{"class":221},[208,1423,1424],{"class":210,"line":277},[208,1425,385],{"class":221},[208,1427,1428],{"class":210,"line":319},[208,1429,255],{"emptyLinePlaceholder":254},[208,1431,1432,1434,1436,1438,1440,1442,1444,1446,1448,1451,1453,1455],{"class":210,"line":364},[208,1433,661],{"class":261},[208,1435,664],{"class":225},[208,1437,667],{"class":221},[208,1439,670],{"class":221},[208,1441,673],{"class":347},[208,1443,621],{"class":225},[208,1445,334],{"class":221},[208,1447,684],{"class":347},[208,1449,1450],{"class":225},"(GlobalAuth)",[208,1452,334],{"class":221},[208,1454,693],{"class":347},[208,1456,696],{"class":225},[208,1458,1459],{"class":210,"line":376},[208,1460,255],{"emptyLinePlaceholder":254},[208,1462,1463,1465,1467,1469,1471,1474,1476],{"class":210,"line":382},[208,1464,454],{"class":221},[208,1466,457],{"class":347},[208,1468,284],{"class":225},[208,1470,353],{"class":221},[208,1472,1473],{"class":244},"\u002Fwebhooks",[208,1475,353],{"class":221},[208,1477,361],{"class":225},[208,1479,1480,1482,1485],{"class":210,"line":545},[208,1481,262],{"class":261},[208,1483,1484],{"class":265}," WebhookController",[208,1486,274],{"class":221},[208,1488,1489,1491,1494,1496,1498,1501,1503],{"class":210,"line":550},[208,1490,482],{"class":221},[208,1492,1493],{"class":347},"Post",[208,1495,284],{"class":225},[208,1497,353],{"class":221},[208,1499,1500],{"class":244},"\u002Fstripe",[208,1502,353],{"class":221},[208,1504,361],{"class":225},[208,1506,1507,1509,1511,1514],{"class":210,"line":869},[208,1508,482],{"class":221},[208,1510,1276],{"class":347},[208,1512,1513],{"class":225},"(GlobalAuth) ",[208,1515,1516],{"class":1282},"\u002F\u002F bypass the app-level guard for this endpoint\n",[208,1518,1519,1522,1524,1526,1528,1530,1532],{"class":210,"line":911},[208,1520,1521],{"class":280},"  stripe",[208,1523,284],{"class":221},[208,1525,288],{"class":287},[208,1527,291],{"class":221},[208,1529,232],{"class":265},[208,1531,522],{"class":221},[208,1533,274],{"class":221},[208,1535,1536,1538,1540,1543,1545,1547],{"class":210,"line":935},[208,1537,367],{"class":214},[208,1539,222],{"class":221},[208,1541,1542],{"class":280}," received",[208,1544,291],{"class":221},[208,1546,539],{"class":538},[208,1548,542],{"class":221},[208,1550,1551],{"class":210,"line":940},[208,1552,379],{"class":221},[208,1554,1555],{"class":210,"line":955},[208,1556,385],{"class":221},[1558,1559,1560],"note",{},[182,1561,1562,1563,1566,1567,1570],{},"Global guards do ",[1362,1564,1565],{},"not"," run on unmatched (404) routes - there is no resource to authorize, and this avoids leaking information about which auth scheme protects a path that doesn't exist. Global middleware (",[194,1568,1569],{},"app.use()",") still runs on 404s.",[186,1572,1574],{"id":1573},"guard-execution-order","Guard execution order",[199,1576,1581],{"className":1577,"code":1579,"language":1580},[1578],"language-text","Global guards (app.useGuard(), filtered by @SkipGuard)\n  -> Controller guards (@UseGuard on class)\n  -> Route guards (@UseGuard on method)\n  -> Route handler\n","text",[194,1582,1579],{"__ignoreMap":204},[1584,1585,1586],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":204,"searchDepth":251,"depth":251,"links":1588},[1589,1590,1595,1596,1597,1598],{"id":188,"depth":251,"text":189},{"id":415,"depth":251,"text":416,"children":1591},[1592,1593,1594],{"id":420,"depth":258,"text":421},{"id":555,"depth":258,"text":556},{"id":650,"depth":258,"text":651},{"id":699,"depth":251,"text":700},{"id":973,"depth":251,"text":974},{"id":1177,"depth":251,"text":1178},{"id":1573,"depth":251,"text":1574},"Control access to routes based on conditions like authentication and roles.","md",{},{"title":79,"description":1599},"T6gqwNT3UjERtAQh91N0E3JOTuQOv9zlkhScFPrFzzI",[1605,1607],{"title":75,"path":76,"stem":77,"description":1606,"children":-1},"Transform requests and responses using the Koa-style onion model.",{"title":83,"path":84,"stem":85,"description":1608,"children":-1},"Handle errors with structured HTTP exception classes.",1778575271891]