1+ const fs = require ( 'fs' ) . promises
2+ const path = require ( 'path' )
3+ const toml = require ( '@iarna/toml' )
4+
5+ /**
6+ @typedef {{
7+ from: string,
8+ to: string,
9+ conditions?: {
10+ Role?: string[],
11+ },
12+ status?: number,
13+ force?: boolean,
14+ }} NetlifyRedirect
15+ */
16+
17+ /**
18+ @typedef {{
19+ build: {
20+ publish: string,
21+ functions?: string,
22+ },
23+ redirects: NetlifyRedirect[],
24+ }} NetlifyConfig
25+ */
26+
27+ const loginPage = '/_netlify-sso'
28+ const authFunc = 'sso-auth'
29+
30+ /**
31+ * @param {{ config: NetlifyConfig, functionsDir?: string, publishDir?: string } } params
32+ */
33+ async function generateSSO ( {
34+ config /* &mut */ ,
35+ functionsDir = '_netlify_sso_functions' ,
36+ publishDir = '_netlify_sso_publish' ,
37+ } ) {
38+ config . build = {
39+ ...config . build ,
40+ functions : functionsDir ,
41+ publish : publishDir ,
42+ }
43+
44+ await fs . mkdir ( functionsDir , { recursive : true } )
45+ await fs . mkdir ( publishDir , { recursive : true } )
46+
47+ const staticFileDir = path . resolve ( __dirname , '../static' )
48+ await fs . copyFile (
49+ path . join ( staticFileDir , 'sso-login.html' ) ,
50+ path . join ( publishDir , `${ loginPage } .html` ) ,
51+ )
52+ await fs . copyFile (
53+ path . join ( staticFileDir , 'sso-auth-function.js' ) ,
54+ path . join ( functionsDir , `${ authFunc } .js` ) ,
55+ )
56+
57+ /** @type {NetlifyRedirect[] } */
58+ const gatedRedirects = config . redirects . map ( ( redirect ) => ( {
59+ ...redirect ,
60+ conditions : {
61+ Role : [ 'netlify' ] ,
62+ } ,
63+ } ) )
64+
65+ /** @type {NetlifyRedirect[] } */
66+ const additionalRedirects = [
67+ // Serve content when logged in
68+ {
69+ from : '/*' ,
70+ to : '/:splat' ,
71+ conditions : {
72+ Role : [ 'netlify' ] ,
73+ } ,
74+ // will be set to 200 when there is content
75+ // since we don't set `force`
76+ status : 404 ,
77+ } ,
78+ // Serve login page on root
79+ {
80+ from : '/' ,
81+ to : loginPage ,
82+ status : 401 ,
83+ force : true ,
84+ } ,
85+ // Redirect to login page otherwise
86+ {
87+ from : '/*' ,
88+ to : '/' ,
89+ status : 302 ,
90+ force : true ,
91+ } ,
92+ ]
93+
94+ config . redirects = [ ...gatedRedirects , ...additionalRedirects ]
95+ }
96+
197module . exports = {
298 // The plugin main logic uses `on...` event handlers that are triggered on
399 // each new Netlify Build.
@@ -8,35 +104,19 @@ module.exports = {
8104 // Whole configuration file. For example, content of `netlify.toml`
9105 netlifyConfig,
10106 // Build constants
11- constants : {
12- // Directory that contains the deploy-ready HTML files and assets
13- // generated by the build. Its value is always defined, but the target
14- // might not have been created yet.
15- PUBLISH_DIR ,
16- // The directory where function source code lives.
17- // `undefined` if not specified by the user.
18- FUNCTIONS_SRC ,
19- } ,
20-
21- // Core utilities
22- utils : {
23- // Utility to report errors.
24- // See https://github.com/netlify/build#error-reporting
25- build,
26- // Utility to display information in the deploy summary.
27- // See https://github.com/netlify/build#logging
28- status,
29- // Utility for caching files.
30- // See https://github.com/netlify/build/blob/master/packages/cache-utils/README.md
31- cache,
32- // Utility for running commands.
33- // See https://github.com/netlify/build/blob/master/packages/run-utils/README.md
34- run,
35- // Utility for dealing with modified, created, deleted files since a git commit.
36- // See https://github.com/netlify/build/blob/master/packages/git-utils/README.md
37- git,
38- } ,
107+ constants : { PUBLISH_DIR , FUNCTIONS_SRC } ,
39108 } ) {
40-
109+ console . log ( 'Copying static assets...' )
110+
111+ await generateSSO ( {
112+ config : netlifyConfig ,
113+ functionsDir : FUNCTIONS_SRC ,
114+ publishDir : PUBLISH_DIR ,
115+ } )
116+ const config_out = toml . stringify ( netlifyConfig )
117+ await fs . writeFile (
118+ path . join ( netlifyConfig . build . publish , 'netlify.toml' ) ,
119+ config_out ,
120+ )
41121 } ,
42122}
0 commit comments